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 {
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 parseDirectiveCFINegateRAStateWithPC();
199 bool parseDirectiveCFIBKeyFrame();
200 bool parseDirectiveCFIMTETaggedFrame();
202 bool parseDirectiveVariantPCS(
SMLoc L);
204 bool parseDirectiveSEHAllocStack(
SMLoc L);
205 bool parseDirectiveSEHPrologEnd(
SMLoc L);
206 bool parseDirectiveSEHSaveR19R20X(
SMLoc L);
207 bool parseDirectiveSEHSaveFPLR(
SMLoc L);
208 bool parseDirectiveSEHSaveFPLRX(
SMLoc L);
209 bool parseDirectiveSEHSaveReg(
SMLoc L);
210 bool parseDirectiveSEHSaveRegX(
SMLoc L);
211 bool parseDirectiveSEHSaveRegP(
SMLoc L);
212 bool parseDirectiveSEHSaveRegPX(
SMLoc L);
213 bool parseDirectiveSEHSaveLRPair(
SMLoc L);
214 bool parseDirectiveSEHSaveFReg(
SMLoc L);
215 bool parseDirectiveSEHSaveFRegX(
SMLoc L);
216 bool parseDirectiveSEHSaveFRegP(
SMLoc L);
217 bool parseDirectiveSEHSaveFRegPX(
SMLoc L);
218 bool parseDirectiveSEHSetFP(
SMLoc L);
219 bool parseDirectiveSEHAddFP(
SMLoc L);
220 bool parseDirectiveSEHNop(
SMLoc L);
221 bool parseDirectiveSEHSaveNext(
SMLoc L);
222 bool parseDirectiveSEHEpilogStart(
SMLoc L);
223 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
224 bool parseDirectiveSEHTrapFrame(
SMLoc L);
225 bool parseDirectiveSEHMachineFrame(
SMLoc L);
226 bool parseDirectiveSEHContext(
SMLoc L);
227 bool parseDirectiveSEHECContext(
SMLoc L);
228 bool parseDirectiveSEHClearUnwoundToCall(
SMLoc L);
229 bool parseDirectiveSEHPACSignLR(
SMLoc L);
230 bool parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
bool Writeback);
231 bool parseDirectiveAeabiSubSectionHeader(
SMLoc L);
232 bool parseDirectiveAeabiAArch64Attr(
SMLoc L);
234 bool validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
236 unsigned getNumRegsForRegKind(RegKind K);
240 bool MatchingInlineAsm)
override;
244#define GET_ASSEMBLER_HEADER
245#include "AArch64GenAsmMatcher.inc"
259 template <
bool IsSVEPrefetch = false>
266 template <
bool AddFPZeroAsLiteral>
274 template <
bool ParseShiftExtend,
275 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
278 template <
bool ParseShiftExtend,
bool ParseSuffix>
280 template <RegKind RK>
284 template <RegKind VectorKind>
286 bool ExpectMatch =
false);
296 enum AArch64MatchResultTy {
298#define GET_OPERAND_DIAGNOSTIC_TYPES
299#include "AArch64GenAsmMatcher.inc"
302 bool IsWindowsArm64EC;
333 SMLoc &EndLoc)
override;
336 unsigned Kind)
override;
340 static bool classifySymbolRef(
const MCExpr *Expr,
373 SMLoc StartLoc, EndLoc;
382 struct ShiftExtendOp {
385 bool HasExplicitAmount;
395 RegConstraintEqualityTy EqualityTy;
411 ShiftExtendOp ShiftExtend;
416 unsigned ElementWidth;
420 struct MatrixTileListOp {
421 unsigned RegMask = 0;
424 struct VectorListOp {
428 unsigned NumElements;
429 unsigned ElementWidth;
430 RegKind RegisterKind;
433 struct VectorIndexOp {
441 struct ShiftedImmOp {
443 unsigned ShiftAmount;
504 unsigned PStateField;
510 struct MatrixRegOp MatrixReg;
511 struct MatrixTileListOp MatrixTileList;
512 struct VectorListOp VectorList;
513 struct VectorIndexOp VectorIndex;
515 struct ShiftedImmOp ShiftedImm;
516 struct ImmRangeOp ImmRange;
518 struct FPImmOp FPImm;
520 struct SysRegOp SysReg;
521 struct SysCRImmOp SysCRImm;
523 struct PSBHintOp PSBHint;
524 struct PHintOp PHint;
525 struct BTIHintOp BTIHint;
526 struct ShiftExtendOp ShiftExtend;
539 StartLoc =
o.StartLoc;
549 ShiftedImm =
o.ShiftedImm;
552 ImmRange =
o.ImmRange;
566 case k_MatrixRegister:
567 MatrixReg =
o.MatrixReg;
569 case k_MatrixTileList:
570 MatrixTileList =
o.MatrixTileList;
573 VectorList =
o.VectorList;
576 VectorIndex =
o.VectorIndex;
582 SysCRImm =
o.SysCRImm;
597 ShiftExtend =
o.ShiftExtend;
606 SMLoc getStartLoc()
const override {
return StartLoc; }
608 SMLoc getEndLoc()
const override {
return EndLoc; }
611 assert(Kind == k_Token &&
"Invalid access!");
615 bool isTokenSuffix()
const {
616 assert(Kind == k_Token &&
"Invalid access!");
620 const MCExpr *getImm()
const {
621 assert(Kind == k_Immediate &&
"Invalid access!");
625 const MCExpr *getShiftedImmVal()
const {
626 assert(Kind == k_ShiftedImm &&
"Invalid access!");
627 return ShiftedImm.Val;
630 unsigned getShiftedImmShift()
const {
631 assert(Kind == k_ShiftedImm &&
"Invalid access!");
632 return ShiftedImm.ShiftAmount;
635 unsigned getFirstImmVal()
const {
636 assert(Kind == k_ImmRange &&
"Invalid access!");
637 return ImmRange.First;
640 unsigned getLastImmVal()
const {
641 assert(Kind == k_ImmRange &&
"Invalid access!");
642 return ImmRange.Last;
646 assert(Kind == k_CondCode &&
"Invalid access!");
651 assert (Kind == k_FPImm &&
"Invalid access!");
652 return APFloat(APFloat::IEEEdouble(),
APInt(64, FPImm.Val,
true));
655 bool getFPImmIsExact()
const {
656 assert (Kind == k_FPImm &&
"Invalid access!");
657 return FPImm.IsExact;
660 unsigned getBarrier()
const {
661 assert(Kind == k_Barrier &&
"Invalid access!");
666 assert(Kind == k_Barrier &&
"Invalid access!");
670 bool getBarriernXSModifier()
const {
671 assert(Kind == k_Barrier &&
"Invalid access!");
676 assert(Kind == k_Register &&
"Invalid access!");
680 unsigned getMatrixReg()
const {
681 assert(Kind == k_MatrixRegister &&
"Invalid access!");
682 return MatrixReg.RegNum;
685 unsigned getMatrixElementWidth()
const {
686 assert(Kind == k_MatrixRegister &&
"Invalid access!");
687 return MatrixReg.ElementWidth;
690 MatrixKind getMatrixKind()
const {
691 assert(Kind == k_MatrixRegister &&
"Invalid access!");
692 return MatrixReg.Kind;
695 unsigned getMatrixTileListRegMask()
const {
696 assert(isMatrixTileList() &&
"Invalid access!");
697 return MatrixTileList.RegMask;
700 RegConstraintEqualityTy getRegEqualityTy()
const {
701 assert(Kind == k_Register &&
"Invalid access!");
702 return Reg.EqualityTy;
705 unsigned getVectorListStart()
const {
706 assert(Kind == k_VectorList &&
"Invalid access!");
707 return VectorList.RegNum;
710 unsigned getVectorListCount()
const {
711 assert(Kind == k_VectorList &&
"Invalid access!");
712 return VectorList.Count;
715 unsigned getVectorListStride()
const {
716 assert(Kind == k_VectorList &&
"Invalid access!");
717 return VectorList.Stride;
720 int getVectorIndex()
const {
721 assert(Kind == k_VectorIndex &&
"Invalid access!");
722 return VectorIndex.Val;
726 assert(Kind == k_SysReg &&
"Invalid access!");
727 return StringRef(SysReg.Data, SysReg.Length);
730 unsigned getSysCR()
const {
731 assert(Kind == k_SysCR &&
"Invalid access!");
735 unsigned getPrefetch()
const {
736 assert(Kind == k_Prefetch &&
"Invalid access!");
740 unsigned getPSBHint()
const {
741 assert(Kind == k_PSBHint &&
"Invalid access!");
745 unsigned getPHint()
const {
746 assert(Kind == k_PHint &&
"Invalid access!");
751 assert(Kind == k_PSBHint &&
"Invalid access!");
752 return StringRef(PSBHint.Data, PSBHint.Length);
756 assert(Kind == k_PHint &&
"Invalid access!");
757 return StringRef(PHint.Data, PHint.Length);
760 unsigned getBTIHint()
const {
761 assert(Kind == k_BTIHint &&
"Invalid access!");
766 assert(Kind == k_BTIHint &&
"Invalid access!");
767 return StringRef(BTIHint.Data, BTIHint.Length);
771 assert(Kind == k_SVCR &&
"Invalid access!");
772 return StringRef(SVCR.Data, SVCR.Length);
776 assert(Kind == k_Prefetch &&
"Invalid access!");
781 if (Kind == k_ShiftExtend)
782 return ShiftExtend.Type;
783 if (Kind == k_Register)
784 return Reg.ShiftExtend.Type;
788 unsigned getShiftExtendAmount()
const {
789 if (Kind == k_ShiftExtend)
790 return ShiftExtend.Amount;
791 if (Kind == k_Register)
792 return Reg.ShiftExtend.Amount;
796 bool hasShiftExtendAmount()
const {
797 if (Kind == k_ShiftExtend)
798 return ShiftExtend.HasExplicitAmount;
799 if (Kind == k_Register)
800 return Reg.ShiftExtend.HasExplicitAmount;
804 bool isImm()
const override {
return Kind == k_Immediate; }
805 bool isMem()
const override {
return false; }
807 bool isUImm6()
const {
814 return (Val >= 0 && Val < 64);
817 template <
int W
idth>
bool isSImm()
const {
return isSImmScaled<Width, 1>(); }
820 return isImmScaled<Bits, Scale>(
true);
823 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
825 if (IsRange && isImmRange() &&
826 (getLastImmVal() != getFirstImmVal() +
Offset))
827 return DiagnosticPredicateTy::NoMatch;
829 return isImmScaled<Bits, Scale, IsRange>(
false);
832 template <
int Bits,
int Scale,
bool IsRange = false>
834 if ((!
isImm() && !isImmRange()) || (
isImm() && IsRange) ||
835 (isImmRange() && !IsRange))
836 return DiagnosticPredicateTy::NoMatch;
840 Val = getFirstImmVal();
844 return DiagnosticPredicateTy::NoMatch;
848 int64_t MinVal, MaxVal;
850 int64_t Shift =
Bits - 1;
851 MinVal = (int64_t(1) << Shift) * -Scale;
852 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
855 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
858 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
859 return DiagnosticPredicateTy::Match;
861 return DiagnosticPredicateTy::NearMatch;
866 return DiagnosticPredicateTy::NoMatch;
867 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
869 return DiagnosticPredicateTy::NoMatch;
871 if (Val >= 0 && Val < 32)
872 return DiagnosticPredicateTy::Match;
873 return DiagnosticPredicateTy::NearMatch;
878 return DiagnosticPredicateTy::NoMatch;
879 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
881 return DiagnosticPredicateTy::NoMatch;
883 if (Val >= 0 && Val <= 1)
884 return DiagnosticPredicateTy::Match;
885 return DiagnosticPredicateTy::NearMatch;
888 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
892 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
926 template <
int Scale>
bool isUImm12Offset()
const {
932 return isSymbolicUImm12Offset(getImm());
935 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
938 template <
int N,
int M>
939 bool isImmInRange()
const {
946 return (Val >=
N && Val <= M);
951 template <
typename T>
952 bool isLogicalImm()
const {
969 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
971 bool isImmRange()
const {
return Kind == k_ImmRange; }
976 template <
unsigned W
idth>
977 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
978 if (isShiftedImm() && Width == getShiftedImmShift())
979 if (
auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
980 return std::make_pair(
CE->getValue(), Width);
983 if (
auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
984 int64_t Val =
CE->getValue();
986 return std::make_pair(Val >> Width, Width);
988 return std::make_pair(Val, 0u);
994 bool isAddSubImm()
const {
995 if (!isShiftedImm() && !
isImm())
1001 if (isShiftedImm()) {
1002 unsigned Shift = ShiftedImm.ShiftAmount;
1003 Expr = ShiftedImm.Val;
1004 if (Shift != 0 && Shift != 12)
1013 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
1014 DarwinRefKind, Addend)) {
1033 if (
auto ShiftedVal = getShiftedVal<12>())
1034 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1041 bool isAddSubImmNeg()
const {
1042 if (!isShiftedImm() && !
isImm())
1046 if (
auto ShiftedVal = getShiftedVal<12>())
1047 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1057 template <
typename T>
1059 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1060 return DiagnosticPredicateTy::NoMatch;
1062 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1063 std::is_same<int8_t, T>::value;
1064 if (
auto ShiftedImm = getShiftedVal<8>())
1065 if (!(IsByte && ShiftedImm->second) &&
1066 AArch64_AM::isSVECpyImm<T>(
uint64_t(ShiftedImm->first)
1067 << ShiftedImm->second))
1068 return DiagnosticPredicateTy::Match;
1070 return DiagnosticPredicateTy::NearMatch;
1077 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1078 return DiagnosticPredicateTy::NoMatch;
1080 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1081 std::is_same<int8_t, T>::value;
1082 if (
auto ShiftedImm = getShiftedVal<8>())
1083 if (!(IsByte && ShiftedImm->second) &&
1084 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
1085 << ShiftedImm->second))
1086 return DiagnosticPredicateTy::Match;
1088 return DiagnosticPredicateTy::NearMatch;
1092 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1093 return DiagnosticPredicateTy::Match;
1094 return DiagnosticPredicateTy::NoMatch;
1097 bool isCondCode()
const {
return Kind == k_CondCode; }
1099 bool isSIMDImmType10()
const {
1109 bool isBranchTarget()
const {
1118 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1119 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1130 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1131 DarwinRefKind, Addend)) {
1140 bool isMovWSymbolG3()
const {
1144 bool isMovWSymbolG2()
const {
1145 return isMovWSymbol(
1152 bool isMovWSymbolG1()
const {
1153 return isMovWSymbol(
1161 bool isMovWSymbolG0()
const {
1162 return isMovWSymbol(
1170 template<
int RegW
idth,
int Shift>
1171 bool isMOVZMovAlias()
const {
1172 if (!
isImm())
return false;
1185 template<
int RegW
idth,
int Shift>
1186 bool isMOVNMovAlias()
const {
1187 if (!
isImm())
return false;
1190 if (!CE)
return false;
1196 bool isFPImm()
const {
1197 return Kind == k_FPImm &&
1201 bool isBarrier()
const {
1202 return Kind == k_Barrier && !getBarriernXSModifier();
1204 bool isBarriernXS()
const {
1205 return Kind == k_Barrier && getBarriernXSModifier();
1207 bool isSysReg()
const {
return Kind == k_SysReg; }
1209 bool isMRSSystemRegister()
const {
1210 if (!isSysReg())
return false;
1212 return SysReg.MRSReg != -1U;
1215 bool isMSRSystemRegister()
const {
1216 if (!isSysReg())
return false;
1217 return SysReg.MSRReg != -1U;
1220 bool isSystemPStateFieldWithImm0_1()
const {
1221 if (!isSysReg())
return false;
1222 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1225 bool isSystemPStateFieldWithImm0_15()
const {
1228 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1231 bool isSVCR()
const {
1234 return SVCR.PStateField != -1U;
1237 bool isReg()
const override {
1238 return Kind == k_Register;
1241 bool isVectorList()
const {
return Kind == k_VectorList; }
1243 bool isScalarReg()
const {
1244 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1247 bool isNeonVectorReg()
const {
1248 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1251 bool isNeonVectorRegLo()
const {
1252 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1253 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1255 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1259 bool isNeonVectorReg0to7()
const {
1260 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1261 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1265 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1266 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1268 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1271 case AArch64::PPRRegClassID:
1272 case AArch64::PPR_3bRegClassID:
1273 case AArch64::PPR_p8to15RegClassID:
1274 case AArch64::PNRRegClassID:
1275 case AArch64::PNR_p8to15RegClassID:
1276 case AArch64::PPRorPNRRegClassID:
1277 RK = RegKind::SVEPredicateAsCounter;
1283 return (Kind == k_Register &&
Reg.Kind == RK) &&
1284 AArch64MCRegisterClasses[
Class].contains(
getReg());
1287 template <
unsigned Class>
bool isSVEVectorReg()
const {
1290 case AArch64::ZPRRegClassID:
1291 case AArch64::ZPR_3bRegClassID:
1292 case AArch64::ZPR_4bRegClassID:
1293 case AArch64::ZPRMul2_LoRegClassID:
1294 case AArch64::ZPRMul2_HiRegClassID:
1295 case AArch64::ZPR_KRegClassID:
1296 RK = RegKind::SVEDataVector;
1298 case AArch64::PPRRegClassID:
1299 case AArch64::PPR_3bRegClassID:
1300 case AArch64::PPR_p8to15RegClassID:
1301 case AArch64::PNRRegClassID:
1302 case AArch64::PNR_p8to15RegClassID:
1303 case AArch64::PPRorPNRRegClassID:
1304 RK = RegKind::SVEPredicateVector;
1310 return (Kind == k_Register &&
Reg.Kind == RK) &&
1311 AArch64MCRegisterClasses[
Class].contains(
getReg());
1314 template <
unsigned Class>
bool isFPRasZPR()
const {
1315 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1316 AArch64MCRegisterClasses[
Class].contains(
getReg());
1319 template <
int ElementW
idth,
unsigned Class>
1321 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1322 return DiagnosticPredicateTy::NoMatch;
1324 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1325 return DiagnosticPredicateTy::Match;
1327 return DiagnosticPredicateTy::NearMatch;
1330 template <
int ElementW
idth,
unsigned Class>
1332 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1333 Reg.Kind != RegKind::SVEPredicateVector))
1334 return DiagnosticPredicateTy::NoMatch;
1336 if ((isSVEPredicateAsCounterReg<Class>() ||
1337 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1338 Reg.ElementWidth == ElementWidth)
1339 return DiagnosticPredicateTy::Match;
1341 return DiagnosticPredicateTy::NearMatch;
1344 template <
int ElementW
idth,
unsigned Class>
1346 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1347 return DiagnosticPredicateTy::NoMatch;
1349 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1350 return DiagnosticPredicateTy::Match;
1352 return DiagnosticPredicateTy::NearMatch;
1355 template <
int ElementW
idth,
unsigned Class>
1357 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1358 return DiagnosticPredicateTy::NoMatch;
1360 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1361 return DiagnosticPredicateTy::Match;
1363 return DiagnosticPredicateTy::NearMatch;
1366 template <
int ElementWidth,
unsigned Class,
1368 bool ShiftWidthAlwaysSame>
1370 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1371 if (!VectorMatch.isMatch())
1372 return DiagnosticPredicateTy::NoMatch;
1377 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1380 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1381 return DiagnosticPredicateTy::NoMatch;
1383 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1384 return DiagnosticPredicateTy::Match;
1386 return DiagnosticPredicateTy::NearMatch;
1389 bool isGPR32as64()
const {
1390 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1391 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1394 bool isGPR64as32()
const {
1395 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1396 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1399 bool isGPR64x8()
const {
1400 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1401 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1405 bool isWSeqPair()
const {
1406 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1407 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1411 bool isXSeqPair()
const {
1412 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1413 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1417 bool isSyspXzrPair()
const {
1418 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1421 template<
int64_t Angle,
int64_t Remainder>
1423 if (!
isImm())
return DiagnosticPredicateTy::NoMatch;
1426 if (!CE)
return DiagnosticPredicateTy::NoMatch;
1429 if (
Value % Angle == Remainder &&
Value <= 270)
1430 return DiagnosticPredicateTy::Match;
1431 return DiagnosticPredicateTy::NearMatch;
1434 template <
unsigned RegClassID>
bool isGPR64()
const {
1435 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1436 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1439 template <
unsigned RegClassID,
int ExtW
idth>
1441 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1442 return DiagnosticPredicateTy::NoMatch;
1444 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1445 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1446 return DiagnosticPredicateTy::Match;
1447 return DiagnosticPredicateTy::NearMatch;
1452 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1453 bool isImplicitlyTypedVectorList()
const {
1454 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1455 VectorList.NumElements == 0 &&
1456 VectorList.RegisterKind == VectorKind &&
1457 (!IsConsecutive || (VectorList.Stride == 1));
1460 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1461 unsigned ElementWidth,
unsigned Stride = 1>
1462 bool isTypedVectorList()
const {
1463 if (Kind != k_VectorList)
1465 if (VectorList.Count != NumRegs)
1467 if (VectorList.RegisterKind != VectorKind)
1469 if (VectorList.ElementWidth != ElementWidth)
1471 if (VectorList.Stride != Stride)
1473 return VectorList.NumElements == NumElements;
1476 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1477 unsigned ElementWidth,
unsigned RegClass>
1480 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1482 return DiagnosticPredicateTy::NoMatch;
1483 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.RegNum))
1484 return DiagnosticPredicateTy::NearMatch;
1485 return DiagnosticPredicateTy::Match;
1488 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1489 unsigned ElementWidth>
1491 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1492 ElementWidth, Stride>();
1494 return DiagnosticPredicateTy::NoMatch;
1495 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1496 ((VectorList.RegNum >= AArch64::Z16) &&
1497 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1498 return DiagnosticPredicateTy::Match;
1499 return DiagnosticPredicateTy::NoMatch;
1502 template <
int Min,
int Max>
1504 if (Kind != k_VectorIndex)
1505 return DiagnosticPredicateTy::NoMatch;
1506 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1507 return DiagnosticPredicateTy::Match;
1508 return DiagnosticPredicateTy::NearMatch;
1511 bool isToken()
const override {
return Kind == k_Token; }
1513 bool isTokenEqual(
StringRef Str)
const {
1514 return Kind == k_Token && getToken() == Str;
1516 bool isSysCR()
const {
return Kind == k_SysCR; }
1517 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1518 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1519 bool isPHint()
const {
return Kind == k_PHint; }
1520 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1521 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1522 bool isShifter()
const {
1523 if (!isShiftExtend())
1533 if (Kind != k_FPImm)
1534 return DiagnosticPredicateTy::NoMatch;
1536 if (getFPImmIsExact()) {
1538 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1542 APFloat RealVal(APFloat::IEEEdouble());
1544 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1545 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1548 if (
getFPImm().bitwiseIsEqual(RealVal))
1549 return DiagnosticPredicateTy::Match;
1552 return DiagnosticPredicateTy::NearMatch;
1555 template <
unsigned ImmA,
unsigned ImmB>
1558 if ((Res = isExactFPImm<ImmA>()))
1559 return DiagnosticPredicateTy::Match;
1560 if ((Res = isExactFPImm<ImmB>()))
1561 return DiagnosticPredicateTy::Match;
1565 bool isExtend()
const {
1566 if (!isShiftExtend())
1575 getShiftExtendAmount() <= 4;
1578 bool isExtend64()
const {
1588 bool isExtendLSL64()
const {
1594 getShiftExtendAmount() <= 4;
1597 bool isLSLImm3Shift()
const {
1598 if (!isShiftExtend())
1604 template<
int W
idth>
bool isMemXExtend()
const {
1609 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1610 getShiftExtendAmount() == 0);
1613 template<
int W
idth>
bool isMemWExtend()
const {
1618 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1619 getShiftExtendAmount() == 0);
1622 template <
unsigned w
idth>
1623 bool isArithmeticShifter()
const {
1633 template <
unsigned w
idth>
1634 bool isLogicalShifter()
const {
1642 getShiftExtendAmount() < width;
1645 bool isMovImm32Shifter()
const {
1653 uint64_t Val = getShiftExtendAmount();
1654 return (Val == 0 || Val == 16);
1657 bool isMovImm64Shifter()
const {
1665 uint64_t Val = getShiftExtendAmount();
1666 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1669 bool isLogicalVecShifter()
const {
1674 unsigned Shift = getShiftExtendAmount();
1676 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1679 bool isLogicalVecHalfWordShifter()
const {
1680 if (!isLogicalVecShifter())
1684 unsigned Shift = getShiftExtendAmount();
1686 (Shift == 0 || Shift == 8);
1689 bool isMoveVecShifter()
const {
1690 if (!isShiftExtend())
1694 unsigned Shift = getShiftExtendAmount();
1696 (Shift == 8 || Shift == 16);
1705 bool isSImm9OffsetFB()
const {
1706 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1709 bool isAdrpLabel()
const {
1716 int64_t Val =
CE->getValue();
1717 int64_t Min = - (4096 * (1LL << (21 - 1)));
1718 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1719 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1725 bool isAdrLabel()
const {
1732 int64_t Val =
CE->getValue();
1733 int64_t Min = - (1LL << (21 - 1));
1734 int64_t
Max = ((1LL << (21 - 1)) - 1);
1735 return Val >= Min && Val <=
Max;
1741 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1744 return DiagnosticPredicateTy::NoMatch;
1745 if (getMatrixKind() != Kind ||
1746 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1747 EltSize != getMatrixElementWidth())
1748 return DiagnosticPredicateTy::NearMatch;
1749 return DiagnosticPredicateTy::Match;
1752 bool isPAuthPCRelLabel16Operand()
const {
1764 return (Val <= 0) && (Val > -(1 << 18));
1771 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1777 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1778 assert(
N == 1 &&
"Invalid number of operands!");
1782 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1783 assert(
N == 1 &&
"Invalid number of operands!");
1787 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1788 assert(
N == 1 &&
"Invalid number of operands!");
1790 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1799 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1800 assert(
N == 1 &&
"Invalid number of operands!");
1802 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1811 template <
int W
idth>
1812 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1815 case 8:
Base = AArch64::B0;
break;
1816 case 16:
Base = AArch64::H0;
break;
1817 case 32:
Base = AArch64::S0;
break;
1818 case 64:
Base = AArch64::D0;
break;
1819 case 128:
Base = AArch64::Q0;
break;
1826 void addPPRorPNRRegOperands(
MCInst &Inst,
unsigned N)
const {
1827 assert(
N == 1 &&
"Invalid number of operands!");
1830 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1831 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1835 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1836 assert(
N == 1 &&
"Invalid number of operands!");
1841 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1842 assert(
N == 1 &&
"Invalid number of operands!");
1844 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1848 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1849 assert(
N == 1 &&
"Invalid number of operands!");
1851 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1855 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1856 assert(
N == 1 &&
"Invalid number of operands!");
1860 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1861 assert(
N == 1 &&
"Invalid number of operands!");
1865 enum VecListIndexType {
1866 VecListIdx_DReg = 0,
1867 VecListIdx_QReg = 1,
1868 VecListIdx_ZReg = 2,
1869 VecListIdx_PReg = 3,
1872 template <VecListIndexType RegTy,
unsigned NumRegs,
1873 bool IsConsecutive =
false>
1874 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1875 assert(
N == 1 &&
"Invalid number of operands!");
1876 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1877 "Expected consecutive registers");
1878 static const unsigned FirstRegs[][5] = {
1880 AArch64::D0, AArch64::D0_D1,
1881 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1883 AArch64::Q0, AArch64::Q0_Q1,
1884 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1886 AArch64::Z0, AArch64::Z0_Z1,
1887 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1889 AArch64::P0, AArch64::P0_P1 }
1892 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1893 " NumRegs must be <= 4 for ZRegs");
1895 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1896 " NumRegs must be <= 2 for PRegs");
1898 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1900 FirstRegs[(
unsigned)RegTy][0]));
1903 template <
unsigned NumRegs>
1904 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1905 assert(
N == 1 &&
"Invalid number of operands!");
1906 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1910 if (getVectorListStart() < AArch64::Z16) {
1911 assert((getVectorListStart() < AArch64::Z8) &&
1912 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1914 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1916 assert((getVectorListStart() < AArch64::Z24) &&
1917 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1919 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1923 if (getVectorListStart() < AArch64::Z16) {
1924 assert((getVectorListStart() < AArch64::Z4) &&
1925 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1927 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1929 assert((getVectorListStart() < AArch64::Z20) &&
1930 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1932 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1940 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1941 assert(
N == 1 &&
"Invalid number of operands!");
1942 unsigned RegMask = getMatrixTileListRegMask();
1943 assert(RegMask <= 0xFF &&
"Invalid mask!");
1947 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1948 assert(
N == 1 &&
"Invalid number of operands!");
1952 template <
unsigned ImmIs0,
unsigned ImmIs1>
1953 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1954 assert(
N == 1 &&
"Invalid number of operands!");
1955 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1959 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1960 assert(
N == 1 &&
"Invalid number of operands!");
1964 addExpr(Inst, getImm());
1967 template <
int Shift>
1968 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1969 assert(
N == 2 &&
"Invalid number of operands!");
1970 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1973 }
else if (isShiftedImm()) {
1974 addExpr(Inst, getShiftedImmVal());
1977 addExpr(Inst, getImm());
1982 template <
int Shift>
1983 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1984 assert(
N == 2 &&
"Invalid number of operands!");
1985 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1992 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1993 assert(
N == 1 &&
"Invalid number of operands!");
1997 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1998 assert(
N == 1 &&
"Invalid number of operands!");
2001 addExpr(Inst, getImm());
2006 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2007 addImmOperands(Inst,
N);
2011 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2012 assert(
N == 1 &&
"Invalid number of operands!");
2022 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
2023 assert(
N == 1 &&
"Invalid number of operands!");
2028 template <
int Scale>
2029 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
2030 assert(
N == 1 &&
"Invalid number of operands!");
2035 template <
int Scale>
2036 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
2037 assert(
N == 1 &&
"Invalid number of operands!");
2041 template <
typename T>
2042 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
2043 assert(
N == 1 &&
"Invalid number of operands!");
2045 std::make_unsigned_t<T> Val = MCE->
getValue();
2050 template <
typename T>
2051 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2052 assert(
N == 1 &&
"Invalid number of operands!");
2054 std::make_unsigned_t<T> Val = ~MCE->getValue();
2059 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
2060 assert(
N == 1 &&
"Invalid number of operands!");
2066 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2070 assert(
N == 1 &&
"Invalid number of operands!");
2073 addExpr(Inst, getImm());
2076 assert(MCE &&
"Invalid constant immediate operand!");
2080 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2084 assert(
N == 1 &&
"Invalid number of operands!");
2087 addExpr(Inst, getImm());
2093 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2097 assert(
N == 1 &&
"Invalid number of operands!");
2100 addExpr(Inst, getImm());
2103 assert(MCE &&
"Invalid constant immediate operand!");
2107 void addPCRelLabel9Operands(
MCInst &Inst,
unsigned N)
const {
2111 assert(
N == 1 &&
"Invalid number of operands!");
2114 addExpr(Inst, getImm());
2117 assert(MCE &&
"Invalid constant immediate operand!");
2121 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2125 assert(
N == 1 &&
"Invalid number of operands!");
2128 addExpr(Inst, getImm());
2131 assert(MCE &&
"Invalid constant immediate operand!");
2135 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2141 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2142 assert(
N == 1 &&
"Invalid number of operands!");
2146 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2147 assert(
N == 1 &&
"Invalid number of operands!");
2151 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2152 assert(
N == 1 &&
"Invalid number of operands!");
2157 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2158 assert(
N == 1 &&
"Invalid number of operands!");
2163 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2164 assert(
N == 1 &&
"Invalid number of operands!");
2169 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2170 assert(
N == 1 &&
"Invalid number of operands!");
2175 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2176 assert(
N == 1 &&
"Invalid number of operands!");
2181 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2182 assert(
N == 1 &&
"Invalid number of operands!");
2186 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2187 assert(
N == 1 &&
"Invalid number of operands!");
2191 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2192 assert(
N == 1 &&
"Invalid number of operands!");
2196 void addPHintOperands(
MCInst &Inst,
unsigned N)
const {
2197 assert(
N == 1 &&
"Invalid number of operands!");
2201 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2202 assert(
N == 1 &&
"Invalid number of operands!");
2206 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2207 assert(
N == 1 &&
"Invalid number of operands!");
2213 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2214 assert(
N == 1 &&
"Invalid number of operands!");
2215 unsigned Imm = getShiftExtendAmount();
2219 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2220 assert(
N == 1 &&
"Invalid number of operands!");
2228 if (
Reg != AArch64::XZR)
2234 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2235 assert(
N == 1 &&
"Invalid number of operands!");
2242 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2243 assert(
N == 1 &&
"Invalid number of operands!");
2250 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2251 assert(
N == 2 &&
"Invalid number of operands!");
2262 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2263 assert(
N == 2 &&
"Invalid number of operands!");
2271 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2272 assert(
N == 1 &&
"Invalid number of operands!");
2279 addExpr(Inst, getImm());
2284 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2285 assert(
N == 1 &&
"Invalid number of operands!");
2292 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2293 assert(
N == 1 &&
"Invalid number of operands!");
2298 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2299 assert(
N == 1 &&
"Invalid number of operands!");
2306 static std::unique_ptr<AArch64Operand>
2308 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2309 Op->Tok.Data = Str.data();
2310 Op->Tok.Length = Str.size();
2311 Op->Tok.IsSuffix = IsSuffix;
2317 static std::unique_ptr<AArch64Operand>
2319 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2321 unsigned ShiftAmount = 0,
2322 unsigned HasExplicitAmount =
false) {
2323 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2324 Op->Reg.RegNum = RegNum;
2326 Op->Reg.ElementWidth = 0;
2327 Op->Reg.EqualityTy = EqTy;
2328 Op->Reg.ShiftExtend.Type = ExtTy;
2329 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2330 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2336 static std::unique_ptr<AArch64Operand>
2337 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2340 unsigned ShiftAmount = 0,
2341 unsigned HasExplicitAmount =
false) {
2342 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2343 Kind == RegKind::SVEPredicateVector ||
2344 Kind == RegKind::SVEPredicateAsCounter) &&
2345 "Invalid vector kind");
2346 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2348 Op->Reg.ElementWidth = ElementWidth;
2352 static std::unique_ptr<AArch64Operand>
2353 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2354 unsigned NumElements,
unsigned ElementWidth,
2356 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2357 Op->VectorList.RegNum = RegNum;
2358 Op->VectorList.Count = Count;
2359 Op->VectorList.Stride = Stride;
2360 Op->VectorList.NumElements = NumElements;
2361 Op->VectorList.ElementWidth = ElementWidth;
2362 Op->VectorList.RegisterKind = RegisterKind;
2368 static std::unique_ptr<AArch64Operand>
2370 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2371 Op->VectorIndex.Val =
Idx;
2377 static std::unique_ptr<AArch64Operand>
2379 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2380 Op->MatrixTileList.RegMask = RegMask;
2387 const unsigned ElementWidth) {
2388 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2390 {{0, AArch64::ZAB0},
2391 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2392 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2393 {{8, AArch64::ZAB0},
2394 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2395 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2396 {{16, AArch64::ZAH0},
2397 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2398 {{16, AArch64::ZAH1},
2399 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2400 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2401 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2402 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2403 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2406 if (ElementWidth == 64)
2409 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2410 assert(!Regs.empty() &&
"Invalid tile or element width!");
2411 for (
auto OutReg : Regs)
2416 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2418 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2425 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2426 unsigned ShiftAmount,
2429 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2430 Op->ShiftedImm .Val = Val;
2431 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2437 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2441 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2443 Op->ImmRange.Last =
Last;
2448 static std::unique_ptr<AArch64Operand>
2450 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2451 Op->CondCode.Code =
Code;
2457 static std::unique_ptr<AArch64Operand>
2459 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2461 Op->FPImm.IsExact = IsExact;
2467 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2471 bool HasnXSModifier) {
2472 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2473 Op->Barrier.Val = Val;
2474 Op->Barrier.Data = Str.data();
2475 Op->Barrier.Length = Str.size();
2476 Op->Barrier.HasnXSModifier = HasnXSModifier;
2482 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2487 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2488 Op->SysReg.Data = Str.data();
2489 Op->SysReg.Length = Str.size();
2490 Op->SysReg.MRSReg = MRSReg;
2491 Op->SysReg.MSRReg = MSRReg;
2492 Op->SysReg.PStateField = PStateField;
2498 static std::unique_ptr<AArch64Operand>
2500 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2501 Op->PHint.Val = Val;
2502 Op->PHint.Data = Str.data();
2503 Op->PHint.Length = Str.size();
2509 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2511 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2512 Op->SysCRImm.Val = Val;
2518 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2522 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2523 Op->Prefetch.Val = Val;
2524 Op->Barrier.Data = Str.data();
2525 Op->Barrier.Length = Str.size();
2531 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2535 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2536 Op->PSBHint.Val = Val;
2537 Op->PSBHint.Data = Str.data();
2538 Op->PSBHint.Length = Str.size();
2544 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2548 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2549 Op->BTIHint.Val = Val | 32;
2550 Op->BTIHint.Data = Str.data();
2551 Op->BTIHint.Length = Str.size();
2557 static std::unique_ptr<AArch64Operand>
2558 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2560 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2561 Op->MatrixReg.RegNum = RegNum;
2562 Op->MatrixReg.ElementWidth = ElementWidth;
2563 Op->MatrixReg.Kind =
Kind;
2569 static std::unique_ptr<AArch64Operand>
2571 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2572 Op->SVCR.PStateField = PStateField;
2573 Op->SVCR.Data = Str.data();
2574 Op->SVCR.Length = Str.size();
2580 static std::unique_ptr<AArch64Operand>
2583 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2584 Op->ShiftExtend.Type = ShOp;
2585 Op->ShiftExtend.Amount = Val;
2586 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2598 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2599 if (!getFPImmIsExact())
2606 OS <<
"<barrier " <<
Name <<
">";
2608 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2614 case k_ShiftedImm: {
2615 unsigned Shift = getShiftedImmShift();
2616 OS <<
"<shiftedimm ";
2617 OS << *getShiftedImmVal();
2623 OS << getFirstImmVal();
2624 OS <<
":" << getLastImmVal() <<
">";
2630 case k_VectorList: {
2631 OS <<
"<vectorlist ";
2632 unsigned Reg = getVectorListStart();
2633 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2634 OS <<
Reg + i * getVectorListStride() <<
" ";
2639 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2642 OS <<
"<sysreg: " << getSysReg() <<
'>';
2645 OS <<
"'" << getToken() <<
"'";
2648 OS <<
"c" << getSysCR();
2653 OS <<
"<prfop " <<
Name <<
">";
2655 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2659 OS << getPSBHintName();
2662 OS << getPHintName();
2665 OS << getBTIHintName();
2667 case k_MatrixRegister:
2668 OS <<
"<matrix " << getMatrixReg() <<
">";
2670 case k_MatrixTileList: {
2671 OS <<
"<matrixlist ";
2672 unsigned RegMask = getMatrixTileListRegMask();
2673 unsigned MaxBits = 8;
2674 for (
unsigned I = MaxBits;
I > 0; --
I)
2675 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2684 OS <<
"<register " <<
getReg() <<
">";
2685 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2690 << getShiftExtendAmount();
2691 if (!hasShiftExtendAmount())
2707 .
Case(
"v0", AArch64::Q0)
2708 .
Case(
"v1", AArch64::Q1)
2709 .
Case(
"v2", AArch64::Q2)
2710 .
Case(
"v3", AArch64::Q3)
2711 .
Case(
"v4", AArch64::Q4)
2712 .
Case(
"v5", AArch64::Q5)
2713 .
Case(
"v6", AArch64::Q6)
2714 .
Case(
"v7", AArch64::Q7)
2715 .
Case(
"v8", AArch64::Q8)
2716 .
Case(
"v9", AArch64::Q9)
2717 .
Case(
"v10", AArch64::Q10)
2718 .
Case(
"v11", AArch64::Q11)
2719 .
Case(
"v12", AArch64::Q12)
2720 .
Case(
"v13", AArch64::Q13)
2721 .
Case(
"v14", AArch64::Q14)
2722 .
Case(
"v15", AArch64::Q15)
2723 .
Case(
"v16", AArch64::Q16)
2724 .
Case(
"v17", AArch64::Q17)
2725 .
Case(
"v18", AArch64::Q18)
2726 .
Case(
"v19", AArch64::Q19)
2727 .
Case(
"v20", AArch64::Q20)
2728 .
Case(
"v21", AArch64::Q21)
2729 .
Case(
"v22", AArch64::Q22)
2730 .
Case(
"v23", AArch64::Q23)
2731 .
Case(
"v24", AArch64::Q24)
2732 .
Case(
"v25", AArch64::Q25)
2733 .
Case(
"v26", AArch64::Q26)
2734 .
Case(
"v27", AArch64::Q27)
2735 .
Case(
"v28", AArch64::Q28)
2736 .
Case(
"v29", AArch64::Q29)
2737 .
Case(
"v30", AArch64::Q30)
2738 .
Case(
"v31", AArch64::Q31)
2747 RegKind VectorKind) {
2748 std::pair<int, int> Res = {-1, -1};
2750 switch (VectorKind) {
2751 case RegKind::NeonVector:
2754 .Case(
".1d", {1, 64})
2755 .Case(
".1q", {1, 128})
2757 .Case(
".2h", {2, 16})
2758 .Case(
".2b", {2, 8})
2759 .Case(
".2s", {2, 32})
2760 .Case(
".2d", {2, 64})
2763 .Case(
".4b", {4, 8})
2764 .Case(
".4h", {4, 16})
2765 .Case(
".4s", {4, 32})
2766 .Case(
".8b", {8, 8})
2767 .Case(
".8h", {8, 16})
2768 .Case(
".16b", {16, 8})
2773 .Case(
".h", {0, 16})
2774 .Case(
".s", {0, 32})
2775 .Case(
".d", {0, 64})
2778 case RegKind::SVEPredicateAsCounter:
2779 case RegKind::SVEPredicateVector:
2780 case RegKind::SVEDataVector:
2781 case RegKind::Matrix:
2785 .Case(
".h", {0, 16})
2786 .Case(
".s", {0, 32})
2787 .Case(
".d", {0, 64})
2788 .Case(
".q", {0, 128})
2795 if (Res == std::make_pair(-1, -1))
2796 return std::nullopt;
2798 return std::optional<std::pair<int, int>>(Res);
2807 .
Case(
"z0", AArch64::Z0)
2808 .
Case(
"z1", AArch64::Z1)
2809 .
Case(
"z2", AArch64::Z2)
2810 .
Case(
"z3", AArch64::Z3)
2811 .
Case(
"z4", AArch64::Z4)
2812 .
Case(
"z5", AArch64::Z5)
2813 .
Case(
"z6", AArch64::Z6)
2814 .
Case(
"z7", AArch64::Z7)
2815 .
Case(
"z8", AArch64::Z8)
2816 .
Case(
"z9", AArch64::Z9)
2817 .
Case(
"z10", AArch64::Z10)
2818 .
Case(
"z11", AArch64::Z11)
2819 .
Case(
"z12", AArch64::Z12)
2820 .
Case(
"z13", AArch64::Z13)
2821 .
Case(
"z14", AArch64::Z14)
2822 .
Case(
"z15", AArch64::Z15)
2823 .
Case(
"z16", AArch64::Z16)
2824 .
Case(
"z17", AArch64::Z17)
2825 .
Case(
"z18", AArch64::Z18)
2826 .
Case(
"z19", AArch64::Z19)
2827 .
Case(
"z20", AArch64::Z20)
2828 .
Case(
"z21", AArch64::Z21)
2829 .
Case(
"z22", AArch64::Z22)
2830 .
Case(
"z23", AArch64::Z23)
2831 .
Case(
"z24", AArch64::Z24)
2832 .
Case(
"z25", AArch64::Z25)
2833 .
Case(
"z26", AArch64::Z26)
2834 .
Case(
"z27", AArch64::Z27)
2835 .
Case(
"z28", AArch64::Z28)
2836 .
Case(
"z29", AArch64::Z29)
2837 .
Case(
"z30", AArch64::Z30)
2838 .
Case(
"z31", AArch64::Z31)
2844 .
Case(
"p0", AArch64::P0)
2845 .
Case(
"p1", AArch64::P1)
2846 .
Case(
"p2", AArch64::P2)
2847 .
Case(
"p3", AArch64::P3)
2848 .
Case(
"p4", AArch64::P4)
2849 .
Case(
"p5", AArch64::P5)
2850 .
Case(
"p6", AArch64::P6)
2851 .
Case(
"p7", AArch64::P7)
2852 .
Case(
"p8", AArch64::P8)
2853 .
Case(
"p9", AArch64::P9)
2854 .
Case(
"p10", AArch64::P10)
2855 .
Case(
"p11", AArch64::P11)
2856 .
Case(
"p12", AArch64::P12)
2857 .
Case(
"p13", AArch64::P13)
2858 .
Case(
"p14", AArch64::P14)
2859 .
Case(
"p15", AArch64::P15)
2865 .
Case(
"pn0", AArch64::PN0)
2866 .
Case(
"pn1", AArch64::PN1)
2867 .
Case(
"pn2", AArch64::PN2)
2868 .
Case(
"pn3", AArch64::PN3)
2869 .
Case(
"pn4", AArch64::PN4)
2870 .
Case(
"pn5", AArch64::PN5)
2871 .
Case(
"pn6", AArch64::PN6)
2872 .
Case(
"pn7", AArch64::PN7)
2873 .
Case(
"pn8", AArch64::PN8)
2874 .
Case(
"pn9", AArch64::PN9)
2875 .
Case(
"pn10", AArch64::PN10)
2876 .
Case(
"pn11", AArch64::PN11)
2877 .
Case(
"pn12", AArch64::PN12)
2878 .
Case(
"pn13", AArch64::PN13)
2879 .
Case(
"pn14", AArch64::PN14)
2880 .
Case(
"pn15", AArch64::PN15)
2886 .
Case(
"za0.d", AArch64::ZAD0)
2887 .
Case(
"za1.d", AArch64::ZAD1)
2888 .
Case(
"za2.d", AArch64::ZAD2)
2889 .
Case(
"za3.d", AArch64::ZAD3)
2890 .
Case(
"za4.d", AArch64::ZAD4)
2891 .
Case(
"za5.d", AArch64::ZAD5)
2892 .
Case(
"za6.d", AArch64::ZAD6)
2893 .
Case(
"za7.d", AArch64::ZAD7)
2894 .
Case(
"za0.s", AArch64::ZAS0)
2895 .
Case(
"za1.s", AArch64::ZAS1)
2896 .
Case(
"za2.s", AArch64::ZAS2)
2897 .
Case(
"za3.s", AArch64::ZAS3)
2898 .
Case(
"za0.h", AArch64::ZAH0)
2899 .
Case(
"za1.h", AArch64::ZAH1)
2900 .
Case(
"za0.b", AArch64::ZAB0)
2906 .
Case(
"za", AArch64::ZA)
2907 .
Case(
"za0.q", AArch64::ZAQ0)
2908 .
Case(
"za1.q", AArch64::ZAQ1)
2909 .
Case(
"za2.q", AArch64::ZAQ2)
2910 .
Case(
"za3.q", AArch64::ZAQ3)
2911 .
Case(
"za4.q", AArch64::ZAQ4)
2912 .
Case(
"za5.q", AArch64::ZAQ5)
2913 .
Case(
"za6.q", AArch64::ZAQ6)
2914 .
Case(
"za7.q", AArch64::ZAQ7)
2915 .
Case(
"za8.q", AArch64::ZAQ8)
2916 .
Case(
"za9.q", AArch64::ZAQ9)
2917 .
Case(
"za10.q", AArch64::ZAQ10)
2918 .
Case(
"za11.q", AArch64::ZAQ11)
2919 .
Case(
"za12.q", AArch64::ZAQ12)
2920 .
Case(
"za13.q", AArch64::ZAQ13)
2921 .
Case(
"za14.q", AArch64::ZAQ14)
2922 .
Case(
"za15.q", AArch64::ZAQ15)
2923 .
Case(
"za0.d", AArch64::ZAD0)
2924 .
Case(
"za1.d", AArch64::ZAD1)
2925 .
Case(
"za2.d", AArch64::ZAD2)
2926 .
Case(
"za3.d", AArch64::ZAD3)
2927 .
Case(
"za4.d", AArch64::ZAD4)
2928 .
Case(
"za5.d", AArch64::ZAD5)
2929 .
Case(
"za6.d", AArch64::ZAD6)
2930 .
Case(
"za7.d", AArch64::ZAD7)
2931 .
Case(
"za0.s", AArch64::ZAS0)
2932 .
Case(
"za1.s", AArch64::ZAS1)
2933 .
Case(
"za2.s", AArch64::ZAS2)
2934 .
Case(
"za3.s", AArch64::ZAS3)
2935 .
Case(
"za0.h", AArch64::ZAH0)
2936 .
Case(
"za1.h", AArch64::ZAH1)
2937 .
Case(
"za0.b", AArch64::ZAB0)
2938 .
Case(
"za0h.q", AArch64::ZAQ0)
2939 .
Case(
"za1h.q", AArch64::ZAQ1)
2940 .
Case(
"za2h.q", AArch64::ZAQ2)
2941 .
Case(
"za3h.q", AArch64::ZAQ3)
2942 .
Case(
"za4h.q", AArch64::ZAQ4)
2943 .
Case(
"za5h.q", AArch64::ZAQ5)
2944 .
Case(
"za6h.q", AArch64::ZAQ6)
2945 .
Case(
"za7h.q", AArch64::ZAQ7)
2946 .
Case(
"za8h.q", AArch64::ZAQ8)
2947 .
Case(
"za9h.q", AArch64::ZAQ9)
2948 .
Case(
"za10h.q", AArch64::ZAQ10)
2949 .
Case(
"za11h.q", AArch64::ZAQ11)
2950 .
Case(
"za12h.q", AArch64::ZAQ12)
2951 .
Case(
"za13h.q", AArch64::ZAQ13)
2952 .
Case(
"za14h.q", AArch64::ZAQ14)
2953 .
Case(
"za15h.q", AArch64::ZAQ15)
2954 .
Case(
"za0h.d", AArch64::ZAD0)
2955 .
Case(
"za1h.d", AArch64::ZAD1)
2956 .
Case(
"za2h.d", AArch64::ZAD2)
2957 .
Case(
"za3h.d", AArch64::ZAD3)
2958 .
Case(
"za4h.d", AArch64::ZAD4)
2959 .
Case(
"za5h.d", AArch64::ZAD5)
2960 .
Case(
"za6h.d", AArch64::ZAD6)
2961 .
Case(
"za7h.d", AArch64::ZAD7)
2962 .
Case(
"za0h.s", AArch64::ZAS0)
2963 .
Case(
"za1h.s", AArch64::ZAS1)
2964 .
Case(
"za2h.s", AArch64::ZAS2)
2965 .
Case(
"za3h.s", AArch64::ZAS3)
2966 .
Case(
"za0h.h", AArch64::ZAH0)
2967 .
Case(
"za1h.h", AArch64::ZAH1)
2968 .
Case(
"za0h.b", AArch64::ZAB0)
2969 .
Case(
"za0v.q", AArch64::ZAQ0)
2970 .
Case(
"za1v.q", AArch64::ZAQ1)
2971 .
Case(
"za2v.q", AArch64::ZAQ2)
2972 .
Case(
"za3v.q", AArch64::ZAQ3)
2973 .
Case(
"za4v.q", AArch64::ZAQ4)
2974 .
Case(
"za5v.q", AArch64::ZAQ5)
2975 .
Case(
"za6v.q", AArch64::ZAQ6)
2976 .
Case(
"za7v.q", AArch64::ZAQ7)
2977 .
Case(
"za8v.q", AArch64::ZAQ8)
2978 .
Case(
"za9v.q", AArch64::ZAQ9)
2979 .
Case(
"za10v.q", AArch64::ZAQ10)
2980 .
Case(
"za11v.q", AArch64::ZAQ11)
2981 .
Case(
"za12v.q", AArch64::ZAQ12)
2982 .
Case(
"za13v.q", AArch64::ZAQ13)
2983 .
Case(
"za14v.q", AArch64::ZAQ14)
2984 .
Case(
"za15v.q", AArch64::ZAQ15)
2985 .
Case(
"za0v.d", AArch64::ZAD0)
2986 .
Case(
"za1v.d", AArch64::ZAD1)
2987 .
Case(
"za2v.d", AArch64::ZAD2)
2988 .
Case(
"za3v.d", AArch64::ZAD3)
2989 .
Case(
"za4v.d", AArch64::ZAD4)
2990 .
Case(
"za5v.d", AArch64::ZAD5)
2991 .
Case(
"za6v.d", AArch64::ZAD6)
2992 .
Case(
"za7v.d", AArch64::ZAD7)
2993 .
Case(
"za0v.s", AArch64::ZAS0)
2994 .
Case(
"za1v.s", AArch64::ZAS1)
2995 .
Case(
"za2v.s", AArch64::ZAS2)
2996 .
Case(
"za3v.s", AArch64::ZAS3)
2997 .
Case(
"za0v.h", AArch64::ZAH0)
2998 .
Case(
"za1v.h", AArch64::ZAH1)
2999 .
Case(
"za0v.b", AArch64::ZAB0)
3005 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3010 StartLoc = getLoc();
3017unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
3019 unsigned RegNum = 0;
3021 return Kind == RegKind::SVEDataVector ? RegNum : 0;
3024 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
3027 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
3030 return Kind == RegKind::NeonVector ? RegNum : 0;
3033 return Kind == RegKind::Matrix ? RegNum : 0;
3035 if (
Name.equals_insensitive(
"zt0"))
3036 return Kind == RegKind::LookupTable ?
unsigned(AArch64::ZT0) : 0;
3040 return (Kind == RegKind::Scalar) ? RegNum : 0;
3045 .
Case(
"fp", AArch64::FP)
3046 .
Case(
"lr", AArch64::LR)
3047 .
Case(
"x31", AArch64::XZR)
3048 .
Case(
"w31", AArch64::WZR)
3050 return Kind == RegKind::Scalar ? RegNum : 0;
3056 if (Entry == RegisterReqs.
end())
3060 if (Kind ==
Entry->getValue().first)
3061 RegNum =
Entry->getValue().second;
3066unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3068 case RegKind::Scalar:
3069 case RegKind::NeonVector:
3070 case RegKind::SVEDataVector:
3072 case RegKind::Matrix:
3073 case RegKind::SVEPredicateVector:
3074 case RegKind::SVEPredicateAsCounter:
3076 case RegKind::LookupTable:
3091 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3105 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3108 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3109 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3113 if (BadNum || CRNum > 15)
3114 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3118 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3127 unsigned MaxVal = 63;
3133 if (getParser().parseExpression(ImmVal))
3138 return TokError(
"immediate value expected for prefetch operand");
3141 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3144 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3145 Operands.push_back(AArch64Operand::CreatePrefetch(
3146 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3151 return TokError(
"prefetch hint expected");
3153 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3155 return TokError(
"prefetch hint expected");
3157 Operands.push_back(AArch64Operand::CreatePrefetch(
3158 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3164template <
bool IsSVEPrefetch>
3170 if (IsSVEPrefetch) {
3171 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3172 return std::optional<unsigned>(Res->Encoding);
3173 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3174 return std::optional<unsigned>(Res->Encoding);
3175 return std::optional<unsigned>();
3178 auto LookupByEncoding = [](
unsigned E) {
3179 if (IsSVEPrefetch) {
3180 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3181 return std::optional<StringRef>(Res->Name);
3182 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3183 return std::optional<StringRef>(Res->Name);
3184 return std::optional<StringRef>();
3186 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3193 if (getParser().parseExpression(ImmVal))
3198 return TokError(
"immediate value expected for prefetch operand");
3201 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3204 auto PRFM = LookupByEncoding(MCE->
getValue());
3205 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3211 return TokError(
"prefetch hint expected");
3213 auto PRFM = LookupByName(Tok.
getString());
3215 return TokError(
"prefetch hint expected");
3217 Operands.push_back(AArch64Operand::CreatePrefetch(
3218 *PRFM, Tok.
getString(), S, getContext()));
3228 return TokError(
"invalid operand for instruction");
3230 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3232 return TokError(
"invalid operand for instruction");
3234 Operands.push_back(AArch64Operand::CreatePSBHint(
3235 PSB->Encoding, Tok.
getString(), S, getContext()));
3241 SMLoc StartLoc = getLoc();
3247 auto RegTok = getTok();
3248 if (!tryParseScalarRegister(RegNum).isSuccess())
3251 if (RegNum != AArch64::XZR) {
3252 getLexer().UnLex(RegTok);
3259 if (!tryParseScalarRegister(RegNum).isSuccess())
3260 return TokError(
"expected register operand");
3262 if (RegNum != AArch64::XZR)
3263 return TokError(
"xzr must be followed by xzr");
3267 Operands.push_back(AArch64Operand::CreateReg(
3268 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3278 return TokError(
"invalid operand for instruction");
3280 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3282 return TokError(
"invalid operand for instruction");
3284 Operands.push_back(AArch64Operand::CreateBTIHint(
3285 BTI->Encoding, Tok.
getString(), S, getContext()));
3294 const MCExpr *Expr =
nullptr;
3300 if (parseSymbolicImmVal(Expr))
3306 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3316 return Error(S,
"gotpage label reference not allowed an addend");
3328 return Error(S,
"page or gotpage label reference expected");
3336 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3345 const MCExpr *Expr =
nullptr;
3354 if (parseSymbolicImmVal(Expr))
3360 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3373 return Error(S,
"unexpected adr label");
3378 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3383template <
bool AddFPZeroAsLiteral>
3396 return TokError(
"invalid floating point immediate");
3401 if (Tok.
getIntVal() > 255 || isNegative)
3402 return TokError(
"encoded floating point value out of range");
3406 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3409 APFloat RealVal(APFloat::IEEEdouble());
3411 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3413 return TokError(
"invalid floating point representation");
3416 RealVal.changeSign();
3418 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3419 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3420 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3422 Operands.push_back(AArch64Operand::CreateFPImm(
3423 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3448 if (parseSymbolicImmVal(Imm))
3452 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3459 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3461 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3463 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3469 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3470 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3478 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3480 int64_t ShiftAmount = getTok().getIntVal();
3482 if (ShiftAmount < 0)
3483 return Error(getLoc(),
"positive shift amount required");
3487 if (ShiftAmount == 0 && Imm !=
nullptr) {
3489 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3493 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3494 getLoc(), getContext()));
3501AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3538 Suggestion =
"nfrst";
3545 bool invertCondCode) {
3551 std::string Suggestion;
3554 std::string Msg =
"invalid condition code";
3555 if (!Suggestion.empty())
3556 Msg +=
", did you mean " + Suggestion +
"?";
3557 return TokError(Msg);
3561 if (invertCondCode) {
3563 return TokError(
"condition codes AL and NV are invalid for this instruction");
3568 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3577 return TokError(
"invalid operand for instruction");
3579 unsigned PStateImm = -1;
3580 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3583 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3584 PStateImm = SVCR->Encoding;
3587 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3598 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3600 unsigned ElementWidth = 0;
3601 auto DotPosition =
Name.find(
'.');
3603 const auto &KindRes =
3607 "Expected the register to be followed by element width suffix");
3608 ElementWidth = KindRes->second;
3610 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3611 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3616 if (parseOperand(
Operands,
false,
false))
3623 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3627 size_t DotPosition =
Name.find(
'.');
3635 .
Case(
"h", MatrixKind::Row)
3636 .
Case(
"v", MatrixKind::Col)
3643 "Expected the register to be followed by element width suffix");
3644 unsigned ElementWidth = KindRes->second;
3648 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3649 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3654 if (parseOperand(
Operands,
false,
false))
3696 return TokError(
"expected #imm after shift specifier");
3702 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3711 return Error(
E,
"expected integer shift amount");
3714 if (getParser().parseExpression(ImmVal))
3719 return Error(
E,
"expected constant '#imm' after shift specifier");
3722 Operands.push_back(AArch64Operand::CreateShiftExtend(
3723 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3731 {
"crc", {AArch64::FeatureCRC}},
3732 {
"sm4", {AArch64::FeatureSM4}},
3733 {
"sha3", {AArch64::FeatureSHA3}},
3734 {
"sha2", {AArch64::FeatureSHA2}},
3735 {
"aes", {AArch64::FeatureAES}},
3736 {
"crypto", {AArch64::FeatureCrypto}},
3737 {
"fp", {AArch64::FeatureFPARMv8}},
3738 {
"simd", {AArch64::FeatureNEON}},
3739 {
"ras", {AArch64::FeatureRAS}},
3740 {
"rasv2", {AArch64::FeatureRASv2}},
3741 {
"lse", {AArch64::FeatureLSE}},
3742 {
"predres", {AArch64::FeaturePredRes}},
3743 {
"predres2", {AArch64::FeatureSPECRES2}},
3744 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3745 {
"mte", {AArch64::FeatureMTE}},
3746 {
"memtag", {AArch64::FeatureMTE}},
3747 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3748 {
"pan", {AArch64::FeaturePAN}},
3749 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3750 {
"ccpp", {AArch64::FeatureCCPP}},
3751 {
"rcpc", {AArch64::FeatureRCPC}},
3752 {
"rng", {AArch64::FeatureRandGen}},
3753 {
"sve", {AArch64::FeatureSVE}},
3754 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3755 {
"sve2", {AArch64::FeatureSVE2}},
3756 {
"sve-aes", {AArch64::FeatureSVEAES}},
3757 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3758 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3759 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3760 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3762 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3763 AArch64::FeatureSVE2}},
3764 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3765 {
"ls64", {AArch64::FeatureLS64}},
3766 {
"xs", {AArch64::FeatureXS}},
3767 {
"pauth", {AArch64::FeaturePAuth}},
3768 {
"flagm", {AArch64::FeatureFlagM}},
3769 {
"rme", {AArch64::FeatureRME}},
3770 {
"sme", {AArch64::FeatureSME}},
3771 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3772 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3773 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3774 {
"sme2", {AArch64::FeatureSME2}},
3775 {
"sme2p1", {AArch64::FeatureSME2p1}},
3776 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3777 {
"hbc", {AArch64::FeatureHBC}},
3778 {
"mops", {AArch64::FeatureMOPS}},
3779 {
"mec", {AArch64::FeatureMEC}},
3780 {
"the", {AArch64::FeatureTHE}},
3781 {
"d128", {AArch64::FeatureD128}},
3782 {
"lse128", {AArch64::FeatureLSE128}},
3783 {
"ite", {AArch64::FeatureITE}},
3784 {
"cssc", {AArch64::FeatureCSSC}},
3785 {
"rcpc3", {AArch64::FeatureRCPC3}},
3786 {
"gcs", {AArch64::FeatureGCS}},
3787 {
"bf16", {AArch64::FeatureBF16}},
3788 {
"compnum", {AArch64::FeatureComplxNum}},
3789 {
"dotprod", {AArch64::FeatureDotProd}},
3790 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3791 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3792 {
"fp16", {AArch64::FeatureFullFP16}},
3793 {
"fp16fml", {AArch64::FeatureFP16FML}},
3794 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3795 {
"lor", {AArch64::FeatureLOR}},
3796 {
"profile", {AArch64::FeatureSPE}},
3800 {
"rdm", {AArch64::FeatureRDM}},
3801 {
"rdma", {AArch64::FeatureRDM}},
3802 {
"sb", {AArch64::FeatureSB}},
3803 {
"ssbs", {AArch64::FeatureSSBS}},
3804 {
"tme", {AArch64::FeatureTME}},
3805 {
"fp8", {AArch64::FeatureFP8}},
3806 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3807 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3808 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3809 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3810 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3811 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3812 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3813 {
"lut", {AArch64::FeatureLUT}},
3814 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3815 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3816 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3817 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3818 {
"cpa", {AArch64::FeatureCPA}},
3819 {
"tlbiw", {AArch64::FeatureTLBIW}},
3820 {
"pops", {AArch64::FeaturePoPS}},
3821 {
"cmpbr", {AArch64::FeatureCMPBR}},
3822 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3823 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3824 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3825 {
"lsfe", {AArch64::FeatureLSFE}},
3826 {
"sme2p2", {AArch64::FeatureSME2p2}},
3827 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3828 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3829 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3830 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3831 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3832 {
"lsui", {AArch64::FeatureLSUI}},
3833 {
"occmo", {AArch64::FeatureOCCMO}},
3834 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3835 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3836 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3837 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3841 if (FBS[AArch64::HasV8_0aOps])
3843 if (FBS[AArch64::HasV8_1aOps])
3845 else if (FBS[AArch64::HasV8_2aOps])
3847 else if (FBS[AArch64::HasV8_3aOps])
3849 else if (FBS[AArch64::HasV8_4aOps])
3851 else if (FBS[AArch64::HasV8_5aOps])
3853 else if (FBS[AArch64::HasV8_6aOps])
3855 else if (FBS[AArch64::HasV8_7aOps])
3857 else if (FBS[AArch64::HasV8_8aOps])
3859 else if (FBS[AArch64::HasV8_9aOps])
3861 else if (FBS[AArch64::HasV9_0aOps])
3863 else if (FBS[AArch64::HasV9_1aOps])
3865 else if (FBS[AArch64::HasV9_2aOps])
3867 else if (FBS[AArch64::HasV9_3aOps])
3869 else if (FBS[AArch64::HasV9_4aOps])
3871 else if (FBS[AArch64::HasV9_5aOps])
3873 else if (FBS[AArch64::HasV9_6aOps])
3875 else if (FBS[AArch64::HasV8_0rOps])
3884 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3891 const uint16_t Cm = (Encoding & 0x78) >> 3;
3892 const uint16_t Cn = (Encoding & 0x780) >> 7;
3893 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3898 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3900 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3902 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3905 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3912 if (
Name.contains(
'.'))
3913 return TokError(
"invalid operand");
3916 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3922 if (Mnemonic ==
"ic") {
3925 return TokError(
"invalid operand for IC instruction");
3926 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3927 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3929 return TokError(Str);
3932 }
else if (Mnemonic ==
"dc") {
3935 return TokError(
"invalid operand for DC instruction");
3936 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3937 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3939 return TokError(Str);
3942 }
else if (Mnemonic ==
"at") {
3945 return TokError(
"invalid operand for AT instruction");
3946 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3947 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3949 return TokError(Str);
3952 }
else if (Mnemonic ==
"tlbi") {
3955 return TokError(
"invalid operand for TLBI instruction");
3956 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3957 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3959 return TokError(Str);
3962 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3964 if (
Op.lower() !=
"rctx")
3965 return TokError(
"invalid operand for prediction restriction instruction");
3967 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3968 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3969 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3971 if (Mnemonic ==
"cosp" && !hasSpecres2)
3972 return TokError(
"COSP requires: predres2");
3974 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3976 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3977 : Mnemonic ==
"dvp" ? 0b101
3978 : Mnemonic ==
"cosp" ? 0b110
3979 : Mnemonic ==
"cpp" ? 0b111
3982 "Invalid mnemonic for prediction restriction instruction");
3983 const auto SYS_3_7_3 = 0b01101110011;
3984 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3986 createSysAlias(Encoding,
Operands, S);
3991 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3992 bool HasRegister =
false;
3997 return TokError(
"expected register operand");
4001 if (ExpectRegister && !HasRegister)
4002 return TokError(
"specified " + Mnemonic +
" op requires a register");
4003 else if (!ExpectRegister && HasRegister)
4004 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4016 if (
Name.contains(
'.'))
4017 return TokError(
"invalid operand");
4021 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
4027 if (Mnemonic ==
"tlbip") {
4028 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4029 if (HasnXSQualifier) {
4030 Op =
Op.drop_back(3);
4034 return TokError(
"invalid operand for TLBIP instruction");
4036 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4043 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
4044 std::string Str(
"TLBIP " +
Name +
" requires: ");
4046 return TokError(Str);
4057 return TokError(
"expected register identifier");
4062 return TokError(
"specified " + Mnemonic +
4063 " op requires a pair of registers");
4076 return TokError(
"'csync' operand expected");
4080 SMLoc ExprLoc = getLoc();
4082 if (getParser().parseExpression(ImmVal))
4086 return Error(ExprLoc,
"immediate value expected for barrier operand");
4088 if (Mnemonic ==
"dsb" &&
Value > 15) {
4095 if (Value < 0 || Value > 15)
4096 return Error(ExprLoc,
"barrier operand out of range");
4097 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4098 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4099 ExprLoc, getContext(),
4105 return TokError(
"invalid operand for instruction");
4108 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4109 auto DB = AArch64DB::lookupDBByName(Operand);
4111 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4112 return TokError(
"'sy' or #imm operand expected");
4114 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4115 return TokError(
"'csync' operand expected");
4117 if (Mnemonic ==
"dsb") {
4122 return TokError(
"invalid barrier option name");
4125 Operands.push_back(AArch64Operand::CreateBarrier(
4126 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4127 getContext(),
false ));
4137 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4138 if (Mnemonic !=
"dsb")
4144 SMLoc ExprLoc = getLoc();
4145 if (getParser().parseExpression(ImmVal))
4149 return Error(ExprLoc,
"immediate value expected for barrier operand");
4154 return Error(ExprLoc,
"barrier operand out of range");
4155 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4156 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4157 ExprLoc, getContext(),
4163 return TokError(
"invalid operand for instruction");
4166 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4169 return TokError(
"invalid barrier option name");
4172 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4173 getContext(),
true ));
4185 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4189 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4190 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4191 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4192 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4196 unsigned PStateImm = -1;
4197 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4198 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4199 PStateImm = PState15->Encoding;
4201 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4202 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4203 PStateImm = PState1->Encoding;
4207 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4208 PStateImm, getContext()));
4219 return TokError(
"invalid operand for instruction");
4223 return TokError(
"invalid operand for instruction");
4225 Operands.push_back(AArch64Operand::CreatePHintInst(
4226 PH->Encoding, Tok.
getString(), S, getContext()));
4240 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4248 unsigned ElementWidth = KindRes->second;
4250 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4251 S, getLoc(), getContext()));
4256 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4258 return tryParseVectorIndex(
Operands).isFailure();
4262 SMLoc SIdx = getLoc();
4265 if (getParser().parseExpression(ImmVal))
4269 return TokError(
"immediate value expected for vector index");
4276 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4289 RegKind MatchKind) {
4298 size_t Start = 0, Next =
Name.find(
'.');
4300 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4306 return TokError(
"invalid vector kind qualifier");
4317ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4320 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4322 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4327template <RegKind RK>
4331 const SMLoc S = getLoc();
4334 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4342 unsigned ElementWidth = KindRes->second;
4343 Operands.push_back(AArch64Operand::CreateVectorReg(
4344 RegNum, RK, ElementWidth, S,
4345 getLoc(), getContext()));
4348 if (RK == RegKind::SVEPredicateAsCounter) {
4355 if (parseOperand(
Operands,
false,
false))
4366 return Error(S,
"not expecting size suffix");
4369 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4374 auto Pred = getTok().getString().lower();
4375 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4376 return Error(getLoc(),
"expecting 'z' predication");
4378 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4379 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4382 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4383 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4392 if (!tryParseNeonVectorRegister(
Operands))
4395 if (tryParseZTOperand(
Operands).isSuccess())
4399 if (tryParseGPROperand<false>(
Operands).isSuccess())
4405bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4406 bool HasELFModifier =
false;
4410 HasELFModifier =
true;
4413 return TokError(
"expect relocation specifier in operand after ':'");
4415 std::string LowerCase = getTok().getIdentifier().lower();
4471 return TokError(
"expect relocation specifier in operand after ':'");
4475 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4479 if (getParser().parseExpression(ImmVal))
4492 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4495 size_t DotPosition =
Name.find(
'.');
4504 const std::optional<std::pair<int, int>> &KindRes =
4508 "Expected the register to be followed by element width suffix");
4509 ElementWidth = KindRes->second;
4516 auto LCurly = getTok();
4521 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4522 0, S, getLoc(), getContext()));
4527 if (getTok().getString().equals_insensitive(
"za")) {
4533 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4534 0xFF, S, getLoc(), getContext()));
4538 SMLoc TileLoc = getLoc();
4540 unsigned FirstReg, ElementWidth;
4541 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4542 if (!ParseRes.isSuccess()) {
4543 getLexer().UnLex(LCurly);
4549 unsigned PrevReg = FirstReg;
4552 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4555 SeenRegs.
insert(FirstReg);
4559 unsigned Reg, NextElementWidth;
4560 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4561 if (!ParseRes.isSuccess())
4565 if (ElementWidth != NextElementWidth)
4566 return Error(TileLoc,
"mismatched register size suffix");
4569 Warning(TileLoc,
"tile list not in ascending order");
4572 Warning(TileLoc,
"duplicate tile in list");
4575 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4584 unsigned RegMask = 0;
4585 for (
auto Reg : DRegs)
4589 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4594template <RegKind VectorKind>
4604 auto RegTok = getTok();
4605 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4606 if (ParseRes.isSuccess()) {
4613 RegTok.getString().equals_insensitive(
"zt0"))
4617 (ParseRes.isNoMatch() && NoMatchIsError &&
4618 !RegTok.getString().starts_with_insensitive(
"za")))
4619 return Error(Loc,
"vector register expected");
4624 int NumRegs = getNumRegsForRegKind(VectorKind);
4626 auto LCurly = getTok();
4631 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4635 if (ParseRes.isNoMatch())
4638 if (!ParseRes.isSuccess())
4641 int64_t PrevReg = FirstReg;
4646 SMLoc Loc = getLoc();
4650 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4651 if (!ParseRes.isSuccess())
4655 if (Kind != NextKind)
4656 return Error(Loc,
"mismatched register size suffix");
4659 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4661 if (Space == 0 || Space > 3)
4662 return Error(Loc,
"invalid number of vectors");
4667 bool HasCalculatedStride =
false;
4669 SMLoc Loc = getLoc();
4672 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4673 if (!ParseRes.isSuccess())
4677 if (Kind != NextKind)
4678 return Error(Loc,
"mismatched register size suffix");
4680 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4681 unsigned PrevRegVal =
4682 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4683 if (!HasCalculatedStride) {
4684 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4685 : (RegVal + NumRegs - PrevRegVal);
4686 HasCalculatedStride =
true;
4690 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4691 return Error(Loc,
"registers must have the same sequential stride");
4702 return Error(S,
"invalid number of vectors");
4704 unsigned NumElements = 0;
4705 unsigned ElementWidth = 0;
4706 if (!
Kind.empty()) {
4708 std::tie(NumElements, ElementWidth) = *VK;
4711 Operands.push_back(AArch64Operand::CreateVectorList(
4712 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4713 getLoc(), getContext()));
4720 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4721 if (!ParseRes.isSuccess())
4724 return tryParseVectorIndex(
Operands).isFailure();
4728 SMLoc StartLoc = getLoc();
4736 Operands.push_back(AArch64Operand::CreateReg(
4737 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4744 return Error(getLoc(),
"index must be absent or #0");
4747 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4748 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4749 return Error(getLoc(),
"index must be absent or #0");
4751 Operands.push_back(AArch64Operand::CreateReg(
4752 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4757 SMLoc StartLoc = getLoc();
4761 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4766 Operands.push_back(AArch64Operand::CreateReg(
4767 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4773 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4775 if (getParser().parseExpression(ImmVal))
4779 return TokError(
"immediate value expected for vector index");
4780 Operands.push_back(AArch64Operand::CreateImm(
4782 getLoc(), getContext()));
4784 if (parseOptionalMulOperand(
Operands))
4789 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4794template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4796 SMLoc StartLoc = getLoc();
4805 Operands.push_back(AArch64Operand::CreateReg(
4806 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4815 Res = tryParseOptionalShiftExtend(ExtOpnd);
4819 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4820 Operands.push_back(AArch64Operand::CreateReg(
4821 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4822 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4823 Ext->hasShiftExtendAmount()));
4837 if (!getTok().getString().equals_insensitive(
"mul") ||
4838 !(NextIsVL || NextIsHash))
4842 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4847 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4859 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4860 Operands.push_back(AArch64Operand::CreateImm(
4867 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4873 auto Tok = Parser.
getTok();
4878 .
Case(
"vgx2",
"vgx2")
4879 .
Case(
"vgx4",
"vgx4")
4891 auto Tok = getTok();
4901 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4910 bool invertCondCode) {
4914 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4928 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4933 getLexer().UnLex(SavedTok);
4937 switch (getLexer().getKind()) {
4941 if (parseSymbolicImmVal(Expr))
4942 return Error(S,
"invalid operand");
4945 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4946 return parseOptionalShiftExtend(getTok());
4950 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4955 return parseOperand(
Operands,
false,
false);
4958 if (!parseNeonVectorList(
Operands))
4962 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4967 return parseOperand(
Operands,
false,
false);
4972 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4974 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4979 return parseCondCode(
Operands, invertCondCode);
4993 Res = tryParseOptionalShiftExtend(
Operands);
4996 getLexer().UnLex(SavedTok);
5003 if (!parseOptionalMulOperand(
Operands))
5008 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5010 return parseKeywordOperand(
Operands);
5016 if (getParser().parseExpression(IdVal))
5019 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
5022 return parseOptionalShiftExtend(getTok());
5033 bool isNegative =
false;
5049 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5050 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5051 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5052 return TokError(
"unexpected floating point literal");
5053 else if (IntVal != 0 || isNegative)
5054 return TokError(
"expected floating-point constant #0.0");
5057 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
5058 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
5063 if (parseSymbolicImmVal(ImmVal))
5067 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
5070 return parseOptionalShiftExtend(Tok);
5073 SMLoc Loc = getLoc();
5074 if (Mnemonic !=
"ldr")
5075 return TokError(
"unexpected token in operand");
5077 const MCExpr *SubExprVal;
5078 if (getParser().parseExpression(SubExprVal))
5082 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5083 return Error(Loc,
"Only valid when first operand is register");
5086 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5092 if (isa<MCConstantExpr>(SubExprVal)) {
5093 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
5094 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5099 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5100 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5101 Operands.push_back(AArch64Operand::CreateImm(
5105 ShiftAmt,
true, S, E, Ctx));
5111 return Error(Loc,
"Immediate too large for register");
5115 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5116 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
5122bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5123 const MCExpr *Expr =
nullptr;
5125 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5128 if (check(!
Value, L,
"expected constant expression"))
5130 Out =
Value->getValue();
5134bool AArch64AsmParser::parseComma() {
5142bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5146 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5151 unsigned RangeEnd =
Last;
5152 if (
Base == AArch64::X0) {
5153 if (
Last == AArch64::FP) {
5154 RangeEnd = AArch64::X28;
5155 if (Reg == AArch64::FP) {
5160 if (
Last == AArch64::LR) {
5161 RangeEnd = AArch64::X28;
5162 if (Reg == AArch64::FP) {
5165 }
else if (Reg == AArch64::LR) {
5172 if (check(Reg < First || Reg > RangeEnd, Start,
5173 Twine(
"expected register in range ") +
5183 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5184 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5186 if (AOp1.isVectorList() && AOp2.isVectorList())
5187 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5188 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5189 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5191 if (!AOp1.isReg() || !AOp2.isReg())
5194 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5195 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5198 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5199 "Testing equality of non-scalar registers not supported");
5202 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5204 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5206 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5208 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5219 .
Case(
"beq",
"b.eq")
5220 .
Case(
"bne",
"b.ne")
5221 .
Case(
"bhs",
"b.hs")
5222 .
Case(
"bcs",
"b.cs")
5223 .
Case(
"blo",
"b.lo")
5224 .
Case(
"bcc",
"b.cc")
5225 .
Case(
"bmi",
"b.mi")
5226 .
Case(
"bpl",
"b.pl")
5227 .
Case(
"bvs",
"b.vs")
5228 .
Case(
"bvc",
"b.vc")
5229 .
Case(
"bhi",
"b.hi")
5230 .
Case(
"bls",
"b.ls")
5231 .
Case(
"bge",
"b.ge")
5232 .
Case(
"blt",
"b.lt")
5233 .
Case(
"bgt",
"b.gt")
5234 .
Case(
"ble",
"b.le")
5235 .
Case(
"bal",
"b.al")
5236 .
Case(
"bnv",
"b.nv")
5241 getTok().getIdentifier().lower() ==
".req") {
5242 parseDirectiveReq(
Name, NameLoc);
5249 size_t Start = 0, Next =
Name.find(
'.');
5254 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5255 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5256 return parseSysAlias(Head, NameLoc,
Operands);
5259 if (Head ==
"tlbip")
5260 return parseSyspAlias(Head, NameLoc,
Operands);
5262 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5268 Next =
Name.find(
'.', Start + 1);
5269 Head =
Name.slice(Start + 1, Next);
5273 std::string Suggestion;
5276 std::string Msg =
"invalid condition code";
5277 if (!Suggestion.empty())
5278 Msg +=
", did you mean " + Suggestion +
"?";
5279 return Error(SuffixLoc, Msg);
5281 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5284 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5290 Next =
Name.find(
'.', Start + 1);
5291 Head =
Name.slice(Start, Next);
5294 Operands.push_back(AArch64Operand::CreateToken(
5295 Head, SuffixLoc, getContext(),
true));
5300 bool condCodeFourthOperand =
5301 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5302 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5303 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5311 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5312 bool condCodeThirdOperand =
5313 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5321 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5322 (
N == 3 && condCodeThirdOperand) ||
5323 (
N == 2 && condCodeSecondOperand),
5324 condCodeSecondOperand || condCodeThirdOperand)) {
5344 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5347 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5350 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5363 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5364 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5365 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5366 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5367 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5368 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5369 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5375bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5384 PrefixInfo
Prefix = NextPrefix;
5385 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5397 return Error(IDLoc,
"instruction is unpredictable when following a"
5398 " movprfx, suggest replacing movprfx with mov");
5402 return Error(Loc[0],
"instruction is unpredictable when following a"
5403 " movprfx writing to a different destination");
5410 return Error(Loc[0],
"instruction is unpredictable when following a"
5411 " movprfx and destination also used as non-destructive"
5415 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5416 if (
Prefix.isPredicated()) {
5430 return Error(IDLoc,
"instruction is unpredictable when following a"
5431 " predicated movprfx, suggest using unpredicated movprfx");
5435 return Error(IDLoc,
"instruction is unpredictable when following a"
5436 " predicated movprfx using a different general predicate");
5440 return Error(IDLoc,
"instruction is unpredictable when following a"
5441 " predicated movprfx with a different element size");
5447 if (IsWindowsArm64EC) {
5453 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5454 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5455 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5456 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5457 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5458 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5459 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5460 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5461 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5462 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5464 " is disallowed on ARM64EC.");
5474 case AArch64::LDPSWpre:
5475 case AArch64::LDPWpost:
5476 case AArch64::LDPWpre:
5477 case AArch64::LDPXpost:
5478 case AArch64::LDPXpre: {
5483 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5484 "is also a destination");
5486 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5487 "is also a destination");
5490 case AArch64::LDR_ZA:
5491 case AArch64::STR_ZA: {
5494 return Error(Loc[1],
5495 "unpredictable instruction, immediate and offset mismatch.");
5498 case AArch64::LDPDi:
5499 case AArch64::LDPQi:
5500 case AArch64::LDPSi:
5501 case AArch64::LDPSWi:
5502 case AArch64::LDPWi:
5503 case AArch64::LDPXi: {
5507 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5510 case AArch64::LDPDpost:
5511 case AArch64::LDPDpre:
5512 case AArch64::LDPQpost:
5513 case AArch64::LDPQpre:
5514 case AArch64::LDPSpost:
5515 case AArch64::LDPSpre:
5516 case AArch64::LDPSWpost: {
5520 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5523 case AArch64::STPDpost:
5524 case AArch64::STPDpre:
5525 case AArch64::STPQpost:
5526 case AArch64::STPQpre:
5527 case AArch64::STPSpost:
5528 case AArch64::STPSpre:
5529 case AArch64::STPWpost:
5530 case AArch64::STPWpre:
5531 case AArch64::STPXpost:
5532 case AArch64::STPXpre: {
5537 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5538 "is also a source");
5540 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5541 "is also a source");
5544 case AArch64::LDRBBpre:
5545 case AArch64::LDRBpre:
5546 case AArch64::LDRHHpre:
5547 case AArch64::LDRHpre:
5548 case AArch64::LDRSBWpre:
5549 case AArch64::LDRSBXpre:
5550 case AArch64::LDRSHWpre:
5551 case AArch64::LDRSHXpre:
5552 case AArch64::LDRSWpre:
5553 case AArch64::LDRWpre:
5554 case AArch64::LDRXpre:
5555 case AArch64::LDRBBpost:
5556 case AArch64::LDRBpost:
5557 case AArch64::LDRHHpost:
5558 case AArch64::LDRHpost:
5559 case AArch64::LDRSBWpost:
5560 case AArch64::LDRSBXpost:
5561 case AArch64::LDRSHWpost:
5562 case AArch64::LDRSHXpost:
5563 case AArch64::LDRSWpost:
5564 case AArch64::LDRWpost:
5565 case AArch64::LDRXpost: {
5569 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5570 "is also a source");
5573 case AArch64::STRBBpost:
5574 case AArch64::STRBpost:
5575 case AArch64::STRHHpost:
5576 case AArch64::STRHpost:
5577 case AArch64::STRWpost:
5578 case AArch64::STRXpost:
5579 case AArch64::STRBBpre:
5580 case AArch64::STRBpre:
5581 case AArch64::STRHHpre:
5582 case AArch64::STRHpre:
5583 case AArch64::STRWpre:
5584 case AArch64::STRXpre: {
5588 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5589 "is also a source");
5592 case AArch64::STXRB:
5593 case AArch64::STXRH:
5594 case AArch64::STXRW:
5595 case AArch64::STXRX:
5596 case AArch64::STLXRB:
5597 case AArch64::STLXRH:
5598 case AArch64::STLXRW:
5599 case AArch64::STLXRX: {
5605 return Error(Loc[0],
5606 "unpredictable STXR instruction, status is also a source");
5609 case AArch64::STXPW:
5610 case AArch64::STXPX:
5611 case AArch64::STLXPW:
5612 case AArch64::STLXPX: {
5619 return Error(Loc[0],
5620 "unpredictable STXP instruction, status is also a source");
5623 case AArch64::LDRABwriteback:
5624 case AArch64::LDRAAwriteback: {
5628 return Error(Loc[0],
5629 "unpredictable LDRA instruction, writeback base"
5630 " is also a destination");
5637 case AArch64::CPYFP:
5638 case AArch64::CPYFPWN:
5639 case AArch64::CPYFPRN:
5640 case AArch64::CPYFPN:
5641 case AArch64::CPYFPWT:
5642 case AArch64::CPYFPWTWN:
5643 case AArch64::CPYFPWTRN:
5644 case AArch64::CPYFPWTN:
5645 case AArch64::CPYFPRT:
5646 case AArch64::CPYFPRTWN:
5647 case AArch64::CPYFPRTRN:
5648 case AArch64::CPYFPRTN:
5649 case AArch64::CPYFPT:
5650 case AArch64::CPYFPTWN:
5651 case AArch64::CPYFPTRN:
5652 case AArch64::CPYFPTN:
5653 case AArch64::CPYFM:
5654 case AArch64::CPYFMWN:
5655 case AArch64::CPYFMRN:
5656 case AArch64::CPYFMN:
5657 case AArch64::CPYFMWT:
5658 case AArch64::CPYFMWTWN:
5659 case AArch64::CPYFMWTRN:
5660 case AArch64::CPYFMWTN:
5661 case AArch64::CPYFMRT:
5662 case AArch64::CPYFMRTWN:
5663 case AArch64::CPYFMRTRN:
5664 case AArch64::CPYFMRTN:
5665 case AArch64::CPYFMT:
5666 case AArch64::CPYFMTWN:
5667 case AArch64::CPYFMTRN:
5668 case AArch64::CPYFMTN:
5669 case AArch64::CPYFE:
5670 case AArch64::CPYFEWN:
5671 case AArch64::CPYFERN:
5672 case AArch64::CPYFEN:
5673 case AArch64::CPYFEWT:
5674 case AArch64::CPYFEWTWN:
5675 case AArch64::CPYFEWTRN:
5676 case AArch64::CPYFEWTN:
5677 case AArch64::CPYFERT:
5678 case AArch64::CPYFERTWN:
5679 case AArch64::CPYFERTRN:
5680 case AArch64::CPYFERTN:
5681 case AArch64::CPYFET:
5682 case AArch64::CPYFETWN:
5683 case AArch64::CPYFETRN:
5684 case AArch64::CPYFETN:
5686 case AArch64::CPYPWN:
5687 case AArch64::CPYPRN:
5688 case AArch64::CPYPN:
5689 case AArch64::CPYPWT:
5690 case AArch64::CPYPWTWN:
5691 case AArch64::CPYPWTRN:
5692 case AArch64::CPYPWTN:
5693 case AArch64::CPYPRT:
5694 case AArch64::CPYPRTWN:
5695 case AArch64::CPYPRTRN:
5696 case AArch64::CPYPRTN:
5697 case AArch64::CPYPT:
5698 case AArch64::CPYPTWN:
5699 case AArch64::CPYPTRN:
5700 case AArch64::CPYPTN:
5702 case AArch64::CPYMWN:
5703 case AArch64::CPYMRN:
5704 case AArch64::CPYMN:
5705 case AArch64::CPYMWT:
5706 case AArch64::CPYMWTWN:
5707 case AArch64::CPYMWTRN:
5708 case AArch64::CPYMWTN:
5709 case AArch64::CPYMRT:
5710 case AArch64::CPYMRTWN:
5711 case AArch64::CPYMRTRN:
5712 case AArch64::CPYMRTN:
5713 case AArch64::CPYMT:
5714 case AArch64::CPYMTWN:
5715 case AArch64::CPYMTRN:
5716 case AArch64::CPYMTN:
5718 case AArch64::CPYEWN:
5719 case AArch64::CPYERN:
5720 case AArch64::CPYEN:
5721 case AArch64::CPYEWT:
5722 case AArch64::CPYEWTWN:
5723 case AArch64::CPYEWTRN:
5724 case AArch64::CPYEWTN:
5725 case AArch64::CPYERT:
5726 case AArch64::CPYERTWN:
5727 case AArch64::CPYERTRN:
5728 case AArch64::CPYERTN:
5729 case AArch64::CPYET:
5730 case AArch64::CPYETWN:
5731 case AArch64::CPYETRN:
5732 case AArch64::CPYETN: {
5740 return Error(Loc[0],
5741 "invalid CPY instruction, Xd_wb and Xd do not match");
5743 return Error(Loc[0],
5744 "invalid CPY instruction, Xs_wb and Xs do not match");
5746 return Error(Loc[0],
5747 "invalid CPY instruction, Xn_wb and Xn do not match");
5749 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5750 " registers are the same");
5752 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5753 " registers are the same");
5755 return Error(Loc[0],
"invalid CPY instruction, source and size"
5756 " registers are the same");
5760 case AArch64::SETPT:
5761 case AArch64::SETPN:
5762 case AArch64::SETPTN:
5764 case AArch64::SETMT:
5765 case AArch64::SETMN:
5766 case AArch64::SETMTN:
5768 case AArch64::SETET:
5769 case AArch64::SETEN:
5770 case AArch64::SETETN:
5771 case AArch64::SETGP:
5772 case AArch64::SETGPT:
5773 case AArch64::SETGPN:
5774 case AArch64::SETGPTN:
5775 case AArch64::SETGM:
5776 case AArch64::SETGMT:
5777 case AArch64::SETGMN:
5778 case AArch64::SETGMTN:
5779 case AArch64::MOPSSETGE:
5780 case AArch64::MOPSSETGET:
5781 case AArch64::MOPSSETGEN:
5782 case AArch64::MOPSSETGETN: {
5789 return Error(Loc[0],
5790 "invalid SET instruction, Xd_wb and Xd do not match");
5792 return Error(Loc[0],
5793 "invalid SET instruction, Xn_wb and Xn do not match");
5795 return Error(Loc[0],
"invalid SET instruction, destination and size"
5796 " registers are the same");
5798 return Error(Loc[0],
"invalid SET instruction, destination and source"
5799 " registers are the same");
5801 return Error(Loc[0],
"invalid SET instruction, source and size"
5802 " registers are the same");
5811 case AArch64::ADDSWri:
5812 case AArch64::ADDSXri:
5813 case AArch64::ADDWri:
5814 case AArch64::ADDXri:
5815 case AArch64::SUBSWri:
5816 case AArch64::SUBSXri:
5817 case AArch64::SUBWri:
5818 case AArch64::SUBXri: {
5826 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5855 return Error(Loc.
back(),
"invalid immediate expression");
5868 unsigned VariantID = 0);
5870bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5874 case Match_InvalidTiedOperand: {
5876 if (
Op.isVectorList())
5877 return Error(Loc,
"operand must match destination register list");
5879 assert(
Op.isReg() &&
"Unexpected operand type");
5880 switch (
Op.getRegEqualityTy()) {
5881 case RegConstraintEqualityTy::EqualsSubReg:
5882 return Error(Loc,
"operand must be 64-bit form of destination register");
5883 case RegConstraintEqualityTy::EqualsSuperReg:
5884 return Error(Loc,
"operand must be 32-bit form of destination register");
5885 case RegConstraintEqualityTy::EqualsReg:
5886 return Error(Loc,
"operand must match destination register");
5890 case Match_MissingFeature:
5892 "instruction requires a CPU feature not currently enabled");
5893 case Match_InvalidOperand:
5894 return Error(Loc,
"invalid operand for instruction");
5895 case Match_InvalidSuffix:
5896 return Error(Loc,
"invalid type suffix for instruction");
5897 case Match_InvalidCondCode:
5898 return Error(Loc,
"expected AArch64 condition code");
5899 case Match_AddSubRegExtendSmall:
5901 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5902 case Match_AddSubRegExtendLarge:
5904 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5905 case Match_AddSubSecondSource:
5907 "expected compatible register, symbol or integer in range [0, 4095]");
5908 case Match_LogicalSecondSource:
5909 return Error(Loc,
"expected compatible register or logical immediate");
5910 case Match_InvalidMovImm32Shift:
5911 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5912 case Match_InvalidMovImm64Shift:
5913 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5914 case Match_AddSubRegShift32:
5916 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5917 case Match_AddSubRegShift64:
5919 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5920 case Match_InvalidFPImm:
5922 "expected compatible register or floating-point constant");
5923 case Match_InvalidMemoryIndexedSImm6:
5924 return Error(Loc,
"index must be an integer in range [-32, 31].");
5925 case Match_InvalidMemoryIndexedSImm5:
5926 return Error(Loc,
"index must be an integer in range [-16, 15].");
5927 case Match_InvalidMemoryIndexed1SImm4:
5928 return Error(Loc,
"index must be an integer in range [-8, 7].");
5929 case Match_InvalidMemoryIndexed2SImm4:
5930 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5931 case Match_InvalidMemoryIndexed3SImm4:
5932 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5933 case Match_InvalidMemoryIndexed4SImm4:
5934 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5935 case Match_InvalidMemoryIndexed16SImm4:
5936 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5937 case Match_InvalidMemoryIndexed32SImm4:
5938 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5939 case Match_InvalidMemoryIndexed1SImm6:
5940 return Error(Loc,
"index must be an integer in range [-32, 31].");
5941 case Match_InvalidMemoryIndexedSImm8:
5942 return Error(Loc,
"index must be an integer in range [-128, 127].");
5943 case Match_InvalidMemoryIndexedSImm9:
5944 return Error(Loc,
"index must be an integer in range [-256, 255].");
5945 case Match_InvalidMemoryIndexed16SImm9:
5946 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5947 case Match_InvalidMemoryIndexed8SImm10:
5948 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5949 case Match_InvalidMemoryIndexed4SImm7:
5950 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5951 case Match_InvalidMemoryIndexed8SImm7:
5952 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5953 case Match_InvalidMemoryIndexed16SImm7:
5954 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5955 case Match_InvalidMemoryIndexed8UImm5:
5956 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5957 case Match_InvalidMemoryIndexed8UImm3:
5958 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5959 case Match_InvalidMemoryIndexed4UImm5:
5960 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5961 case Match_InvalidMemoryIndexed2UImm5:
5962 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5963 case Match_InvalidMemoryIndexed8UImm6:
5964 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5965 case Match_InvalidMemoryIndexed16UImm6:
5966 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5967 case Match_InvalidMemoryIndexed4UImm6:
5968 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5969 case Match_InvalidMemoryIndexed2UImm6:
5970 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5971 case Match_InvalidMemoryIndexed1UImm6:
5972 return Error(Loc,
"index must be in range [0, 63].");
5973 case Match_InvalidMemoryWExtend8:
5975 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5976 case Match_InvalidMemoryWExtend16:
5978 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5979 case Match_InvalidMemoryWExtend32:
5981 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5982 case Match_InvalidMemoryWExtend64:
5984 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5985 case Match_InvalidMemoryWExtend128:
5987 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5988 case Match_InvalidMemoryXExtend8:
5990 "expected 'lsl' or 'sxtx' with optional shift of #0");
5991 case Match_InvalidMemoryXExtend16:
5993 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5994 case Match_InvalidMemoryXExtend32:
5996 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5997 case Match_InvalidMemoryXExtend64:
5999 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6000 case Match_InvalidMemoryXExtend128:
6002 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6003 case Match_InvalidMemoryIndexed1:
6004 return Error(Loc,
"index must be an integer in range [0, 4095].");
6005 case Match_InvalidMemoryIndexed2:
6006 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6007 case Match_InvalidMemoryIndexed4:
6008 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6009 case Match_InvalidMemoryIndexed8:
6010 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6011 case Match_InvalidMemoryIndexed16:
6012 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6013 case Match_InvalidImm0_0:
6014 return Error(Loc,
"immediate must be 0.");
6015 case Match_InvalidImm0_1:
6016 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6017 case Match_InvalidImm0_3:
6018 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6019 case Match_InvalidImm0_7:
6020 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6021 case Match_InvalidImm0_15:
6022 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6023 case Match_InvalidImm0_31:
6024 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6025 case Match_InvalidImm0_63:
6026 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6027 case Match_InvalidImm0_127:
6028 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6029 case Match_InvalidImm0_255:
6030 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6031 case Match_InvalidImm0_65535:
6032 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6033 case Match_InvalidImm1_8:
6034 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6035 case Match_InvalidImm1_16:
6036 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6037 case Match_InvalidImm1_32:
6038 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6039 case Match_InvalidImm1_64:
6040 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6041 case Match_InvalidImmM1_62:
6042 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6043 case Match_InvalidMemoryIndexedRange2UImm0:
6044 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6045 case Match_InvalidMemoryIndexedRange2UImm1:
6046 return Error(Loc,
"vector select offset must be an immediate range of the "
6047 "form <immf>:<imml>, where the first "
6048 "immediate is a multiple of 2 in the range [0, 2], and "
6049 "the second immediate is immf + 1.");
6050 case Match_InvalidMemoryIndexedRange2UImm2:
6051 case Match_InvalidMemoryIndexedRange2UImm3:
6054 "vector select offset must be an immediate range of the form "
6056 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6058 "depending on the instruction, and the second immediate is immf + 1.");
6059 case Match_InvalidMemoryIndexedRange4UImm0:
6060 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6061 case Match_InvalidMemoryIndexedRange4UImm1:
6062 case Match_InvalidMemoryIndexedRange4UImm2:
6065 "vector select offset must be an immediate range of the form "
6067 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6069 "depending on the instruction, and the second immediate is immf + 3.");
6070 case Match_InvalidSVEAddSubImm8:
6071 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6072 " with a shift amount of 0");
6073 case Match_InvalidSVEAddSubImm16:
6074 case Match_InvalidSVEAddSubImm32:
6075 case Match_InvalidSVEAddSubImm64:
6076 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6077 "multiple of 256 in range [256, 65280]");
6078 case Match_InvalidSVECpyImm8:
6079 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6080 " with a shift amount of 0");
6081 case Match_InvalidSVECpyImm16:
6082 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6083 "multiple of 256 in range [-32768, 65280]");
6084 case Match_InvalidSVECpyImm32:
6085 case Match_InvalidSVECpyImm64:
6086 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6087 "multiple of 256 in range [-32768, 32512]");
6088 case Match_InvalidIndexRange0_0:
6089 return Error(Loc,
"expected lane specifier '[0]'");
6090 case Match_InvalidIndexRange1_1:
6091 return Error(Loc,
"expected lane specifier '[1]'");
6092 case Match_InvalidIndexRange0_15:
6093 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6094 case Match_InvalidIndexRange0_7:
6095 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6096 case Match_InvalidIndexRange0_3:
6097 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6098 case Match_InvalidIndexRange0_1:
6099 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6100 case Match_InvalidSVEIndexRange0_63:
6101 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6102 case Match_InvalidSVEIndexRange0_31:
6103 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6104 case Match_InvalidSVEIndexRange0_15:
6105 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6106 case Match_InvalidSVEIndexRange0_7:
6107 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6108 case Match_InvalidSVEIndexRange0_3:
6109 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6110 case Match_InvalidLabel:
6111 return Error(Loc,
"expected label or encodable integer pc offset");
6113 return Error(Loc,
"expected readable system register");
6115 case Match_InvalidSVCR:
6116 return Error(Loc,
"expected writable system register or pstate");
6117 case Match_InvalidComplexRotationEven:
6118 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6119 case Match_InvalidComplexRotationOdd:
6120 return Error(Loc,
"complex rotation must be 90 or 270.");
6121 case Match_MnemonicFail: {
6123 ((AArch64Operand &)*
Operands[0]).getToken(),
6124 ComputeAvailableFeatures(STI->getFeatureBits()));
6125 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6127 case Match_InvalidGPR64shifted8:
6128 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6129 case Match_InvalidGPR64shifted16:
6130 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6131 case Match_InvalidGPR64shifted32:
6132 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6133 case Match_InvalidGPR64shifted64:
6134 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6135 case Match_InvalidGPR64shifted128:
6137 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6138 case Match_InvalidGPR64NoXZRshifted8:
6139 return Error(Loc,
"register must be x0..x30 without shift");
6140 case Match_InvalidGPR64NoXZRshifted16:
6141 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6142 case Match_InvalidGPR64NoXZRshifted32:
6143 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6144 case Match_InvalidGPR64NoXZRshifted64:
6145 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6146 case Match_InvalidGPR64NoXZRshifted128:
6147 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6148 case Match_InvalidZPR32UXTW8:
6149 case Match_InvalidZPR32SXTW8:
6150 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6151 case Match_InvalidZPR32UXTW16:
6152 case Match_InvalidZPR32SXTW16:
6153 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6154 case Match_InvalidZPR32UXTW32:
6155 case Match_InvalidZPR32SXTW32:
6156 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6157 case Match_InvalidZPR32UXTW64:
6158 case Match_InvalidZPR32SXTW64:
6159 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6160 case Match_InvalidZPR64UXTW8:
6161 case Match_InvalidZPR64SXTW8:
6162 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6163 case Match_InvalidZPR64UXTW16:
6164 case Match_InvalidZPR64SXTW16:
6165 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6166 case Match_InvalidZPR64UXTW32:
6167 case Match_InvalidZPR64SXTW32:
6168 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6169 case Match_InvalidZPR64UXTW64:
6170 case Match_InvalidZPR64SXTW64:
6171 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6172 case Match_InvalidZPR32LSL8:
6173 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6174 case Match_InvalidZPR32LSL16:
6175 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6176 case Match_InvalidZPR32LSL32:
6177 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6178 case Match_InvalidZPR32LSL64:
6179 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6180 case Match_InvalidZPR64LSL8:
6181 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6182 case Match_InvalidZPR64LSL16:
6183 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6184 case Match_InvalidZPR64LSL32:
6185 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6186 case Match_InvalidZPR64LSL64:
6187 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6188 case Match_InvalidZPR0:
6189 return Error(Loc,
"expected register without element width suffix");
6190 case Match_InvalidZPR8:
6191 case Match_InvalidZPR16:
6192 case Match_InvalidZPR32:
6193 case Match_InvalidZPR64:
6194 case Match_InvalidZPR128:
6195 return Error(Loc,
"invalid element width");
6196 case Match_InvalidZPR_3b8:
6197 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6198 case Match_InvalidZPR_3b16:
6199 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6200 case Match_InvalidZPR_3b32:
6201 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6202 case Match_InvalidZPR_4b8:
6204 "Invalid restricted vector register, expected z0.b..z15.b");
6205 case Match_InvalidZPR_4b16:
6206 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6207 case Match_InvalidZPR_4b32:
6208 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6209 case Match_InvalidZPR_4b64:
6210 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6211 case Match_InvalidZPRMul2_Lo8:
6212 return Error(Loc,
"Invalid restricted vector register, expected even "
6213 "register in z0.b..z14.b");
6214 case Match_InvalidZPRMul2_Hi8:
6215 return Error(Loc,
"Invalid restricted vector register, expected even "
6216 "register in z16.b..z30.b");
6217 case Match_InvalidZPRMul2_Lo16:
6218 return Error(Loc,
"Invalid restricted vector register, expected even "
6219 "register in z0.h..z14.h");
6220 case Match_InvalidZPRMul2_Hi16:
6221 return Error(Loc,
"Invalid restricted vector register, expected even "
6222 "register in z16.h..z30.h");
6223 case Match_InvalidZPRMul2_Lo32:
6224 return Error(Loc,
"Invalid restricted vector register, expected even "
6225 "register in z0.s..z14.s");
6226 case Match_InvalidZPRMul2_Hi32:
6227 return Error(Loc,
"Invalid restricted vector register, expected even "
6228 "register in z16.s..z30.s");
6229 case Match_InvalidZPRMul2_Lo64:
6230 return Error(Loc,
"Invalid restricted vector register, expected even "
6231 "register in z0.d..z14.d");
6232 case Match_InvalidZPRMul2_Hi64:
6233 return Error(Loc,
"Invalid restricted vector register, expected even "
6234 "register in z16.d..z30.d");
6235 case Match_InvalidZPR_K0:
6236 return Error(Loc,
"invalid restricted vector register, expected register "
6237 "in z20..z23 or z28..z31");
6238 case Match_InvalidSVEPattern:
6239 return Error(Loc,
"invalid predicate pattern");
6240 case Match_InvalidSVEPPRorPNRAnyReg:
6241 case Match_InvalidSVEPPRorPNRBReg:
6242 case Match_InvalidSVEPredicateAnyReg:
6243 case Match_InvalidSVEPredicateBReg:
6244 case Match_InvalidSVEPredicateHReg:
6245 case Match_InvalidSVEPredicateSReg:
6246 case Match_InvalidSVEPredicateDReg:
6247 return Error(Loc,
"invalid predicate register.");
6248 case Match_InvalidSVEPredicate3bAnyReg:
6249 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6250 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6251 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6252 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6253 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6254 return Error(Loc,
"Invalid predicate register, expected PN in range "
6255 "pn8..pn15 with element suffix.");
6256 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6257 return Error(Loc,
"invalid restricted predicate-as-counter register "
6258 "expected pn8..pn15");
6259 case Match_InvalidSVEPNPredicateBReg:
6260 case Match_InvalidSVEPNPredicateHReg:
6261 case Match_InvalidSVEPNPredicateSReg:
6262 case Match_InvalidSVEPNPredicateDReg:
6263 return Error(Loc,
"Invalid predicate register, expected PN in range "
6264 "pn0..pn15 with element suffix.");
6265 case Match_InvalidSVEVecLenSpecifier:
6266 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6267 case Match_InvalidSVEPredicateListMul2x8:
6268 case Match_InvalidSVEPredicateListMul2x16:
6269 case Match_InvalidSVEPredicateListMul2x32:
6270 case Match_InvalidSVEPredicateListMul2x64:
6271 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6272 "predicate registers, where the first vector is a multiple of 2 "
6273 "and with correct element type");
6274 case Match_InvalidSVEExactFPImmOperandHalfOne:
6275 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6276 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6277 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6278 case Match_InvalidSVEExactFPImmOperandZeroOne:
6279 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6280 case Match_InvalidMatrixTileVectorH8:
6281 case Match_InvalidMatrixTileVectorV8:
6282 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6283 case Match_InvalidMatrixTileVectorH16:
6284 case Match_InvalidMatrixTileVectorV16:
6286 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6287 case Match_InvalidMatrixTileVectorH32:
6288 case Match_InvalidMatrixTileVectorV32:
6290 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6291 case Match_InvalidMatrixTileVectorH64:
6292 case Match_InvalidMatrixTileVectorV64:
6294 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6295 case Match_InvalidMatrixTileVectorH128:
6296 case Match_InvalidMatrixTileVectorV128:
6298 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6299 case Match_InvalidMatrixTile16:
6300 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6301 case Match_InvalidMatrixTile32:
6302 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6303 case Match_InvalidMatrixTile64:
6304 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6305 case Match_InvalidMatrix:
6306 return Error(Loc,
"invalid matrix operand, expected za");
6307 case Match_InvalidMatrix8:
6308 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6309 case Match_InvalidMatrix16:
6310 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6311 case Match_InvalidMatrix32:
6312 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6313 case Match_InvalidMatrix64:
6314 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6315 case Match_InvalidMatrixIndexGPR32_12_15:
6316 return Error(Loc,
"operand must be a register in range [w12, w15]");
6317 case Match_InvalidMatrixIndexGPR32_8_11:
6318 return Error(Loc,
"operand must be a register in range [w8, w11]");
6319 case Match_InvalidSVEVectorList2x8Mul2:
6320 case Match_InvalidSVEVectorList2x16Mul2:
6321 case Match_InvalidSVEVectorList2x32Mul2:
6322 case Match_InvalidSVEVectorList2x64Mul2:
6323 case Match_InvalidSVEVectorList2x128Mul2:
6324 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6325 "SVE vectors, where the first vector is a multiple of 2 "
6326 "and with matching element types");
6327 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6328 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6329 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6330 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6331 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6332 "SVE vectors in the range z0-z14, where the first vector "
6333 "is a multiple of 2 "
6334 "and with matching element types");
6335 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6336 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6337 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6338 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6340 "Invalid vector list, expected list with 2 consecutive "
6341 "SVE vectors in the range z16-z30, where the first vector "
6342 "is a multiple of 2 "
6343 "and with matching element types");
6344 case Match_InvalidSVEVectorList4x8Mul4:
6345 case Match_InvalidSVEVectorList4x16Mul4:
6346 case Match_InvalidSVEVectorList4x32Mul4:
6347 case Match_InvalidSVEVectorList4x64Mul4:
6348 case Match_InvalidSVEVectorList4x128Mul4:
6349 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6350 "SVE vectors, where the first vector is a multiple of 4 "
6351 "and with matching element types");
6352 case Match_InvalidLookupTable:
6353 return Error(Loc,
"Invalid lookup table, expected zt0");
6354 case Match_InvalidSVEVectorListStrided2x8:
6355 case Match_InvalidSVEVectorListStrided2x16:
6356 case Match_InvalidSVEVectorListStrided2x32:
6357 case Match_InvalidSVEVectorListStrided2x64:
6360 "Invalid vector list, expected list with each SVE vector in the list "
6361 "8 registers apart, and the first register in the range [z0, z7] or "
6362 "[z16, z23] and with correct element type");
6363 case Match_InvalidSVEVectorListStrided4x8:
6364 case Match_InvalidSVEVectorListStrided4x16:
6365 case Match_InvalidSVEVectorListStrided4x32:
6366 case Match_InvalidSVEVectorListStrided4x64:
6369 "Invalid vector list, expected list with each SVE vector in the list "
6370 "4 registers apart, and the first register in the range [z0, z3] or "
6371 "[z16, z19] and with correct element type");
6372 case Match_AddSubLSLImm3ShiftLarge:
6374 "expected 'lsl' with optional integer in range [0, 7]");
6382bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6386 bool MatchingInlineAsm) {
6388 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6389 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6392 unsigned NumOperands =
Operands.size();
6394 if (NumOperands == 4 && Tok ==
"lsl") {
6395 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6396 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6397 if (Op2.isScalarReg() && Op3.isImm()) {
6398 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6403 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6405 NewOp3Val = (32 - Op3Val) & 0x1f;
6406 NewOp4Val = 31 - Op3Val;
6408 NewOp3Val = (64 - Op3Val) & 0x3f;
6409 NewOp4Val = 63 - Op3Val;
6416 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6417 Operands.push_back(AArch64Operand::CreateImm(
6418 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6419 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6420 Op3.getEndLoc(), getContext());
6423 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6425 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6426 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6427 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6429 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6430 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6431 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6433 if (LSBCE && WidthCE) {
6438 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6444 if (LSB >= RegWidth)
6445 return Error(LSBOp.getStartLoc(),
6446 "expected integer in range [0, 31]");
6447 if (Width < 1 || Width > RegWidth)
6448 return Error(WidthOp.getStartLoc(),
6449 "expected integer in range [1, 32]");
6453 ImmR = (32 - LSB) & 0x1f;
6455 ImmR = (64 - LSB) & 0x3f;
6459 if (ImmR != 0 && ImmS >= ImmR)
6460 return Error(WidthOp.getStartLoc(),
6461 "requested insert overflows register");
6466 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6467 Operands[2] = AArch64Operand::CreateReg(
6468 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6470 Operands[3] = AArch64Operand::CreateImm(
6471 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6473 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6474 WidthOp.getEndLoc(), getContext()));
6477 }
else if (NumOperands == 5) {
6480 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6481 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6482 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6483 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6485 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6486 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6487 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6489 if (Op3CE && Op4CE) {
6494 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6500 if (Op3Val >= RegWidth)
6501 return Error(Op3.getStartLoc(),
6502 "expected integer in range [0, 31]");
6503 if (Op4Val < 1 || Op4Val > RegWidth)
6504 return Error(Op4.getStartLoc(),
6505 "expected integer in range [1, 32]");
6509 NewOp3Val = (32 - Op3Val) & 0x1f;
6511 NewOp3Val = (64 - Op3Val) & 0x3f;
6515 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6516 return Error(Op4.getStartLoc(),
6517 "requested insert overflows register");
6523 Operands[3] = AArch64Operand::CreateImm(
6524 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6525 Operands[4] = AArch64Operand::CreateImm(
6526 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6528 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6530 else if (Tok ==
"sbfiz")
6531 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6533 else if (Tok ==
"ubfiz")
6534 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6543 }
else if (NumOperands == 5 &&
6544 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6545 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6546 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6547 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6549 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6550 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6551 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6553 if (Op3CE && Op4CE) {
6558 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6564 if (Op3Val >= RegWidth)
6565 return Error(Op3.getStartLoc(),
6566 "expected integer in range [0, 31]");
6567 if (Op4Val < 1 || Op4Val > RegWidth)
6568 return Error(Op4.getStartLoc(),
6569 "expected integer in range [1, 32]");
6571 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6573 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6574 return Error(Op4.getStartLoc(),
6575 "requested extract overflows register");
6579 Operands[4] = AArch64Operand::CreateImm(
6580 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6582 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6584 else if (Tok ==
"sbfx")
6585 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6587 else if (Tok ==
"ubfx")
6588 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6601 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6602 NumOperands == 4 && Tok ==
"movi") {
6603 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6604 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6605 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6606 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6607 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6608 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6609 if (Suffix.
lower() ==
".2d" &&
6610 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6611 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6612 " correctly on this CPU, converting to equivalent movi.16b");
6614 unsigned Idx = Op1.isToken() ? 1 : 2;
6616 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6624 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6627 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6628 if (
Op.isScalarReg()) {
6630 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6631 Op.getStartLoc(),
Op.getEndLoc(),
6636 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6637 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6638 if (
Op.isScalarReg() &&
6639 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6643 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6644 if (
Op.isScalarReg()) {
6646 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6648 Op.getEndLoc(), getContext());
6653 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6654 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6655 if (
Op.isScalarReg() &&
6656 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6660 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6661 if (
Op.isScalarReg()) {
6663 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6665 Op.getEndLoc(), getContext());
6674 unsigned MatchResult =
6676 MatchingInlineAsm, 1);
6680 if (MatchResult != Match_Success) {
6683 auto ShortFormNEONErrorInfo =
ErrorInfo;
6684 auto ShortFormNEONMatchResult = MatchResult;
6685 auto ShortFormNEONMissingFeatures = MissingFeatures;
6689 MatchingInlineAsm, 0);
6694 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6696 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6697 MatchResult = ShortFormNEONMatchResult;
6699 MissingFeatures = ShortFormNEONMissingFeatures;
6703 switch (MatchResult) {
6704 case Match_Success: {
6708 for (
unsigned i = 1; i < NumOperands; ++i)
6710 if (validateInstruction(Inst, IDLoc, OperandLocs))
6717 case Match_MissingFeature: {
6718 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6721 std::string Msg =
"instruction requires:";
6722 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6723 if (MissingFeatures[i]) {
6728 return Error(IDLoc, Msg);
6730 case Match_MnemonicFail:
6732 case Match_InvalidOperand: {
6733 SMLoc ErrorLoc = IDLoc;
6737 return Error(IDLoc,
"too few operands for instruction",
6738 SMRange(IDLoc, getTok().getLoc()));
6741 if (ErrorLoc ==
SMLoc())
6748 MatchResult = Match_InvalidSuffix;
6752 case Match_InvalidTiedOperand:
6753 case Match_InvalidMemoryIndexed1:
6754 case Match_InvalidMemoryIndexed2:
6755 case Match_InvalidMemoryIndexed4:
6756 case Match_InvalidMemoryIndexed8:
6757 case Match_InvalidMemoryIndexed16:
6758 case Match_InvalidCondCode:
6759 case Match_AddSubLSLImm3ShiftLarge:
6760 case Match_AddSubRegExtendSmall:
6761 case Match_AddSubRegExtendLarge:
6762 case Match_AddSubSecondSource:
6763 case Match_LogicalSecondSource:
6764 case Match_AddSubRegShift32:
6765 case Match_AddSubRegShift64:
6766 case Match_InvalidMovImm32Shift:
6767 case Match_InvalidMovImm64Shift:
6768 case Match_InvalidFPImm:
6769 case Match_InvalidMemoryWExtend8:
6770 case Match_InvalidMemoryWExtend16:
6771 case Match_InvalidMemoryWExtend32:
6772 case Match_InvalidMemoryWExtend64:
6773 case Match_InvalidMemoryWExtend128:
6774 case Match_InvalidMemoryXExtend8:
6775 case Match_InvalidMemoryXExtend16:
6776 case Match_InvalidMemoryXExtend32:
6777 case Match_InvalidMemoryXExtend64:
6778 case Match_InvalidMemoryXExtend128:
6779 case Match_InvalidMemoryIndexed1SImm4:
6780 case Match_InvalidMemoryIndexed2SImm4:
6781 case Match_InvalidMemoryIndexed3SImm4:
6782 case Match_InvalidMemoryIndexed4SImm4:
6783 case Match_InvalidMemoryIndexed1SImm6:
6784 case Match_InvalidMemoryIndexed16SImm4:
6785 case Match_InvalidMemoryIndexed32SImm4:
6786 case Match_InvalidMemoryIndexed4SImm7:
6787 case Match_InvalidMemoryIndexed8SImm7:
6788 case Match_InvalidMemoryIndexed16SImm7:
6789 case Match_InvalidMemoryIndexed8UImm5:
6790 case Match_InvalidMemoryIndexed8UImm3:
6791 case Match_InvalidMemoryIndexed4UImm5:
6792 case Match_InvalidMemoryIndexed2UImm5:
6793 case Match_InvalidMemoryIndexed1UImm6:
6794 case Match_InvalidMemoryIndexed2UImm6:
6795 case Match_InvalidMemoryIndexed4UImm6:
6796 case Match_InvalidMemoryIndexed8UImm6:
6797 case Match_InvalidMemoryIndexed16UImm6:
6798 case Match_InvalidMemoryIndexedSImm6:
6799 case Match_InvalidMemoryIndexedSImm5:
6800 case Match_InvalidMemoryIndexedSImm8:
6801 case Match_InvalidMemoryIndexedSImm9:
6802 case Match_InvalidMemoryIndexed16SImm9:
6803 case Match_InvalidMemoryIndexed8SImm10:
6804 case Match_InvalidImm0_0:
6805 case Match_InvalidImm0_1:
6806 case Match_InvalidImm0_3:
6807 case Match_InvalidImm0_7:
6808 case Match_InvalidImm0_15:
6809 case Match_InvalidImm0_31:
6810 case Match_InvalidImm0_63:
6811 case Match_InvalidImm0_127:
6812 case Match_InvalidImm0_255:
6813 case Match_InvalidImm0_65535:
6814 case Match_InvalidImm1_8:
6815 case Match_InvalidImm1_16:
6816 case Match_InvalidImm1_32:
6817 case Match_InvalidImm1_64:
6818 case Match_InvalidImmM1_62:
6819 case Match_InvalidMemoryIndexedRange2UImm0:
6820 case Match_InvalidMemoryIndexedRange2UImm1:
6821 case Match_InvalidMemoryIndexedRange2UImm2:
6822 case Match_InvalidMemoryIndexedRange2UImm3:
6823 case Match_InvalidMemoryIndexedRange4UImm0:
6824 case Match_InvalidMemoryIndexedRange4UImm1:
6825 case Match_InvalidMemoryIndexedRange4UImm2:
6826 case Match_InvalidSVEAddSubImm8:
6827 case Match_InvalidSVEAddSubImm16:
6828 case Match_InvalidSVEAddSubImm32:
6829 case Match_InvalidSVEAddSubImm64:
6830 case Match_InvalidSVECpyImm8:
6831 case Match_InvalidSVECpyImm16:
6832 case Match_InvalidSVECpyImm32:
6833 case Match_InvalidSVECpyImm64:
6834 case Match_InvalidIndexRange0_0:
6835 case Match_InvalidIndexRange1_1:
6836 case Match_InvalidIndexRange0_15:
6837 case Match_InvalidIndexRange0_7:
6838 case Match_InvalidIndexRange0_3:
6839 case Match_InvalidIndexRange0_1:
6840 case Match_InvalidSVEIndexRange0_63:
6841 case Match_InvalidSVEIndexRange0_31:
6842 case Match_InvalidSVEIndexRange0_15:
6843 case Match_InvalidSVEIndexRange0_7:
6844 case Match_InvalidSVEIndexRange0_3:
6845 case Match_InvalidLabel:
6846 case Match_InvalidComplexRotationEven:
6847 case Match_InvalidComplexRotationOdd:
6848 case Match_InvalidGPR64shifted8:
6849 case Match_InvalidGPR64shifted16:
6850 case Match_InvalidGPR64shifted32:
6851 case Match_InvalidGPR64shifted64:
6852 case Match_InvalidGPR64shifted128:
6853 case Match_InvalidGPR64NoXZRshifted8:
6854 case Match_InvalidGPR64NoXZRshifted16:
6855 case Match_InvalidGPR64NoXZRshifted32:
6856 case Match_InvalidGPR64NoXZRshifted64:
6857 case Match_InvalidGPR64NoXZRshifted128:
6858 case Match_InvalidZPR32UXTW8:
6859 case Match_InvalidZPR32UXTW16:
6860 case Match_InvalidZPR32UXTW32:
6861 case Match_InvalidZPR32UXTW64:
6862 case Match_InvalidZPR32SXTW8:
6863 case Match_InvalidZPR32SXTW16:
6864 case Match_InvalidZPR32SXTW32:
6865 case Match_InvalidZPR32SXTW64:
6866 case Match_InvalidZPR64UXTW8:
6867 case Match_InvalidZPR64SXTW8:
6868 case Match_InvalidZPR64UXTW16:
6869 case Match_InvalidZPR64SXTW16:
6870 case Match_InvalidZPR64UXTW32:
6871 case Match_InvalidZPR64SXTW32:
6872 case Match_InvalidZPR64UXTW64:
6873 case Match_InvalidZPR64SXTW64:
6874 case Match_InvalidZPR32LSL8:
6875 case Match_InvalidZPR32LSL16:
6876 case Match_InvalidZPR32LSL32:
6877 case Match_InvalidZPR32LSL64:
6878 case Match_InvalidZPR64LSL8:
6879 case Match_InvalidZPR64LSL16:
6880 case Match_InvalidZPR64LSL32:
6881 case Match_InvalidZPR64LSL64:
6882 case Match_InvalidZPR0:
6883 case Match_InvalidZPR8:
6884 case Match_InvalidZPR16:
6885 case Match_InvalidZPR32:
6886 case Match_InvalidZPR64:
6887 case Match_InvalidZPR128:
6888 case Match_InvalidZPR_3b8:
6889 case Match_InvalidZPR_3b16:
6890 case Match_InvalidZPR_3b32:
6891 case Match_InvalidZPR_4b8:
6892 case Match_InvalidZPR_4b16:
6893 case Match_InvalidZPR_4b32:
6894 case Match_InvalidZPR_4b64:
6895 case Match_InvalidSVEPPRorPNRAnyReg:
6896 case Match_InvalidSVEPPRorPNRBReg:
6897 case Match_InvalidSVEPredicateAnyReg:
6898 case Match_InvalidSVEPattern:
6899 case Match_InvalidSVEVecLenSpecifier:
6900 case Match_InvalidSVEPredicateBReg:
6901 case Match_InvalidSVEPredicateHReg:
6902 case Match_InvalidSVEPredicateSReg:
6903 case Match_InvalidSVEPredicateDReg:
6904 case Match_InvalidSVEPredicate3bAnyReg:
6905 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6906 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6907 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6908 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6909 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6910 case Match_InvalidSVEPNPredicateBReg:
6911 case Match_InvalidSVEPNPredicateHReg:
6912 case Match_InvalidSVEPNPredicateSReg:
6913 case Match_InvalidSVEPNPredicateDReg:
6914 case Match_InvalidSVEPredicateListMul2x8:
6915 case Match_InvalidSVEPredicateListMul2x16:
6916 case Match_InvalidSVEPredicateListMul2x32:
6917 case Match_InvalidSVEPredicateListMul2x64:
6918 case Match_InvalidSVEExactFPImmOperandHalfOne:
6919 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6920 case Match_InvalidSVEExactFPImmOperandZeroOne:
6921 case Match_InvalidMatrixTile16:
6922 case Match_InvalidMatrixTile32:
6923 case Match_InvalidMatrixTile64:
6924 case Match_InvalidMatrix:
6925 case Match_InvalidMatrix8:
6926 case Match_InvalidMatrix16:
6927 case Match_InvalidMatrix32:
6928 case Match_InvalidMatrix64:
6929 case Match_InvalidMatrixTileVectorH8:
6930 case Match_InvalidMatrixTileVectorH16:
6931 case Match_InvalidMatrixTileVectorH32:
6932 case Match_InvalidMatrixTileVectorH64:
6933 case Match_InvalidMatrixTileVectorH128:
6934 case Match_InvalidMatrixTileVectorV8:
6935 case Match_InvalidMatrixTileVectorV16:
6936 case Match_InvalidMatrixTileVectorV32:
6937 case Match_InvalidMatrixTileVectorV64:
6938 case Match_InvalidMatrixTileVectorV128:
6939 case Match_InvalidSVCR:
6940 case Match_InvalidMatrixIndexGPR32_12_15:
6941 case Match_InvalidMatrixIndexGPR32_8_11:
6942 case Match_InvalidLookupTable:
6943 case Match_InvalidZPRMul2_Lo8:
6944 case Match_InvalidZPRMul2_Hi8:
6945 case Match_InvalidZPRMul2_Lo16:
6946 case Match_InvalidZPRMul2_Hi16:
6947 case Match_InvalidZPRMul2_Lo32:
6948 case Match_InvalidZPRMul2_Hi32:
6949 case Match_InvalidZPRMul2_Lo64:
6950 case Match_InvalidZPRMul2_Hi64:
6951 case Match_InvalidZPR_K0:
6952 case Match_InvalidSVEVectorList2x8Mul2:
6953 case Match_InvalidSVEVectorList2x16Mul2:
6954 case Match_InvalidSVEVectorList2x32Mul2:
6955 case Match_InvalidSVEVectorList2x64Mul2:
6956 case Match_InvalidSVEVectorList2x128Mul2:
6957 case Match_InvalidSVEVectorList4x8Mul4:
6958 case Match_InvalidSVEVectorList4x16Mul4:
6959 case Match_InvalidSVEVectorList4x32Mul4:
6960 case Match_InvalidSVEVectorList4x64Mul4:
6961 case Match_InvalidSVEVectorList4x128Mul4:
6962 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6963 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6964 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6965 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6966 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6967 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6968 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6969 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6970 case Match_InvalidSVEVectorListStrided2x8:
6971 case Match_InvalidSVEVectorListStrided2x16:
6972 case Match_InvalidSVEVectorListStrided2x32:
6973 case Match_InvalidSVEVectorListStrided2x64:
6974 case Match_InvalidSVEVectorListStrided4x8:
6975 case Match_InvalidSVEVectorListStrided4x16:
6976 case Match_InvalidSVEVectorListStrided4x32:
6977 case Match_InvalidSVEVectorListStrided4x64:
6981 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6985 if (ErrorLoc ==
SMLoc())
6995bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
7003 if (IDVal ==
".arch")
7004 parseDirectiveArch(Loc);
7005 else if (IDVal ==
".cpu")
7006 parseDirectiveCPU(Loc);
7007 else if (IDVal ==
".tlsdesccall")
7008 parseDirectiveTLSDescCall(Loc);
7009 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7010 parseDirectiveLtorg(Loc);
7011 else if (IDVal ==
".unreq")
7012 parseDirectiveUnreq(Loc);
7013 else if (IDVal ==
".inst")
7014 parseDirectiveInst(Loc);
7015 else if (IDVal ==
".cfi_negate_ra_state")
7016 parseDirectiveCFINegateRAState();
7017 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7018 parseDirectiveCFINegateRAStateWithPC();
7019 else if (IDVal ==
".cfi_b_key_frame")
7020 parseDirectiveCFIBKeyFrame();
7021 else if (IDVal ==
".cfi_mte_tagged_frame")
7022 parseDirectiveCFIMTETaggedFrame();
7023 else if (IDVal ==
".arch_extension")
7024 parseDirectiveArchExtension(Loc);
7025 else if (IDVal ==
".variant_pcs")
7026 parseDirectiveVariantPCS(Loc);
7029 parseDirectiveLOH(IDVal, Loc);
7032 }
else if (IsCOFF) {
7033 if (IDVal ==
".seh_stackalloc")
7034 parseDirectiveSEHAllocStack(Loc);
7035 else if (IDVal ==
".seh_endprologue")
7036 parseDirectiveSEHPrologEnd(Loc);
7037 else if (IDVal ==
".seh_save_r19r20_x")
7038 parseDirectiveSEHSaveR19R20X(Loc);
7039 else if (IDVal ==
".seh_save_fplr")
7040 parseDirectiveSEHSaveFPLR(Loc);
7041 else if (IDVal ==
".seh_save_fplr_x")
7042 parseDirectiveSEHSaveFPLRX(Loc);
7043 else if (IDVal ==
".seh_save_reg")
7044 parseDirectiveSEHSaveReg(Loc);
7045 else if (IDVal ==
".seh_save_reg_x")
7046 parseDirectiveSEHSaveRegX(Loc);
7047 else if (IDVal ==
".seh_save_regp")
7048 parseDirectiveSEHSaveRegP(Loc);
7049 else if (IDVal ==
".seh_save_regp_x")
7050 parseDirectiveSEHSaveRegPX(Loc);
7051 else if (IDVal ==
".seh_save_lrpair")
7052 parseDirectiveSEHSaveLRPair(Loc);
7053 else if (IDVal ==
".seh_save_freg")
7054 parseDirectiveSEHSaveFReg(Loc);
7055 else if (IDVal ==
".seh_save_freg_x")
7056 parseDirectiveSEHSaveFRegX(Loc);
7057 else if (IDVal ==
".seh_save_fregp")
7058 parseDirectiveSEHSaveFRegP(Loc);
7059 else if (IDVal ==
".seh_save_fregp_x")
7060 parseDirectiveSEHSaveFRegPX(Loc);
7061 else if (IDVal ==
".seh_set_fp")
7062 parseDirectiveSEHSetFP(Loc);
7063 else if (IDVal ==
".seh_add_fp")
7064 parseDirectiveSEHAddFP(Loc);
7065 else if (IDVal ==
".seh_nop")
7066 parseDirectiveSEHNop(Loc);
7067 else if (IDVal ==
".seh_save_next")
7068 parseDirectiveSEHSaveNext(Loc);
7069 else if (IDVal ==
".seh_startepilogue")
7070 parseDirectiveSEHEpilogStart(Loc);
7071 else if (IDVal ==
".seh_endepilogue")
7072 parseDirectiveSEHEpilogEnd(Loc);
7073 else if (IDVal ==
".seh_trap_frame")
7074 parseDirectiveSEHTrapFrame(Loc);
7075 else if (IDVal ==
".seh_pushframe")
7076 parseDirectiveSEHMachineFrame(Loc);
7077 else if (IDVal ==
".seh_context")
7078 parseDirectiveSEHContext(Loc);
7079 else if (IDVal ==
".seh_ec_context")
7080 parseDirectiveSEHECContext(Loc);
7081 else if (IDVal ==
".seh_clear_unwound_to_call")
7082 parseDirectiveSEHClearUnwoundToCall(Loc);
7083 else if (IDVal ==
".seh_pac_sign_lr")
7084 parseDirectiveSEHPACSignLR(Loc);
7085 else if (IDVal ==
".seh_save_any_reg")
7086 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7087 else if (IDVal ==
".seh_save_any_reg_p")
7088 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7089 else if (IDVal ==
".seh_save_any_reg_x")
7090 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7091 else if (IDVal ==
".seh_save_any_reg_px")
7092 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7096 if (IDVal ==
".aeabi_subsection")
7097 parseDirectiveAeabiSubSectionHeader(Loc);
7098 else if (IDVal ==
".aeabi_attribute")
7099 parseDirectiveAeabiAArch64Attr(Loc);
7112 if (!NoCrypto && Crypto) {
7115 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7116 ArchInfo == AArch64::ARMV8_3A) {
7120 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7121 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7122 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7123 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7124 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7125 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7131 }
else if (NoCrypto) {
7134 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7135 ArchInfo == AArch64::ARMV8_3A) {
7136 RequestedExtensions.
push_back(
"nosha2");
7139 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7140 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7141 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7142 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7143 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7144 ArchInfo == AArch64::ARMV9_4A) {
7146 RequestedExtensions.
push_back(
"nosha3");
7147 RequestedExtensions.
push_back(
"nosha2");
7159bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
7160 SMLoc CurLoc = getLoc();
7163 std::tie(Arch, ExtensionString) =
7164 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7168 return Error(CurLoc,
"unknown arch name");
7174 std::vector<StringRef> AArch64Features;
7179 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7181 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7184 if (!ExtensionString.
empty())
7185 ExtensionString.
split(RequestedExtensions,
'+');
7190 for (
auto Name : RequestedExtensions) {
7194 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7201 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7210 setAvailableFeatures(Features);
7216bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7217 SMLoc ExtLoc = getLoc();
7219 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7224 bool EnableFeature =
true;
7225 if (
Name.starts_with_insensitive(
"no")) {
7226 EnableFeature =
false;
7235 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7243 setAvailableFeatures(Features);
7249bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7250 SMLoc CurLoc = getLoc();
7253 std::tie(CPU, ExtensionString) =
7254 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7260 if (!ExtensionString.
empty())
7261 ExtensionString.
split(RequestedExtensions,
'+');
7265 Error(CurLoc,
"unknown CPU name");
7274 for (
auto Name : RequestedExtensions) {
7278 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7285 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7294 setAvailableFeatures(Features);
7300bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7302 return Error(Loc,
"expected expression following '.inst' directive");
7304 auto parseOp = [&]() ->
bool {
7306 const MCExpr *Expr =
nullptr;
7307 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7310 if (check(!
Value, L,
"expected constant expression"))
7312 getTargetStreamer().emitInst(
Value->getValue());
7316 return parseMany(parseOp);
7321bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7323 if (check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7335 getParser().getStreamer().emitInstruction(Inst, getSTI());
7341bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7345 return TokError(
"expected an identifier or a number in directive");
7348 int64_t
Id = getTok().getIntVal();
7350 return TokError(
"invalid numeric identifier in directive");
7359 return TokError(
"invalid identifier in directive");
7367 assert(NbArgs != -1 &&
"Invalid number of arguments");
7370 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7372 if (getParser().parseIdentifier(
Name))
7373 return TokError(
"expected identifier in directive");
7374 Args.push_back(getContext().getOrCreateSymbol(
Name));
7376 if (
Idx + 1 == NbArgs)
7384 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7390bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7393 getTargetStreamer().emitCurrentConstantPool();
7401 SMLoc SRegLoc = getLoc();
7402 RegKind RegisterKind = RegKind::Scalar;
7404 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7408 RegisterKind = RegKind::NeonVector;
7409 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7415 return Error(SRegLoc,
"vector register without type specifier expected");
7420 RegisterKind = RegKind::SVEDataVector;
7422 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7428 return Error(SRegLoc,
7429 "sve vector register without type specifier expected");
7434 RegisterKind = RegKind::SVEPredicateVector;
7435 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7441 return Error(SRegLoc,
7442 "sve predicate register without type specifier expected");
7446 return Error(SRegLoc,
"register name or alias expected");
7452 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7453 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7454 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7461bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7463 return TokError(
"unexpected input in .unreq directive.");
7464 RegisterReqs.
erase(getTok().getIdentifier().lower());
7469bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7472 getStreamer().emitCFINegateRAState();
7476bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7479 getStreamer().emitCFINegateRAStateWithPC();
7485bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7488 getStreamer().emitCFIBKeyFrame();
7494bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7497 getStreamer().emitCFIMTETaggedFrame();
7503bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7505 if (getParser().parseIdentifier(
Name))
7506 return TokError(
"expected symbol name");
7509 getTargetStreamer().emitDirectiveVariantPCS(
7510 getContext().getOrCreateSymbol(
Name));
7516bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7518 if (parseImmExpr(
Size))
7520 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7526bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7527 getTargetStreamer().emitARM64WinCFIPrologEnd();
7533bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7535 if (parseImmExpr(
Offset))
7537 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7543bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7545 if (parseImmExpr(
Offset))
7547 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7553bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7555 if (parseImmExpr(
Offset))
7557 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7563bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7566 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7567 parseComma() || parseImmExpr(
Offset))
7569 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7575bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7578 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7579 parseComma() || parseImmExpr(
Offset))
7581 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7587bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7590 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7591 parseComma() || parseImmExpr(
Offset))
7593 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7599bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7602 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7603 parseComma() || parseImmExpr(
Offset))
7605 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7611bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7615 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7616 parseComma() || parseImmExpr(
Offset))
7618 if (check(((Reg - 19) % 2 != 0), L,
7619 "expected register with even offset from x19"))
7621 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7627bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7630 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7631 parseComma() || parseImmExpr(
Offset))
7633 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7639bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7642 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7643 parseComma() || parseImmExpr(
Offset))
7645 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7651bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7654 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7655 parseComma() || parseImmExpr(
Offset))
7657 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7663bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7666 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7667 parseComma() || parseImmExpr(
Offset))
7669 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7675bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7676 getTargetStreamer().emitARM64WinCFISetFP();
7682bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7684 if (parseImmExpr(
Size))
7686 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7692bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7693 getTargetStreamer().emitARM64WinCFINop();
7699bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7700 getTargetStreamer().emitARM64WinCFISaveNext();
7706bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7707 getTargetStreamer().emitARM64WinCFIEpilogStart();
7713bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7714 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7720bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7721 getTargetStreamer().emitARM64WinCFITrapFrame();
7727bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7728 getTargetStreamer().emitARM64WinCFIMachineFrame();
7734bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7735 getTargetStreamer().emitARM64WinCFIContext();
7741bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7742 getTargetStreamer().emitARM64WinCFIECContext();
7748bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7749 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7755bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7756 getTargetStreamer().emitARM64WinCFIPACSignLR();
7765bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7770 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7771 parseComma() || parseImmExpr(
Offset))
7774 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7775 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7776 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7777 return Error(L,
"invalid save_any_reg offset");
7778 unsigned EncodedReg;
7779 if (Reg == AArch64::FP)
7781 else if (Reg == AArch64::LR)
7784 EncodedReg =
Reg - AArch64::X0;
7786 if (Reg == AArch64::LR)
7787 return Error(Start,
"lr cannot be paired with another register");
7789 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7791 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7794 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7796 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7798 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7799 unsigned EncodedReg =
Reg - AArch64::D0;
7800 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7801 return Error(L,
"invalid save_any_reg offset");
7803 if (Reg == AArch64::D31)
7804 return Error(Start,
"d31 cannot be paired with another register");
7806 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7808 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7811 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7813 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7815 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7816 unsigned EncodedReg =
Reg - AArch64::Q0;
7818 return Error(L,
"invalid save_any_reg offset");
7820 if (Reg == AArch64::Q31)
7821 return Error(Start,
"q31 cannot be paired with another register");
7823 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7825 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7828 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7830 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7833 return Error(Start,
"save_any_reg register must be x, q or d register");
7838bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(
SMLoc L) {
7862 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
7863 getTargetStreamer().getAtributesSubsectionByName(SubsectionName);
7877 if (SubsectionExists) {
7878 if (IsOptional != SubsectionExists->IsOptional) {
7880 "optionality mismatch! subsection '" + SubsectionName +
7881 "' already exists with optionality defined as '" +
7883 SubsectionExists->IsOptional) +
7891 "optionality parameter not found, expected required|optional");
7898 "aeabi_feature_and_bits must be marked as optional");
7905 "aeabi_pauthabi must be marked as required");
7926 if (SubsectionExists) {
7927 if (
Type != SubsectionExists->ParameterType) {
7929 "type mismatch! subsection '" + SubsectionName +
7930 "' already exists with type defined as '" +
7932 SubsectionExists->ParameterType) +
7940 "type parameter not found, expected uleb128|ntbs");
7948 SubsectionName +
" must be marked as ULEB128");
7956 "attributes subsection header directive");
7960 getTargetStreamer().emitAtributesSubsection(SubsectionName, IsOptional,
Type);
7965bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(
SMLoc L) {
7971 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
7972 getTargetStreamer().getActiveAtributesSubsection();
7973 if (
nullptr == ActiveSubsection) {
7975 "no active subsection, build attribute can not be added");
7978 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
7979 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
7987 ActiveSubsectionName)
7994 switch (ActiveSubsectionID) {
7996 assert(0 &&
"Subsection name error");
8005 TagStr +
"' for subsection '" +
8006 ActiveSubsectionName +
"'");
8014 TagStr +
"' for subsection '" +
8015 ActiveSubsectionName +
"'");
8021 Tag = getTok().getIntVal();
8036 std::string ValueStr =
"";
8041 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8044 ValueInt = getTok().getIntVal();
8049 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8057 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8069 if (0 != ValueInt && 1 != ValueInt) {
8071 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8072 "' options are 0|1");
8080 "unexpected token for AArch64 build attributes tag and value "
8081 "attribute directive");
8085 if (
unsigned(-1) != ValueInt) {
8086 getTargetStreamer().emitAttribute(ActiveSubsectionName, Tag, ValueInt,
"",
8090 if (
"" != ValueStr) {
8091 getTargetStreamer().emitAttribute(ActiveSubsectionName, Tag,
unsigned(-1),
8097bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8099 if (!parseAuthExpr(Res, EndLoc))
8101 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8108bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8119 "combination of @AUTH with other modifiers not supported");
8142 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
8164 return TokError(
"expected key name");
8169 return TokError(
"invalid key '" + KeyStr +
"'");
8176 return TokError(
"expected integer discriminator");
8179 if (!isUInt<16>(Discriminator))
8180 return TokError(
"integer discriminator " +
Twine(Discriminator) +
8181 " out of range [0, 0xFFFF]");
8184 bool UseAddressDiversity =
false;
8189 return TokError(
"expected 'addr'");
8190 UseAddressDiversity =
true;
8199 UseAddressDiversity, Ctx);
8204AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8212 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
8213 ELFRefKind = AE->getKind();
8214 Expr = AE->getSubExpr();
8220 DarwinRefKind = SE->
getKind();
8227 if (!Relocatable || Res.
getSymB())
8254#define GET_REGISTER_MATCHER
8255#define GET_SUBTARGET_FEATURE_NAME
8256#define GET_MATCHER_IMPLEMENTATION
8257#define GET_MNEMONIC_SPELL_CHECKER
8258#include "AArch64GenAsmMatcher.inc"
8264 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8266 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8268 return Match_InvalidOperand;
8271 return Match_InvalidOperand;
8272 if (CE->getValue() == ExpectedVal)
8273 return Match_Success;
8274 return Match_InvalidOperand;
8279 return Match_InvalidOperand;
8285 if (
Op.isTokenEqual(
"za"))
8286 return Match_Success;
8287 return Match_InvalidOperand;
8293#define MATCH_HASH(N) \
8294 case MCK__HASH_##N: \
8295 return MatchesOpImmediate(N);
8321#define MATCH_HASH_MINUS(N) \
8322 case MCK__HASH__MINUS_##N: \
8323 return MatchesOpImmediate(-N);
8327#undef MATCH_HASH_MINUS
8336 return Error(S,
"expected register");
8339 ParseStatus Res = tryParseScalarRegister(FirstReg);
8341 return Error(S,
"expected first even register of a consecutive same-size "
8342 "even/odd register pair");
8345 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8347 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8349 bool isXReg = XRegClass.
contains(FirstReg),
8350 isWReg = WRegClass.
contains(FirstReg);
8351 if (!isXReg && !isWReg)
8352 return Error(S,
"expected first even register of a consecutive same-size "
8353 "even/odd register pair");
8358 if (FirstEncoding & 0x1)
8359 return Error(S,
"expected first even register of a consecutive same-size "
8360 "even/odd register pair");
8363 return Error(getLoc(),
"expected comma");
8369 Res = tryParseScalarRegister(SecondReg);
8371 return Error(E,
"expected second odd register of a consecutive same-size "
8372 "even/odd register pair");
8375 (isXReg && !XRegClass.
contains(SecondReg)) ||
8376 (isWReg && !WRegClass.
contains(SecondReg)))
8377 return Error(E,
"expected second odd register of a consecutive same-size "
8378 "even/odd register pair");
8383 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8386 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8389 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8390 getLoc(), getContext()));
8395template <
bool ParseShiftExtend,
bool ParseSuffix>
8397 const SMLoc S = getLoc();
8403 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8408 if (ParseSuffix &&
Kind.empty())
8415 unsigned ElementWidth = KindRes->second;
8419 Operands.push_back(AArch64Operand::CreateVectorReg(
8420 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
8433 Res = tryParseOptionalShiftExtend(ExtOpnd);
8437 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
8438 Operands.push_back(AArch64Operand::CreateVectorReg(
8439 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8440 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
8441 Ext->hasShiftExtendAmount()));
8466 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8468 return TokError(
"invalid operand for instruction");
8473 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8484 SS, getLoc(), getContext()));
8495 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8506 SS, getLoc(), getContext()));
8515 if (!tryParseScalarRegister(XReg).isSuccess())
8521 XReg, AArch64::x8sub_0,
8522 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8525 "expected an even-numbered x-register in the range [x0,x22]");
8528 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8542 if (getParser().parseExpression(ImmF))
8552 SMLoc E = getTok().getLoc();
8554 if (getParser().parseExpression(ImmL))
8557 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8558 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8561 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
8576 if (getParser().parseExpression(Ex))
8579 int64_t
Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
8586 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8593 Operands.push_back(AArch64Operand::CreateImm(
#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(MCRegister ZReg, MCRegister 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)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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 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 MCAssembler *Asm, 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 createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister 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.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
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 ClearFeatureBitsTransitively(const FeatureBitset &FB)
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.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
@ 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
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
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...
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.
bool isWindowsArm64EC() const
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.
SubsectionType getTypeID(StringRef Type)
StringRef getVendorName(unsigned const Vendor)
StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
StringRef getSubsectionTypeUnknownError()
SubsectionOptional getOptionalID(StringRef Optional)
StringRef getSubsectionOptionalUnknownError()
FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
VendorID getVendorID(StringRef const Vendor)
PauthABITags getPauthABITagsID(StringRef PauthABITag)
StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
const PHint * lookupPHintByName(StringRef)
uint32_t parseGenericRegister(StringRef Name)
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 ==...
const ArchInfo * parseArch(StringRef Arch)
const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
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.
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()
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
Target & getTheARM64Target()
DWARFExpression::Operation Op
static MCRegister getWRegFromXReg(MCRegister Reg)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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