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()));
5031 bool isNegative =
false;
5047 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5048 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5049 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5050 return TokError(
"unexpected floating point literal");
5051 else if (IntVal != 0 || isNegative)
5052 return TokError(
"expected floating-point constant #0.0");
5055 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
5056 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
5061 if (parseSymbolicImmVal(ImmVal))
5065 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
5068 return parseOptionalShiftExtend(Tok);
5071 SMLoc Loc = getLoc();
5072 if (Mnemonic !=
"ldr")
5073 return TokError(
"unexpected token in operand");
5075 const MCExpr *SubExprVal;
5076 if (getParser().parseExpression(SubExprVal))
5080 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5081 return Error(Loc,
"Only valid when first operand is register");
5084 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5090 if (isa<MCConstantExpr>(SubExprVal)) {
5091 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
5092 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5097 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5098 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5099 Operands.push_back(AArch64Operand::CreateImm(
5103 ShiftAmt,
true, S, E, Ctx));
5109 return Error(Loc,
"Immediate too large for register");
5113 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5114 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
5120bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5121 const MCExpr *Expr =
nullptr;
5123 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5126 if (check(!
Value, L,
"expected constant expression"))
5128 Out =
Value->getValue();
5132bool AArch64AsmParser::parseComma() {
5140bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5144 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5149 unsigned RangeEnd =
Last;
5150 if (
Base == AArch64::X0) {
5151 if (
Last == AArch64::FP) {
5152 RangeEnd = AArch64::X28;
5153 if (Reg == AArch64::FP) {
5158 if (
Last == AArch64::LR) {
5159 RangeEnd = AArch64::X28;
5160 if (Reg == AArch64::FP) {
5163 }
else if (Reg == AArch64::LR) {
5170 if (check(Reg < First || Reg > RangeEnd, Start,
5171 Twine(
"expected register in range ") +
5181 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5182 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5184 if (AOp1.isVectorList() && AOp2.isVectorList())
5185 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5186 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5187 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5189 if (!AOp1.isReg() || !AOp2.isReg())
5192 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5193 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5196 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5197 "Testing equality of non-scalar registers not supported");
5200 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5202 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5204 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5206 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5217 .
Case(
"beq",
"b.eq")
5218 .
Case(
"bne",
"b.ne")
5219 .
Case(
"bhs",
"b.hs")
5220 .
Case(
"bcs",
"b.cs")
5221 .
Case(
"blo",
"b.lo")
5222 .
Case(
"bcc",
"b.cc")
5223 .
Case(
"bmi",
"b.mi")
5224 .
Case(
"bpl",
"b.pl")
5225 .
Case(
"bvs",
"b.vs")
5226 .
Case(
"bvc",
"b.vc")
5227 .
Case(
"bhi",
"b.hi")
5228 .
Case(
"bls",
"b.ls")
5229 .
Case(
"bge",
"b.ge")
5230 .
Case(
"blt",
"b.lt")
5231 .
Case(
"bgt",
"b.gt")
5232 .
Case(
"ble",
"b.le")
5233 .
Case(
"bal",
"b.al")
5234 .
Case(
"bnv",
"b.nv")
5239 getTok().getIdentifier().lower() ==
".req") {
5240 parseDirectiveReq(
Name, NameLoc);
5247 size_t Start = 0, Next =
Name.find(
'.');
5252 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5253 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5254 return parseSysAlias(Head, NameLoc,
Operands);
5257 if (Head ==
"tlbip")
5258 return parseSyspAlias(Head, NameLoc,
Operands);
5260 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5266 Next =
Name.find(
'.', Start + 1);
5267 Head =
Name.slice(Start + 1, Next);
5271 std::string Suggestion;
5274 std::string Msg =
"invalid condition code";
5275 if (!Suggestion.empty())
5276 Msg +=
", did you mean " + Suggestion +
"?";
5277 return Error(SuffixLoc, Msg);
5279 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5282 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5288 Next =
Name.find(
'.', Start + 1);
5289 Head =
Name.slice(Start, Next);
5292 Operands.push_back(AArch64Operand::CreateToken(
5293 Head, SuffixLoc, getContext(),
true));
5298 bool condCodeFourthOperand =
5299 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5300 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5301 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5309 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5310 bool condCodeThirdOperand =
5311 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5319 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5320 (
N == 3 && condCodeThirdOperand) ||
5321 (
N == 2 && condCodeSecondOperand),
5322 condCodeSecondOperand || condCodeThirdOperand)) {
5342 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5345 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5348 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5361 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5362 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5363 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5364 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5365 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5366 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5367 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5373bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5382 PrefixInfo
Prefix = NextPrefix;
5383 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5395 return Error(IDLoc,
"instruction is unpredictable when following a"
5396 " movprfx, suggest replacing movprfx with mov");
5400 return Error(Loc[0],
"instruction is unpredictable when following a"
5401 " movprfx writing to a different destination");
5408 return Error(Loc[0],
"instruction is unpredictable when following a"
5409 " movprfx and destination also used as non-destructive"
5413 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5414 if (
Prefix.isPredicated()) {
5428 return Error(IDLoc,
"instruction is unpredictable when following a"
5429 " predicated movprfx, suggest using unpredicated movprfx");
5433 return Error(IDLoc,
"instruction is unpredictable when following a"
5434 " predicated movprfx using a different general predicate");
5438 return Error(IDLoc,
"instruction is unpredictable when following a"
5439 " predicated movprfx with a different element size");
5445 if (IsWindowsArm64EC) {
5451 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5452 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5453 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5454 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5455 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5456 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5457 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5458 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5459 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5460 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5462 " is disallowed on ARM64EC.");
5472 case AArch64::LDPSWpre:
5473 case AArch64::LDPWpost:
5474 case AArch64::LDPWpre:
5475 case AArch64::LDPXpost:
5476 case AArch64::LDPXpre: {
5481 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5482 "is also a destination");
5484 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5485 "is also a destination");
5488 case AArch64::LDR_ZA:
5489 case AArch64::STR_ZA: {
5492 return Error(Loc[1],
5493 "unpredictable instruction, immediate and offset mismatch.");
5496 case AArch64::LDPDi:
5497 case AArch64::LDPQi:
5498 case AArch64::LDPSi:
5499 case AArch64::LDPSWi:
5500 case AArch64::LDPWi:
5501 case AArch64::LDPXi: {
5505 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5508 case AArch64::LDPDpost:
5509 case AArch64::LDPDpre:
5510 case AArch64::LDPQpost:
5511 case AArch64::LDPQpre:
5512 case AArch64::LDPSpost:
5513 case AArch64::LDPSpre:
5514 case AArch64::LDPSWpost: {
5518 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5521 case AArch64::STPDpost:
5522 case AArch64::STPDpre:
5523 case AArch64::STPQpost:
5524 case AArch64::STPQpre:
5525 case AArch64::STPSpost:
5526 case AArch64::STPSpre:
5527 case AArch64::STPWpost:
5528 case AArch64::STPWpre:
5529 case AArch64::STPXpost:
5530 case AArch64::STPXpre: {
5535 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5536 "is also a source");
5538 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5539 "is also a source");
5542 case AArch64::LDRBBpre:
5543 case AArch64::LDRBpre:
5544 case AArch64::LDRHHpre:
5545 case AArch64::LDRHpre:
5546 case AArch64::LDRSBWpre:
5547 case AArch64::LDRSBXpre:
5548 case AArch64::LDRSHWpre:
5549 case AArch64::LDRSHXpre:
5550 case AArch64::LDRSWpre:
5551 case AArch64::LDRWpre:
5552 case AArch64::LDRXpre:
5553 case AArch64::LDRBBpost:
5554 case AArch64::LDRBpost:
5555 case AArch64::LDRHHpost:
5556 case AArch64::LDRHpost:
5557 case AArch64::LDRSBWpost:
5558 case AArch64::LDRSBXpost:
5559 case AArch64::LDRSHWpost:
5560 case AArch64::LDRSHXpost:
5561 case AArch64::LDRSWpost:
5562 case AArch64::LDRWpost:
5563 case AArch64::LDRXpost: {
5567 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5568 "is also a source");
5571 case AArch64::STRBBpost:
5572 case AArch64::STRBpost:
5573 case AArch64::STRHHpost:
5574 case AArch64::STRHpost:
5575 case AArch64::STRWpost:
5576 case AArch64::STRXpost:
5577 case AArch64::STRBBpre:
5578 case AArch64::STRBpre:
5579 case AArch64::STRHHpre:
5580 case AArch64::STRHpre:
5581 case AArch64::STRWpre:
5582 case AArch64::STRXpre: {
5586 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5587 "is also a source");
5590 case AArch64::STXRB:
5591 case AArch64::STXRH:
5592 case AArch64::STXRW:
5593 case AArch64::STXRX:
5594 case AArch64::STLXRB:
5595 case AArch64::STLXRH:
5596 case AArch64::STLXRW:
5597 case AArch64::STLXRX: {
5603 return Error(Loc[0],
5604 "unpredictable STXR instruction, status is also a source");
5607 case AArch64::STXPW:
5608 case AArch64::STXPX:
5609 case AArch64::STLXPW:
5610 case AArch64::STLXPX: {
5617 return Error(Loc[0],
5618 "unpredictable STXP instruction, status is also a source");
5621 case AArch64::LDRABwriteback:
5622 case AArch64::LDRAAwriteback: {
5626 return Error(Loc[0],
5627 "unpredictable LDRA instruction, writeback base"
5628 " is also a destination");
5635 case AArch64::CPYFP:
5636 case AArch64::CPYFPWN:
5637 case AArch64::CPYFPRN:
5638 case AArch64::CPYFPN:
5639 case AArch64::CPYFPWT:
5640 case AArch64::CPYFPWTWN:
5641 case AArch64::CPYFPWTRN:
5642 case AArch64::CPYFPWTN:
5643 case AArch64::CPYFPRT:
5644 case AArch64::CPYFPRTWN:
5645 case AArch64::CPYFPRTRN:
5646 case AArch64::CPYFPRTN:
5647 case AArch64::CPYFPT:
5648 case AArch64::CPYFPTWN:
5649 case AArch64::CPYFPTRN:
5650 case AArch64::CPYFPTN:
5651 case AArch64::CPYFM:
5652 case AArch64::CPYFMWN:
5653 case AArch64::CPYFMRN:
5654 case AArch64::CPYFMN:
5655 case AArch64::CPYFMWT:
5656 case AArch64::CPYFMWTWN:
5657 case AArch64::CPYFMWTRN:
5658 case AArch64::CPYFMWTN:
5659 case AArch64::CPYFMRT:
5660 case AArch64::CPYFMRTWN:
5661 case AArch64::CPYFMRTRN:
5662 case AArch64::CPYFMRTN:
5663 case AArch64::CPYFMT:
5664 case AArch64::CPYFMTWN:
5665 case AArch64::CPYFMTRN:
5666 case AArch64::CPYFMTN:
5667 case AArch64::CPYFE:
5668 case AArch64::CPYFEWN:
5669 case AArch64::CPYFERN:
5670 case AArch64::CPYFEN:
5671 case AArch64::CPYFEWT:
5672 case AArch64::CPYFEWTWN:
5673 case AArch64::CPYFEWTRN:
5674 case AArch64::CPYFEWTN:
5675 case AArch64::CPYFERT:
5676 case AArch64::CPYFERTWN:
5677 case AArch64::CPYFERTRN:
5678 case AArch64::CPYFERTN:
5679 case AArch64::CPYFET:
5680 case AArch64::CPYFETWN:
5681 case AArch64::CPYFETRN:
5682 case AArch64::CPYFETN:
5684 case AArch64::CPYPWN:
5685 case AArch64::CPYPRN:
5686 case AArch64::CPYPN:
5687 case AArch64::CPYPWT:
5688 case AArch64::CPYPWTWN:
5689 case AArch64::CPYPWTRN:
5690 case AArch64::CPYPWTN:
5691 case AArch64::CPYPRT:
5692 case AArch64::CPYPRTWN:
5693 case AArch64::CPYPRTRN:
5694 case AArch64::CPYPRTN:
5695 case AArch64::CPYPT:
5696 case AArch64::CPYPTWN:
5697 case AArch64::CPYPTRN:
5698 case AArch64::CPYPTN:
5700 case AArch64::CPYMWN:
5701 case AArch64::CPYMRN:
5702 case AArch64::CPYMN:
5703 case AArch64::CPYMWT:
5704 case AArch64::CPYMWTWN:
5705 case AArch64::CPYMWTRN:
5706 case AArch64::CPYMWTN:
5707 case AArch64::CPYMRT:
5708 case AArch64::CPYMRTWN:
5709 case AArch64::CPYMRTRN:
5710 case AArch64::CPYMRTN:
5711 case AArch64::CPYMT:
5712 case AArch64::CPYMTWN:
5713 case AArch64::CPYMTRN:
5714 case AArch64::CPYMTN:
5716 case AArch64::CPYEWN:
5717 case AArch64::CPYERN:
5718 case AArch64::CPYEN:
5719 case AArch64::CPYEWT:
5720 case AArch64::CPYEWTWN:
5721 case AArch64::CPYEWTRN:
5722 case AArch64::CPYEWTN:
5723 case AArch64::CPYERT:
5724 case AArch64::CPYERTWN:
5725 case AArch64::CPYERTRN:
5726 case AArch64::CPYERTN:
5727 case AArch64::CPYET:
5728 case AArch64::CPYETWN:
5729 case AArch64::CPYETRN:
5730 case AArch64::CPYETN: {
5738 return Error(Loc[0],
5739 "invalid CPY instruction, Xd_wb and Xd do not match");
5741 return Error(Loc[0],
5742 "invalid CPY instruction, Xs_wb and Xs do not match");
5744 return Error(Loc[0],
5745 "invalid CPY instruction, Xn_wb and Xn do not match");
5747 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5748 " registers are the same");
5750 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5751 " registers are the same");
5753 return Error(Loc[0],
"invalid CPY instruction, source and size"
5754 " registers are the same");
5758 case AArch64::SETPT:
5759 case AArch64::SETPN:
5760 case AArch64::SETPTN:
5762 case AArch64::SETMT:
5763 case AArch64::SETMN:
5764 case AArch64::SETMTN:
5766 case AArch64::SETET:
5767 case AArch64::SETEN:
5768 case AArch64::SETETN:
5769 case AArch64::SETGP:
5770 case AArch64::SETGPT:
5771 case AArch64::SETGPN:
5772 case AArch64::SETGPTN:
5773 case AArch64::SETGM:
5774 case AArch64::SETGMT:
5775 case AArch64::SETGMN:
5776 case AArch64::SETGMTN:
5777 case AArch64::MOPSSETGE:
5778 case AArch64::MOPSSETGET:
5779 case AArch64::MOPSSETGEN:
5780 case AArch64::MOPSSETGETN: {
5787 return Error(Loc[0],
5788 "invalid SET instruction, Xd_wb and Xd do not match");
5790 return Error(Loc[0],
5791 "invalid SET instruction, Xn_wb and Xn do not match");
5793 return Error(Loc[0],
"invalid SET instruction, destination and size"
5794 " registers are the same");
5796 return Error(Loc[0],
"invalid SET instruction, destination and source"
5797 " registers are the same");
5799 return Error(Loc[0],
"invalid SET instruction, source and size"
5800 " registers are the same");
5809 case AArch64::ADDSWri:
5810 case AArch64::ADDSXri:
5811 case AArch64::ADDWri:
5812 case AArch64::ADDXri:
5813 case AArch64::SUBSWri:
5814 case AArch64::SUBSXri:
5815 case AArch64::SUBWri:
5816 case AArch64::SUBXri: {
5824 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5853 return Error(Loc.
back(),
"invalid immediate expression");
5866 unsigned VariantID = 0);
5868bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5872 case Match_InvalidTiedOperand: {
5874 if (
Op.isVectorList())
5875 return Error(Loc,
"operand must match destination register list");
5877 assert(
Op.isReg() &&
"Unexpected operand type");
5878 switch (
Op.getRegEqualityTy()) {
5879 case RegConstraintEqualityTy::EqualsSubReg:
5880 return Error(Loc,
"operand must be 64-bit form of destination register");
5881 case RegConstraintEqualityTy::EqualsSuperReg:
5882 return Error(Loc,
"operand must be 32-bit form of destination register");
5883 case RegConstraintEqualityTy::EqualsReg:
5884 return Error(Loc,
"operand must match destination register");
5888 case Match_MissingFeature:
5890 "instruction requires a CPU feature not currently enabled");
5891 case Match_InvalidOperand:
5892 return Error(Loc,
"invalid operand for instruction");
5893 case Match_InvalidSuffix:
5894 return Error(Loc,
"invalid type suffix for instruction");
5895 case Match_InvalidCondCode:
5896 return Error(Loc,
"expected AArch64 condition code");
5897 case Match_AddSubRegExtendSmall:
5899 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5900 case Match_AddSubRegExtendLarge:
5902 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5903 case Match_AddSubSecondSource:
5905 "expected compatible register, symbol or integer in range [0, 4095]");
5906 case Match_LogicalSecondSource:
5907 return Error(Loc,
"expected compatible register or logical immediate");
5908 case Match_InvalidMovImm32Shift:
5909 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5910 case Match_InvalidMovImm64Shift:
5911 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5912 case Match_AddSubRegShift32:
5914 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5915 case Match_AddSubRegShift64:
5917 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5918 case Match_InvalidFPImm:
5920 "expected compatible register or floating-point constant");
5921 case Match_InvalidMemoryIndexedSImm6:
5922 return Error(Loc,
"index must be an integer in range [-32, 31].");
5923 case Match_InvalidMemoryIndexedSImm5:
5924 return Error(Loc,
"index must be an integer in range [-16, 15].");
5925 case Match_InvalidMemoryIndexed1SImm4:
5926 return Error(Loc,
"index must be an integer in range [-8, 7].");
5927 case Match_InvalidMemoryIndexed2SImm4:
5928 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5929 case Match_InvalidMemoryIndexed3SImm4:
5930 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5931 case Match_InvalidMemoryIndexed4SImm4:
5932 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5933 case Match_InvalidMemoryIndexed16SImm4:
5934 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5935 case Match_InvalidMemoryIndexed32SImm4:
5936 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5937 case Match_InvalidMemoryIndexed1SImm6:
5938 return Error(Loc,
"index must be an integer in range [-32, 31].");
5939 case Match_InvalidMemoryIndexedSImm8:
5940 return Error(Loc,
"index must be an integer in range [-128, 127].");
5941 case Match_InvalidMemoryIndexedSImm9:
5942 return Error(Loc,
"index must be an integer in range [-256, 255].");
5943 case Match_InvalidMemoryIndexed16SImm9:
5944 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5945 case Match_InvalidMemoryIndexed8SImm10:
5946 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5947 case Match_InvalidMemoryIndexed4SImm7:
5948 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5949 case Match_InvalidMemoryIndexed8SImm7:
5950 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5951 case Match_InvalidMemoryIndexed16SImm7:
5952 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5953 case Match_InvalidMemoryIndexed8UImm5:
5954 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5955 case Match_InvalidMemoryIndexed8UImm3:
5956 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5957 case Match_InvalidMemoryIndexed4UImm5:
5958 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5959 case Match_InvalidMemoryIndexed2UImm5:
5960 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5961 case Match_InvalidMemoryIndexed8UImm6:
5962 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5963 case Match_InvalidMemoryIndexed16UImm6:
5964 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5965 case Match_InvalidMemoryIndexed4UImm6:
5966 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5967 case Match_InvalidMemoryIndexed2UImm6:
5968 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5969 case Match_InvalidMemoryIndexed1UImm6:
5970 return Error(Loc,
"index must be in range [0, 63].");
5971 case Match_InvalidMemoryWExtend8:
5973 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5974 case Match_InvalidMemoryWExtend16:
5976 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5977 case Match_InvalidMemoryWExtend32:
5979 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5980 case Match_InvalidMemoryWExtend64:
5982 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5983 case Match_InvalidMemoryWExtend128:
5985 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5986 case Match_InvalidMemoryXExtend8:
5988 "expected 'lsl' or 'sxtx' with optional shift of #0");
5989 case Match_InvalidMemoryXExtend16:
5991 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5992 case Match_InvalidMemoryXExtend32:
5994 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5995 case Match_InvalidMemoryXExtend64:
5997 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5998 case Match_InvalidMemoryXExtend128:
6000 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6001 case Match_InvalidMemoryIndexed1:
6002 return Error(Loc,
"index must be an integer in range [0, 4095].");
6003 case Match_InvalidMemoryIndexed2:
6004 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6005 case Match_InvalidMemoryIndexed4:
6006 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6007 case Match_InvalidMemoryIndexed8:
6008 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6009 case Match_InvalidMemoryIndexed16:
6010 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6011 case Match_InvalidImm0_0:
6012 return Error(Loc,
"immediate must be 0.");
6013 case Match_InvalidImm0_1:
6014 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6015 case Match_InvalidImm0_3:
6016 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6017 case Match_InvalidImm0_7:
6018 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6019 case Match_InvalidImm0_15:
6020 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6021 case Match_InvalidImm0_31:
6022 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6023 case Match_InvalidImm0_63:
6024 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6025 case Match_InvalidImm0_127:
6026 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6027 case Match_InvalidImm0_255:
6028 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6029 case Match_InvalidImm0_65535:
6030 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6031 case Match_InvalidImm1_8:
6032 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6033 case Match_InvalidImm1_16:
6034 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6035 case Match_InvalidImm1_32:
6036 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6037 case Match_InvalidImm1_64:
6038 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6039 case Match_InvalidImmM1_62:
6040 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6041 case Match_InvalidMemoryIndexedRange2UImm0:
6042 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6043 case Match_InvalidMemoryIndexedRange2UImm1:
6044 return Error(Loc,
"vector select offset must be an immediate range of the "
6045 "form <immf>:<imml>, where the first "
6046 "immediate is a multiple of 2 in the range [0, 2], and "
6047 "the second immediate is immf + 1.");
6048 case Match_InvalidMemoryIndexedRange2UImm2:
6049 case Match_InvalidMemoryIndexedRange2UImm3:
6052 "vector select offset must be an immediate range of the form "
6054 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6056 "depending on the instruction, and the second immediate is immf + 1.");
6057 case Match_InvalidMemoryIndexedRange4UImm0:
6058 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6059 case Match_InvalidMemoryIndexedRange4UImm1:
6060 case Match_InvalidMemoryIndexedRange4UImm2:
6063 "vector select offset must be an immediate range of the form "
6065 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6067 "depending on the instruction, and the second immediate is immf + 3.");
6068 case Match_InvalidSVEAddSubImm8:
6069 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6070 " with a shift amount of 0");
6071 case Match_InvalidSVEAddSubImm16:
6072 case Match_InvalidSVEAddSubImm32:
6073 case Match_InvalidSVEAddSubImm64:
6074 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6075 "multiple of 256 in range [256, 65280]");
6076 case Match_InvalidSVECpyImm8:
6077 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6078 " with a shift amount of 0");
6079 case Match_InvalidSVECpyImm16:
6080 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6081 "multiple of 256 in range [-32768, 65280]");
6082 case Match_InvalidSVECpyImm32:
6083 case Match_InvalidSVECpyImm64:
6084 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6085 "multiple of 256 in range [-32768, 32512]");
6086 case Match_InvalidIndexRange0_0:
6087 return Error(Loc,
"expected lane specifier '[0]'");
6088 case Match_InvalidIndexRange1_1:
6089 return Error(Loc,
"expected lane specifier '[1]'");
6090 case Match_InvalidIndexRange0_15:
6091 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6092 case Match_InvalidIndexRange0_7:
6093 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6094 case Match_InvalidIndexRange0_3:
6095 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6096 case Match_InvalidIndexRange0_1:
6097 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6098 case Match_InvalidSVEIndexRange0_63:
6099 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6100 case Match_InvalidSVEIndexRange0_31:
6101 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6102 case Match_InvalidSVEIndexRange0_15:
6103 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6104 case Match_InvalidSVEIndexRange0_7:
6105 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6106 case Match_InvalidSVEIndexRange0_3:
6107 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6108 case Match_InvalidLabel:
6109 return Error(Loc,
"expected label or encodable integer pc offset");
6111 return Error(Loc,
"expected readable system register");
6113 case Match_InvalidSVCR:
6114 return Error(Loc,
"expected writable system register or pstate");
6115 case Match_InvalidComplexRotationEven:
6116 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6117 case Match_InvalidComplexRotationOdd:
6118 return Error(Loc,
"complex rotation must be 90 or 270.");
6119 case Match_MnemonicFail: {
6121 ((AArch64Operand &)*
Operands[0]).getToken(),
6122 ComputeAvailableFeatures(STI->getFeatureBits()));
6123 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6125 case Match_InvalidGPR64shifted8:
6126 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6127 case Match_InvalidGPR64shifted16:
6128 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6129 case Match_InvalidGPR64shifted32:
6130 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6131 case Match_InvalidGPR64shifted64:
6132 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6133 case Match_InvalidGPR64shifted128:
6135 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6136 case Match_InvalidGPR64NoXZRshifted8:
6137 return Error(Loc,
"register must be x0..x30 without shift");
6138 case Match_InvalidGPR64NoXZRshifted16:
6139 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6140 case Match_InvalidGPR64NoXZRshifted32:
6141 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6142 case Match_InvalidGPR64NoXZRshifted64:
6143 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6144 case Match_InvalidGPR64NoXZRshifted128:
6145 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6146 case Match_InvalidZPR32UXTW8:
6147 case Match_InvalidZPR32SXTW8:
6148 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6149 case Match_InvalidZPR32UXTW16:
6150 case Match_InvalidZPR32SXTW16:
6151 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6152 case Match_InvalidZPR32UXTW32:
6153 case Match_InvalidZPR32SXTW32:
6154 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6155 case Match_InvalidZPR32UXTW64:
6156 case Match_InvalidZPR32SXTW64:
6157 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6158 case Match_InvalidZPR64UXTW8:
6159 case Match_InvalidZPR64SXTW8:
6160 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6161 case Match_InvalidZPR64UXTW16:
6162 case Match_InvalidZPR64SXTW16:
6163 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6164 case Match_InvalidZPR64UXTW32:
6165 case Match_InvalidZPR64SXTW32:
6166 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6167 case Match_InvalidZPR64UXTW64:
6168 case Match_InvalidZPR64SXTW64:
6169 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6170 case Match_InvalidZPR32LSL8:
6171 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6172 case Match_InvalidZPR32LSL16:
6173 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6174 case Match_InvalidZPR32LSL32:
6175 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6176 case Match_InvalidZPR32LSL64:
6177 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6178 case Match_InvalidZPR64LSL8:
6179 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6180 case Match_InvalidZPR64LSL16:
6181 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6182 case Match_InvalidZPR64LSL32:
6183 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6184 case Match_InvalidZPR64LSL64:
6185 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6186 case Match_InvalidZPR0:
6187 return Error(Loc,
"expected register without element width suffix");
6188 case Match_InvalidZPR8:
6189 case Match_InvalidZPR16:
6190 case Match_InvalidZPR32:
6191 case Match_InvalidZPR64:
6192 case Match_InvalidZPR128:
6193 return Error(Loc,
"invalid element width");
6194 case Match_InvalidZPR_3b8:
6195 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6196 case Match_InvalidZPR_3b16:
6197 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6198 case Match_InvalidZPR_3b32:
6199 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6200 case Match_InvalidZPR_4b8:
6202 "Invalid restricted vector register, expected z0.b..z15.b");
6203 case Match_InvalidZPR_4b16:
6204 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6205 case Match_InvalidZPR_4b32:
6206 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6207 case Match_InvalidZPR_4b64:
6208 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6209 case Match_InvalidZPRMul2_Lo8:
6210 return Error(Loc,
"Invalid restricted vector register, expected even "
6211 "register in z0.b..z14.b");
6212 case Match_InvalidZPRMul2_Hi8:
6213 return Error(Loc,
"Invalid restricted vector register, expected even "
6214 "register in z16.b..z30.b");
6215 case Match_InvalidZPRMul2_Lo16:
6216 return Error(Loc,
"Invalid restricted vector register, expected even "
6217 "register in z0.h..z14.h");
6218 case Match_InvalidZPRMul2_Hi16:
6219 return Error(Loc,
"Invalid restricted vector register, expected even "
6220 "register in z16.h..z30.h");
6221 case Match_InvalidZPRMul2_Lo32:
6222 return Error(Loc,
"Invalid restricted vector register, expected even "
6223 "register in z0.s..z14.s");
6224 case Match_InvalidZPRMul2_Hi32:
6225 return Error(Loc,
"Invalid restricted vector register, expected even "
6226 "register in z16.s..z30.s");
6227 case Match_InvalidZPRMul2_Lo64:
6228 return Error(Loc,
"Invalid restricted vector register, expected even "
6229 "register in z0.d..z14.d");
6230 case Match_InvalidZPRMul2_Hi64:
6231 return Error(Loc,
"Invalid restricted vector register, expected even "
6232 "register in z16.d..z30.d");
6233 case Match_InvalidZPR_K0:
6234 return Error(Loc,
"invalid restricted vector register, expected register "
6235 "in z20..z23 or z28..z31");
6236 case Match_InvalidSVEPattern:
6237 return Error(Loc,
"invalid predicate pattern");
6238 case Match_InvalidSVEPPRorPNRAnyReg:
6239 case Match_InvalidSVEPPRorPNRBReg:
6240 case Match_InvalidSVEPredicateAnyReg:
6241 case Match_InvalidSVEPredicateBReg:
6242 case Match_InvalidSVEPredicateHReg:
6243 case Match_InvalidSVEPredicateSReg:
6244 case Match_InvalidSVEPredicateDReg:
6245 return Error(Loc,
"invalid predicate register.");
6246 case Match_InvalidSVEPredicate3bAnyReg:
6247 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6248 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6249 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6250 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6251 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6252 return Error(Loc,
"Invalid predicate register, expected PN in range "
6253 "pn8..pn15 with element suffix.");
6254 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6255 return Error(Loc,
"invalid restricted predicate-as-counter register "
6256 "expected pn8..pn15");
6257 case Match_InvalidSVEPNPredicateBReg:
6258 case Match_InvalidSVEPNPredicateHReg:
6259 case Match_InvalidSVEPNPredicateSReg:
6260 case Match_InvalidSVEPNPredicateDReg:
6261 return Error(Loc,
"Invalid predicate register, expected PN in range "
6262 "pn0..pn15 with element suffix.");
6263 case Match_InvalidSVEVecLenSpecifier:
6264 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6265 case Match_InvalidSVEPredicateListMul2x8:
6266 case Match_InvalidSVEPredicateListMul2x16:
6267 case Match_InvalidSVEPredicateListMul2x32:
6268 case Match_InvalidSVEPredicateListMul2x64:
6269 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6270 "predicate registers, where the first vector is a multiple of 2 "
6271 "and with correct element type");
6272 case Match_InvalidSVEExactFPImmOperandHalfOne:
6273 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6274 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6275 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6276 case Match_InvalidSVEExactFPImmOperandZeroOne:
6277 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6278 case Match_InvalidMatrixTileVectorH8:
6279 case Match_InvalidMatrixTileVectorV8:
6280 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6281 case Match_InvalidMatrixTileVectorH16:
6282 case Match_InvalidMatrixTileVectorV16:
6284 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6285 case Match_InvalidMatrixTileVectorH32:
6286 case Match_InvalidMatrixTileVectorV32:
6288 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6289 case Match_InvalidMatrixTileVectorH64:
6290 case Match_InvalidMatrixTileVectorV64:
6292 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6293 case Match_InvalidMatrixTileVectorH128:
6294 case Match_InvalidMatrixTileVectorV128:
6296 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6297 case Match_InvalidMatrixTile16:
6298 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6299 case Match_InvalidMatrixTile32:
6300 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6301 case Match_InvalidMatrixTile64:
6302 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6303 case Match_InvalidMatrix:
6304 return Error(Loc,
"invalid matrix operand, expected za");
6305 case Match_InvalidMatrix8:
6306 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6307 case Match_InvalidMatrix16:
6308 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6309 case Match_InvalidMatrix32:
6310 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6311 case Match_InvalidMatrix64:
6312 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6313 case Match_InvalidMatrixIndexGPR32_12_15:
6314 return Error(Loc,
"operand must be a register in range [w12, w15]");
6315 case Match_InvalidMatrixIndexGPR32_8_11:
6316 return Error(Loc,
"operand must be a register in range [w8, w11]");
6317 case Match_InvalidSVEVectorList2x8Mul2:
6318 case Match_InvalidSVEVectorList2x16Mul2:
6319 case Match_InvalidSVEVectorList2x32Mul2:
6320 case Match_InvalidSVEVectorList2x64Mul2:
6321 case Match_InvalidSVEVectorList2x128Mul2:
6322 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6323 "SVE vectors, where the first vector is a multiple of 2 "
6324 "and with matching element types");
6325 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6326 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6327 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6328 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6329 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6330 "SVE vectors in the range z0-z14, where the first vector "
6331 "is a multiple of 2 "
6332 "and with matching element types");
6333 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6334 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6335 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6336 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6338 "Invalid vector list, expected list with 2 consecutive "
6339 "SVE vectors in the range z16-z30, where the first vector "
6340 "is a multiple of 2 "
6341 "and with matching element types");
6342 case Match_InvalidSVEVectorList4x8Mul4:
6343 case Match_InvalidSVEVectorList4x16Mul4:
6344 case Match_InvalidSVEVectorList4x32Mul4:
6345 case Match_InvalidSVEVectorList4x64Mul4:
6346 case Match_InvalidSVEVectorList4x128Mul4:
6347 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6348 "SVE vectors, where the first vector is a multiple of 4 "
6349 "and with matching element types");
6350 case Match_InvalidLookupTable:
6351 return Error(Loc,
"Invalid lookup table, expected zt0");
6352 case Match_InvalidSVEVectorListStrided2x8:
6353 case Match_InvalidSVEVectorListStrided2x16:
6354 case Match_InvalidSVEVectorListStrided2x32:
6355 case Match_InvalidSVEVectorListStrided2x64:
6358 "Invalid vector list, expected list with each SVE vector in the list "
6359 "8 registers apart, and the first register in the range [z0, z7] or "
6360 "[z16, z23] and with correct element type");
6361 case Match_InvalidSVEVectorListStrided4x8:
6362 case Match_InvalidSVEVectorListStrided4x16:
6363 case Match_InvalidSVEVectorListStrided4x32:
6364 case Match_InvalidSVEVectorListStrided4x64:
6367 "Invalid vector list, expected list with each SVE vector in the list "
6368 "4 registers apart, and the first register in the range [z0, z3] or "
6369 "[z16, z19] and with correct element type");
6370 case Match_AddSubLSLImm3ShiftLarge:
6372 "expected 'lsl' with optional integer in range [0, 7]");
6380bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6384 bool MatchingInlineAsm) {
6386 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6387 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6390 unsigned NumOperands =
Operands.size();
6392 if (NumOperands == 4 && Tok ==
"lsl") {
6393 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6394 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6395 if (Op2.isScalarReg() && Op3.isImm()) {
6396 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6401 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6403 NewOp3Val = (32 - Op3Val) & 0x1f;
6404 NewOp4Val = 31 - Op3Val;
6406 NewOp3Val = (64 - Op3Val) & 0x3f;
6407 NewOp4Val = 63 - Op3Val;
6414 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6415 Operands.push_back(AArch64Operand::CreateImm(
6416 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6417 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6418 Op3.getEndLoc(), getContext());
6421 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6423 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6424 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6425 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6427 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6428 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6429 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6431 if (LSBCE && WidthCE) {
6436 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6442 if (LSB >= RegWidth)
6443 return Error(LSBOp.getStartLoc(),
6444 "expected integer in range [0, 31]");
6445 if (Width < 1 || Width > RegWidth)
6446 return Error(WidthOp.getStartLoc(),
6447 "expected integer in range [1, 32]");
6451 ImmR = (32 - LSB) & 0x1f;
6453 ImmR = (64 - LSB) & 0x3f;
6457 if (ImmR != 0 && ImmS >= ImmR)
6458 return Error(WidthOp.getStartLoc(),
6459 "requested insert overflows register");
6464 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6465 Operands[2] = AArch64Operand::CreateReg(
6466 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6468 Operands[3] = AArch64Operand::CreateImm(
6469 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6471 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6472 WidthOp.getEndLoc(), getContext()));
6475 }
else if (NumOperands == 5) {
6478 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6479 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6480 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6481 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6483 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6484 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6485 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6487 if (Op3CE && Op4CE) {
6492 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6498 if (Op3Val >= RegWidth)
6499 return Error(Op3.getStartLoc(),
6500 "expected integer in range [0, 31]");
6501 if (Op4Val < 1 || Op4Val > RegWidth)
6502 return Error(Op4.getStartLoc(),
6503 "expected integer in range [1, 32]");
6507 NewOp3Val = (32 - Op3Val) & 0x1f;
6509 NewOp3Val = (64 - Op3Val) & 0x3f;
6513 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6514 return Error(Op4.getStartLoc(),
6515 "requested insert overflows register");
6521 Operands[3] = AArch64Operand::CreateImm(
6522 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6523 Operands[4] = AArch64Operand::CreateImm(
6524 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6526 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6528 else if (Tok ==
"sbfiz")
6529 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6531 else if (Tok ==
"ubfiz")
6532 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6541 }
else if (NumOperands == 5 &&
6542 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6543 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6544 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6545 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6547 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6548 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6549 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6551 if (Op3CE && Op4CE) {
6556 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6562 if (Op3Val >= RegWidth)
6563 return Error(Op3.getStartLoc(),
6564 "expected integer in range [0, 31]");
6565 if (Op4Val < 1 || Op4Val > RegWidth)
6566 return Error(Op4.getStartLoc(),
6567 "expected integer in range [1, 32]");
6569 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6571 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6572 return Error(Op4.getStartLoc(),
6573 "requested extract overflows register");
6577 Operands[4] = AArch64Operand::CreateImm(
6578 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6580 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6582 else if (Tok ==
"sbfx")
6583 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6585 else if (Tok ==
"ubfx")
6586 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6599 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6600 NumOperands == 4 && Tok ==
"movi") {
6601 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6602 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6603 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6604 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6605 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6606 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6607 if (Suffix.
lower() ==
".2d" &&
6608 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6609 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6610 " correctly on this CPU, converting to equivalent movi.16b");
6612 unsigned Idx = Op1.isToken() ? 1 : 2;
6614 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6622 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6625 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6626 if (
Op.isScalarReg()) {
6628 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6629 Op.getStartLoc(),
Op.getEndLoc(),
6634 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6635 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6636 if (
Op.isScalarReg() &&
6637 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6641 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6642 if (
Op.isScalarReg()) {
6644 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6646 Op.getEndLoc(), getContext());
6651 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6652 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6653 if (
Op.isScalarReg() &&
6654 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6658 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6659 if (
Op.isScalarReg()) {
6661 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6663 Op.getEndLoc(), getContext());
6672 unsigned MatchResult =
6674 MatchingInlineAsm, 1);
6678 if (MatchResult != Match_Success) {
6681 auto ShortFormNEONErrorInfo =
ErrorInfo;
6682 auto ShortFormNEONMatchResult = MatchResult;
6683 auto ShortFormNEONMissingFeatures = MissingFeatures;
6687 MatchingInlineAsm, 0);
6692 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6694 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6695 MatchResult = ShortFormNEONMatchResult;
6697 MissingFeatures = ShortFormNEONMissingFeatures;
6701 switch (MatchResult) {
6702 case Match_Success: {
6706 for (
unsigned i = 1; i < NumOperands; ++i)
6708 if (validateInstruction(Inst, IDLoc, OperandLocs))
6715 case Match_MissingFeature: {
6716 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6719 std::string Msg =
"instruction requires:";
6720 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6721 if (MissingFeatures[i]) {
6726 return Error(IDLoc, Msg);
6728 case Match_MnemonicFail:
6730 case Match_InvalidOperand: {
6731 SMLoc ErrorLoc = IDLoc;
6735 return Error(IDLoc,
"too few operands for instruction",
6736 SMRange(IDLoc, getTok().getLoc()));
6739 if (ErrorLoc ==
SMLoc())
6746 MatchResult = Match_InvalidSuffix;
6750 case Match_InvalidTiedOperand:
6751 case Match_InvalidMemoryIndexed1:
6752 case Match_InvalidMemoryIndexed2:
6753 case Match_InvalidMemoryIndexed4:
6754 case Match_InvalidMemoryIndexed8:
6755 case Match_InvalidMemoryIndexed16:
6756 case Match_InvalidCondCode:
6757 case Match_AddSubLSLImm3ShiftLarge:
6758 case Match_AddSubRegExtendSmall:
6759 case Match_AddSubRegExtendLarge:
6760 case Match_AddSubSecondSource:
6761 case Match_LogicalSecondSource:
6762 case Match_AddSubRegShift32:
6763 case Match_AddSubRegShift64:
6764 case Match_InvalidMovImm32Shift:
6765 case Match_InvalidMovImm64Shift:
6766 case Match_InvalidFPImm:
6767 case Match_InvalidMemoryWExtend8:
6768 case Match_InvalidMemoryWExtend16:
6769 case Match_InvalidMemoryWExtend32:
6770 case Match_InvalidMemoryWExtend64:
6771 case Match_InvalidMemoryWExtend128:
6772 case Match_InvalidMemoryXExtend8:
6773 case Match_InvalidMemoryXExtend16:
6774 case Match_InvalidMemoryXExtend32:
6775 case Match_InvalidMemoryXExtend64:
6776 case Match_InvalidMemoryXExtend128:
6777 case Match_InvalidMemoryIndexed1SImm4:
6778 case Match_InvalidMemoryIndexed2SImm4:
6779 case Match_InvalidMemoryIndexed3SImm4:
6780 case Match_InvalidMemoryIndexed4SImm4:
6781 case Match_InvalidMemoryIndexed1SImm6:
6782 case Match_InvalidMemoryIndexed16SImm4:
6783 case Match_InvalidMemoryIndexed32SImm4:
6784 case Match_InvalidMemoryIndexed4SImm7:
6785 case Match_InvalidMemoryIndexed8SImm7:
6786 case Match_InvalidMemoryIndexed16SImm7:
6787 case Match_InvalidMemoryIndexed8UImm5:
6788 case Match_InvalidMemoryIndexed8UImm3:
6789 case Match_InvalidMemoryIndexed4UImm5:
6790 case Match_InvalidMemoryIndexed2UImm5:
6791 case Match_InvalidMemoryIndexed1UImm6:
6792 case Match_InvalidMemoryIndexed2UImm6:
6793 case Match_InvalidMemoryIndexed4UImm6:
6794 case Match_InvalidMemoryIndexed8UImm6:
6795 case Match_InvalidMemoryIndexed16UImm6:
6796 case Match_InvalidMemoryIndexedSImm6:
6797 case Match_InvalidMemoryIndexedSImm5:
6798 case Match_InvalidMemoryIndexedSImm8:
6799 case Match_InvalidMemoryIndexedSImm9:
6800 case Match_InvalidMemoryIndexed16SImm9:
6801 case Match_InvalidMemoryIndexed8SImm10:
6802 case Match_InvalidImm0_0:
6803 case Match_InvalidImm0_1:
6804 case Match_InvalidImm0_3:
6805 case Match_InvalidImm0_7:
6806 case Match_InvalidImm0_15:
6807 case Match_InvalidImm0_31:
6808 case Match_InvalidImm0_63:
6809 case Match_InvalidImm0_127:
6810 case Match_InvalidImm0_255:
6811 case Match_InvalidImm0_65535:
6812 case Match_InvalidImm1_8:
6813 case Match_InvalidImm1_16:
6814 case Match_InvalidImm1_32:
6815 case Match_InvalidImm1_64:
6816 case Match_InvalidImmM1_62:
6817 case Match_InvalidMemoryIndexedRange2UImm0:
6818 case Match_InvalidMemoryIndexedRange2UImm1:
6819 case Match_InvalidMemoryIndexedRange2UImm2:
6820 case Match_InvalidMemoryIndexedRange2UImm3:
6821 case Match_InvalidMemoryIndexedRange4UImm0:
6822 case Match_InvalidMemoryIndexedRange4UImm1:
6823 case Match_InvalidMemoryIndexedRange4UImm2:
6824 case Match_InvalidSVEAddSubImm8:
6825 case Match_InvalidSVEAddSubImm16:
6826 case Match_InvalidSVEAddSubImm32:
6827 case Match_InvalidSVEAddSubImm64:
6828 case Match_InvalidSVECpyImm8:
6829 case Match_InvalidSVECpyImm16:
6830 case Match_InvalidSVECpyImm32:
6831 case Match_InvalidSVECpyImm64:
6832 case Match_InvalidIndexRange0_0:
6833 case Match_InvalidIndexRange1_1:
6834 case Match_InvalidIndexRange0_15:
6835 case Match_InvalidIndexRange0_7:
6836 case Match_InvalidIndexRange0_3:
6837 case Match_InvalidIndexRange0_1:
6838 case Match_InvalidSVEIndexRange0_63:
6839 case Match_InvalidSVEIndexRange0_31:
6840 case Match_InvalidSVEIndexRange0_15:
6841 case Match_InvalidSVEIndexRange0_7:
6842 case Match_InvalidSVEIndexRange0_3:
6843 case Match_InvalidLabel:
6844 case Match_InvalidComplexRotationEven:
6845 case Match_InvalidComplexRotationOdd:
6846 case Match_InvalidGPR64shifted8:
6847 case Match_InvalidGPR64shifted16:
6848 case Match_InvalidGPR64shifted32:
6849 case Match_InvalidGPR64shifted64:
6850 case Match_InvalidGPR64shifted128:
6851 case Match_InvalidGPR64NoXZRshifted8:
6852 case Match_InvalidGPR64NoXZRshifted16:
6853 case Match_InvalidGPR64NoXZRshifted32:
6854 case Match_InvalidGPR64NoXZRshifted64:
6855 case Match_InvalidGPR64NoXZRshifted128:
6856 case Match_InvalidZPR32UXTW8:
6857 case Match_InvalidZPR32UXTW16:
6858 case Match_InvalidZPR32UXTW32:
6859 case Match_InvalidZPR32UXTW64:
6860 case Match_InvalidZPR32SXTW8:
6861 case Match_InvalidZPR32SXTW16:
6862 case Match_InvalidZPR32SXTW32:
6863 case Match_InvalidZPR32SXTW64:
6864 case Match_InvalidZPR64UXTW8:
6865 case Match_InvalidZPR64SXTW8:
6866 case Match_InvalidZPR64UXTW16:
6867 case Match_InvalidZPR64SXTW16:
6868 case Match_InvalidZPR64UXTW32:
6869 case Match_InvalidZPR64SXTW32:
6870 case Match_InvalidZPR64UXTW64:
6871 case Match_InvalidZPR64SXTW64:
6872 case Match_InvalidZPR32LSL8:
6873 case Match_InvalidZPR32LSL16:
6874 case Match_InvalidZPR32LSL32:
6875 case Match_InvalidZPR32LSL64:
6876 case Match_InvalidZPR64LSL8:
6877 case Match_InvalidZPR64LSL16:
6878 case Match_InvalidZPR64LSL32:
6879 case Match_InvalidZPR64LSL64:
6880 case Match_InvalidZPR0:
6881 case Match_InvalidZPR8:
6882 case Match_InvalidZPR16:
6883 case Match_InvalidZPR32:
6884 case Match_InvalidZPR64:
6885 case Match_InvalidZPR128:
6886 case Match_InvalidZPR_3b8:
6887 case Match_InvalidZPR_3b16:
6888 case Match_InvalidZPR_3b32:
6889 case Match_InvalidZPR_4b8:
6890 case Match_InvalidZPR_4b16:
6891 case Match_InvalidZPR_4b32:
6892 case Match_InvalidZPR_4b64:
6893 case Match_InvalidSVEPPRorPNRAnyReg:
6894 case Match_InvalidSVEPPRorPNRBReg:
6895 case Match_InvalidSVEPredicateAnyReg:
6896 case Match_InvalidSVEPattern:
6897 case Match_InvalidSVEVecLenSpecifier:
6898 case Match_InvalidSVEPredicateBReg:
6899 case Match_InvalidSVEPredicateHReg:
6900 case Match_InvalidSVEPredicateSReg:
6901 case Match_InvalidSVEPredicateDReg:
6902 case Match_InvalidSVEPredicate3bAnyReg:
6903 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6904 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6905 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6906 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6907 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6908 case Match_InvalidSVEPNPredicateBReg:
6909 case Match_InvalidSVEPNPredicateHReg:
6910 case Match_InvalidSVEPNPredicateSReg:
6911 case Match_InvalidSVEPNPredicateDReg:
6912 case Match_InvalidSVEPredicateListMul2x8:
6913 case Match_InvalidSVEPredicateListMul2x16:
6914 case Match_InvalidSVEPredicateListMul2x32:
6915 case Match_InvalidSVEPredicateListMul2x64:
6916 case Match_InvalidSVEExactFPImmOperandHalfOne:
6917 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6918 case Match_InvalidSVEExactFPImmOperandZeroOne:
6919 case Match_InvalidMatrixTile16:
6920 case Match_InvalidMatrixTile32:
6921 case Match_InvalidMatrixTile64:
6922 case Match_InvalidMatrix:
6923 case Match_InvalidMatrix8:
6924 case Match_InvalidMatrix16:
6925 case Match_InvalidMatrix32:
6926 case Match_InvalidMatrix64:
6927 case Match_InvalidMatrixTileVectorH8:
6928 case Match_InvalidMatrixTileVectorH16:
6929 case Match_InvalidMatrixTileVectorH32:
6930 case Match_InvalidMatrixTileVectorH64:
6931 case Match_InvalidMatrixTileVectorH128:
6932 case Match_InvalidMatrixTileVectorV8:
6933 case Match_InvalidMatrixTileVectorV16:
6934 case Match_InvalidMatrixTileVectorV32:
6935 case Match_InvalidMatrixTileVectorV64:
6936 case Match_InvalidMatrixTileVectorV128:
6937 case Match_InvalidSVCR:
6938 case Match_InvalidMatrixIndexGPR32_12_15:
6939 case Match_InvalidMatrixIndexGPR32_8_11:
6940 case Match_InvalidLookupTable:
6941 case Match_InvalidZPRMul2_Lo8:
6942 case Match_InvalidZPRMul2_Hi8:
6943 case Match_InvalidZPRMul2_Lo16:
6944 case Match_InvalidZPRMul2_Hi16:
6945 case Match_InvalidZPRMul2_Lo32:
6946 case Match_InvalidZPRMul2_Hi32:
6947 case Match_InvalidZPRMul2_Lo64:
6948 case Match_InvalidZPRMul2_Hi64:
6949 case Match_InvalidZPR_K0:
6950 case Match_InvalidSVEVectorList2x8Mul2:
6951 case Match_InvalidSVEVectorList2x16Mul2:
6952 case Match_InvalidSVEVectorList2x32Mul2:
6953 case Match_InvalidSVEVectorList2x64Mul2:
6954 case Match_InvalidSVEVectorList2x128Mul2:
6955 case Match_InvalidSVEVectorList4x8Mul4:
6956 case Match_InvalidSVEVectorList4x16Mul4:
6957 case Match_InvalidSVEVectorList4x32Mul4:
6958 case Match_InvalidSVEVectorList4x64Mul4:
6959 case Match_InvalidSVEVectorList4x128Mul4:
6960 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6961 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6962 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6963 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6964 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6965 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6966 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6967 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6968 case Match_InvalidSVEVectorListStrided2x8:
6969 case Match_InvalidSVEVectorListStrided2x16:
6970 case Match_InvalidSVEVectorListStrided2x32:
6971 case Match_InvalidSVEVectorListStrided2x64:
6972 case Match_InvalidSVEVectorListStrided4x8:
6973 case Match_InvalidSVEVectorListStrided4x16:
6974 case Match_InvalidSVEVectorListStrided4x32:
6975 case Match_InvalidSVEVectorListStrided4x64:
6979 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6983 if (ErrorLoc ==
SMLoc())
6993bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
7001 if (IDVal ==
".arch")
7002 parseDirectiveArch(Loc);
7003 else if (IDVal ==
".cpu")
7004 parseDirectiveCPU(Loc);
7005 else if (IDVal ==
".tlsdesccall")
7006 parseDirectiveTLSDescCall(Loc);
7007 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7008 parseDirectiveLtorg(Loc);
7009 else if (IDVal ==
".unreq")
7010 parseDirectiveUnreq(Loc);
7011 else if (IDVal ==
".inst")
7012 parseDirectiveInst(Loc);
7013 else if (IDVal ==
".cfi_negate_ra_state")
7014 parseDirectiveCFINegateRAState();
7015 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7016 parseDirectiveCFINegateRAStateWithPC();
7017 else if (IDVal ==
".cfi_b_key_frame")
7018 parseDirectiveCFIBKeyFrame();
7019 else if (IDVal ==
".cfi_mte_tagged_frame")
7020 parseDirectiveCFIMTETaggedFrame();
7021 else if (IDVal ==
".arch_extension")
7022 parseDirectiveArchExtension(Loc);
7023 else if (IDVal ==
".variant_pcs")
7024 parseDirectiveVariantPCS(Loc);
7027 parseDirectiveLOH(IDVal, Loc);
7030 }
else if (IsCOFF) {
7031 if (IDVal ==
".seh_stackalloc")
7032 parseDirectiveSEHAllocStack(Loc);
7033 else if (IDVal ==
".seh_endprologue")
7034 parseDirectiveSEHPrologEnd(Loc);
7035 else if (IDVal ==
".seh_save_r19r20_x")
7036 parseDirectiveSEHSaveR19R20X(Loc);
7037 else if (IDVal ==
".seh_save_fplr")
7038 parseDirectiveSEHSaveFPLR(Loc);
7039 else if (IDVal ==
".seh_save_fplr_x")
7040 parseDirectiveSEHSaveFPLRX(Loc);
7041 else if (IDVal ==
".seh_save_reg")
7042 parseDirectiveSEHSaveReg(Loc);
7043 else if (IDVal ==
".seh_save_reg_x")
7044 parseDirectiveSEHSaveRegX(Loc);
7045 else if (IDVal ==
".seh_save_regp")
7046 parseDirectiveSEHSaveRegP(Loc);
7047 else if (IDVal ==
".seh_save_regp_x")
7048 parseDirectiveSEHSaveRegPX(Loc);
7049 else if (IDVal ==
".seh_save_lrpair")
7050 parseDirectiveSEHSaveLRPair(Loc);
7051 else if (IDVal ==
".seh_save_freg")
7052 parseDirectiveSEHSaveFReg(Loc);
7053 else if (IDVal ==
".seh_save_freg_x")
7054 parseDirectiveSEHSaveFRegX(Loc);
7055 else if (IDVal ==
".seh_save_fregp")
7056 parseDirectiveSEHSaveFRegP(Loc);
7057 else if (IDVal ==
".seh_save_fregp_x")
7058 parseDirectiveSEHSaveFRegPX(Loc);
7059 else if (IDVal ==
".seh_set_fp")
7060 parseDirectiveSEHSetFP(Loc);
7061 else if (IDVal ==
".seh_add_fp")
7062 parseDirectiveSEHAddFP(Loc);
7063 else if (IDVal ==
".seh_nop")
7064 parseDirectiveSEHNop(Loc);
7065 else if (IDVal ==
".seh_save_next")
7066 parseDirectiveSEHSaveNext(Loc);
7067 else if (IDVal ==
".seh_startepilogue")
7068 parseDirectiveSEHEpilogStart(Loc);
7069 else if (IDVal ==
".seh_endepilogue")
7070 parseDirectiveSEHEpilogEnd(Loc);
7071 else if (IDVal ==
".seh_trap_frame")
7072 parseDirectiveSEHTrapFrame(Loc);
7073 else if (IDVal ==
".seh_pushframe")
7074 parseDirectiveSEHMachineFrame(Loc);
7075 else if (IDVal ==
".seh_context")
7076 parseDirectiveSEHContext(Loc);
7077 else if (IDVal ==
".seh_ec_context")
7078 parseDirectiveSEHECContext(Loc);
7079 else if (IDVal ==
".seh_clear_unwound_to_call")
7080 parseDirectiveSEHClearUnwoundToCall(Loc);
7081 else if (IDVal ==
".seh_pac_sign_lr")
7082 parseDirectiveSEHPACSignLR(Loc);
7083 else if (IDVal ==
".seh_save_any_reg")
7084 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7085 else if (IDVal ==
".seh_save_any_reg_p")
7086 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7087 else if (IDVal ==
".seh_save_any_reg_x")
7088 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7089 else if (IDVal ==
".seh_save_any_reg_px")
7090 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7094 if (IDVal ==
".aeabi_subsection")
7095 parseDirectiveAeabiSubSectionHeader(Loc);
7096 else if (IDVal ==
".aeabi_attribute")
7097 parseDirectiveAeabiAArch64Attr(Loc);
7110 if (!NoCrypto && Crypto) {
7113 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7114 ArchInfo == AArch64::ARMV8_3A) {
7118 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7119 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7120 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7121 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7122 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7123 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7129 }
else if (NoCrypto) {
7132 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7133 ArchInfo == AArch64::ARMV8_3A) {
7134 RequestedExtensions.
push_back(
"nosha2");
7137 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7138 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7139 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7140 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7141 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7142 ArchInfo == AArch64::ARMV9_4A) {
7144 RequestedExtensions.
push_back(
"nosha3");
7145 RequestedExtensions.
push_back(
"nosha2");
7157bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
7158 SMLoc CurLoc = getLoc();
7161 std::tie(Arch, ExtensionString) =
7162 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7166 return Error(CurLoc,
"unknown arch name");
7172 std::vector<StringRef> AArch64Features;
7177 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7179 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7182 if (!ExtensionString.
empty())
7183 ExtensionString.
split(RequestedExtensions,
'+');
7188 for (
auto Name : RequestedExtensions) {
7192 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7199 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7208 setAvailableFeatures(Features);
7214bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7215 SMLoc ExtLoc = getLoc();
7217 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7222 bool EnableFeature =
true;
7223 if (
Name.starts_with_insensitive(
"no")) {
7224 EnableFeature =
false;
7233 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7241 setAvailableFeatures(Features);
7247bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7248 SMLoc CurLoc = getLoc();
7251 std::tie(CPU, ExtensionString) =
7252 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7258 if (!ExtensionString.
empty())
7259 ExtensionString.
split(RequestedExtensions,
'+');
7263 Error(CurLoc,
"unknown CPU name");
7272 for (
auto Name : RequestedExtensions) {
7276 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7283 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7292 setAvailableFeatures(Features);
7298bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7300 return Error(Loc,
"expected expression following '.inst' directive");
7302 auto parseOp = [&]() ->
bool {
7304 const MCExpr *Expr =
nullptr;
7305 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7308 if (check(!
Value, L,
"expected constant expression"))
7310 getTargetStreamer().emitInst(
Value->getValue());
7314 return parseMany(parseOp);
7319bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7321 if (check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7333 getParser().getStreamer().emitInstruction(Inst, getSTI());
7339bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7343 return TokError(
"expected an identifier or a number in directive");
7346 int64_t
Id = getTok().getIntVal();
7348 return TokError(
"invalid numeric identifier in directive");
7357 return TokError(
"invalid identifier in directive");
7365 assert(NbArgs != -1 &&
"Invalid number of arguments");
7368 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7370 if (getParser().parseIdentifier(
Name))
7371 return TokError(
"expected identifier in directive");
7372 Args.push_back(getContext().getOrCreateSymbol(
Name));
7374 if (
Idx + 1 == NbArgs)
7382 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7388bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7391 getTargetStreamer().emitCurrentConstantPool();
7399 SMLoc SRegLoc = getLoc();
7400 RegKind RegisterKind = RegKind::Scalar;
7402 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7406 RegisterKind = RegKind::NeonVector;
7407 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7413 return Error(SRegLoc,
"vector register without type specifier expected");
7418 RegisterKind = RegKind::SVEDataVector;
7420 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7426 return Error(SRegLoc,
7427 "sve vector register without type specifier expected");
7432 RegisterKind = RegKind::SVEPredicateVector;
7433 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7439 return Error(SRegLoc,
7440 "sve predicate register without type specifier expected");
7444 return Error(SRegLoc,
"register name or alias expected");
7450 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7451 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7452 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7459bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7461 return TokError(
"unexpected input in .unreq directive.");
7462 RegisterReqs.
erase(getTok().getIdentifier().lower());
7467bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7470 getStreamer().emitCFINegateRAState();
7474bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7477 getStreamer().emitCFINegateRAStateWithPC();
7483bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7486 getStreamer().emitCFIBKeyFrame();
7492bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7495 getStreamer().emitCFIMTETaggedFrame();
7501bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7503 if (getParser().parseIdentifier(
Name))
7504 return TokError(
"expected symbol name");
7507 getTargetStreamer().emitDirectiveVariantPCS(
7508 getContext().getOrCreateSymbol(
Name));
7514bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7516 if (parseImmExpr(
Size))
7518 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7524bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7525 getTargetStreamer().emitARM64WinCFIPrologEnd();
7531bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7533 if (parseImmExpr(
Offset))
7535 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7541bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7543 if (parseImmExpr(
Offset))
7545 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7551bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7553 if (parseImmExpr(
Offset))
7555 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7561bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7564 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7565 parseComma() || parseImmExpr(
Offset))
7567 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7573bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7576 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7577 parseComma() || parseImmExpr(
Offset))
7579 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7585bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7588 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7589 parseComma() || parseImmExpr(
Offset))
7591 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7597bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7600 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7601 parseComma() || parseImmExpr(
Offset))
7603 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7609bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7613 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7614 parseComma() || parseImmExpr(
Offset))
7616 if (check(((Reg - 19) % 2 != 0), L,
7617 "expected register with even offset from x19"))
7619 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7625bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7628 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7629 parseComma() || parseImmExpr(
Offset))
7631 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7637bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7640 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7641 parseComma() || parseImmExpr(
Offset))
7643 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7649bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7652 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7653 parseComma() || parseImmExpr(
Offset))
7655 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7661bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7664 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7665 parseComma() || parseImmExpr(
Offset))
7667 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7673bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7674 getTargetStreamer().emitARM64WinCFISetFP();
7680bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7682 if (parseImmExpr(
Size))
7684 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7690bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7691 getTargetStreamer().emitARM64WinCFINop();
7697bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7698 getTargetStreamer().emitARM64WinCFISaveNext();
7704bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7705 getTargetStreamer().emitARM64WinCFIEpilogStart();
7711bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7712 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7718bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7719 getTargetStreamer().emitARM64WinCFITrapFrame();
7725bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7726 getTargetStreamer().emitARM64WinCFIMachineFrame();
7732bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7733 getTargetStreamer().emitARM64WinCFIContext();
7739bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7740 getTargetStreamer().emitARM64WinCFIECContext();
7746bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7747 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7753bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7754 getTargetStreamer().emitARM64WinCFIPACSignLR();
7763bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7768 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7769 parseComma() || parseImmExpr(
Offset))
7772 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7773 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7774 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7775 return Error(L,
"invalid save_any_reg offset");
7776 unsigned EncodedReg;
7777 if (Reg == AArch64::FP)
7779 else if (Reg == AArch64::LR)
7782 EncodedReg =
Reg - AArch64::X0;
7784 if (Reg == AArch64::LR)
7785 return Error(Start,
"lr cannot be paired with another register");
7787 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7789 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7792 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7794 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7796 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7797 unsigned EncodedReg =
Reg - AArch64::D0;
7798 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7799 return Error(L,
"invalid save_any_reg offset");
7801 if (Reg == AArch64::D31)
7802 return Error(Start,
"d31 cannot be paired with another register");
7804 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7806 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7809 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7811 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7813 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7814 unsigned EncodedReg =
Reg - AArch64::Q0;
7816 return Error(L,
"invalid save_any_reg offset");
7818 if (Reg == AArch64::Q31)
7819 return Error(Start,
"q31 cannot be paired with another register");
7821 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7823 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7826 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7828 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7831 return Error(Start,
"save_any_reg register must be x, q or d register");
7836bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(
SMLoc L) {
7860 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
7861 getTargetStreamer().getAtributesSubsectionByName(SubsectionName);
7875 if (SubsectionExists) {
7876 if (IsOptional != SubsectionExists->IsOptional) {
7878 "optionality mismatch! subsection '" + SubsectionName +
7879 "' already exists with optionality defined as '" +
7881 SubsectionExists->IsOptional) +
7889 "optionality parameter not found, expected required|optional");
7896 "aeabi_feature_and_bits must be marked as optional");
7903 "aeabi_pauthabi must be marked as required");
7924 if (SubsectionExists) {
7925 if (
Type != SubsectionExists->ParameterType) {
7927 "type mismatch! subsection '" + SubsectionName +
7928 "' already exists with type defined as '" +
7930 SubsectionExists->ParameterType) +
7938 "type parameter not found, expected uleb128|ntbs");
7946 SubsectionName +
" must be marked as ULEB128");
7954 "attributes subsection header directive");
7958 getTargetStreamer().emitAtributesSubsection(SubsectionName, IsOptional,
Type);
7963bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(
SMLoc L) {
7969 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
7970 getTargetStreamer().getActiveAtributesSubsection();
7971 if (
nullptr == ActiveSubsection) {
7973 "no active subsection, build attribute can not be added");
7976 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
7977 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
7985 ActiveSubsectionName)
7992 switch (ActiveSubsectionID) {
7994 assert(0 &&
"Subsection name error");
8003 TagStr +
"' for subsection '" +
8004 ActiveSubsectionName +
"'");
8012 TagStr +
"' for subsection '" +
8013 ActiveSubsectionName +
"'");
8019 Tag = getTok().getIntVal();
8034 std::string ValueStr =
"";
8039 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8042 ValueInt = getTok().getIntVal();
8047 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8055 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8067 if (0 != ValueInt && 1 != ValueInt) {
8069 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8070 "' options are 0|1");
8078 "unexpected token for AArch64 build attributes tag and value "
8079 "attribute directive");
8083 if (
unsigned(-1) != ValueInt) {
8084 getTargetStreamer().emitAttribute(ActiveSubsectionName, Tag, ValueInt,
"",
8088 if (
"" != ValueStr) {
8089 getTargetStreamer().emitAttribute(ActiveSubsectionName, Tag,
unsigned(-1),
8095bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8097 if (!parseAuthExpr(Res, EndLoc))
8099 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8106bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8117 "combination of @AUTH with other modifiers not supported");
8140 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
8162 return TokError(
"expected key name");
8167 return TokError(
"invalid key '" + KeyStr +
"'");
8174 return TokError(
"expected integer discriminator");
8177 if (!isUInt<16>(Discriminator))
8178 return TokError(
"integer discriminator " +
Twine(Discriminator) +
8179 " out of range [0, 0xFFFF]");
8182 bool UseAddressDiversity =
false;
8187 return TokError(
"expected 'addr'");
8188 UseAddressDiversity =
true;
8197 UseAddressDiversity, Ctx);
8202AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8210 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
8211 ELFRefKind = AE->getKind();
8212 Expr = AE->getSubExpr();
8218 DarwinRefKind = SE->
getKind();
8225 if (!Relocatable || Res.
getSymB())
8252#define GET_REGISTER_MATCHER
8253#define GET_SUBTARGET_FEATURE_NAME
8254#define GET_MATCHER_IMPLEMENTATION
8255#define GET_MNEMONIC_SPELL_CHECKER
8256#include "AArch64GenAsmMatcher.inc"
8262 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8264 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8266 return Match_InvalidOperand;
8269 return Match_InvalidOperand;
8270 if (CE->getValue() == ExpectedVal)
8271 return Match_Success;
8272 return Match_InvalidOperand;
8277 return Match_InvalidOperand;
8283 if (
Op.isTokenEqual(
"za"))
8284 return Match_Success;
8285 return Match_InvalidOperand;
8291#define MATCH_HASH(N) \
8292 case MCK__HASH_##N: \
8293 return MatchesOpImmediate(N);
8319#define MATCH_HASH_MINUS(N) \
8320 case MCK__HASH__MINUS_##N: \
8321 return MatchesOpImmediate(-N);
8325#undef MATCH_HASH_MINUS
8334 return Error(S,
"expected register");
8337 ParseStatus Res = tryParseScalarRegister(FirstReg);
8339 return Error(S,
"expected first even register of a consecutive same-size "
8340 "even/odd register pair");
8343 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8345 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8347 bool isXReg = XRegClass.
contains(FirstReg),
8348 isWReg = WRegClass.
contains(FirstReg);
8349 if (!isXReg && !isWReg)
8350 return Error(S,
"expected first even register of a consecutive same-size "
8351 "even/odd register pair");
8356 if (FirstEncoding & 0x1)
8357 return Error(S,
"expected first even register of a consecutive same-size "
8358 "even/odd register pair");
8361 return Error(getLoc(),
"expected comma");
8367 Res = tryParseScalarRegister(SecondReg);
8369 return Error(E,
"expected second odd register of a consecutive same-size "
8370 "even/odd register pair");
8373 (isXReg && !XRegClass.
contains(SecondReg)) ||
8374 (isWReg && !WRegClass.
contains(SecondReg)))
8375 return Error(E,
"expected second odd register of a consecutive same-size "
8376 "even/odd register pair");
8381 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8384 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8387 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8388 getLoc(), getContext()));
8393template <
bool ParseShiftExtend,
bool ParseSuffix>
8395 const SMLoc S = getLoc();
8401 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8406 if (ParseSuffix &&
Kind.empty())
8413 unsigned ElementWidth = KindRes->second;
8417 Operands.push_back(AArch64Operand::CreateVectorReg(
8418 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
8431 Res = tryParseOptionalShiftExtend(ExtOpnd);
8435 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
8436 Operands.push_back(AArch64Operand::CreateVectorReg(
8437 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8438 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
8439 Ext->hasShiftExtendAmount()));
8464 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8466 return TokError(
"invalid operand for instruction");
8471 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8482 SS, getLoc(), getContext()));
8493 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8504 SS, getLoc(), getContext()));
8513 if (!tryParseScalarRegister(XReg).isSuccess())
8519 XReg, AArch64::x8sub_0,
8520 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8523 "expected an even-numbered x-register in the range [x0,x22]");
8526 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8540 if (getParser().parseExpression(ImmF))
8550 SMLoc E = getTok().getLoc();
8552 if (getParser().parseExpression(ImmL))
8555 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8556 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8559 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
8574 if (getParser().parseExpression(Ex))
8577 int64_t
Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
8584 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8591 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