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);
232 bool validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
234 unsigned getNumRegsForRegKind(RegKind K);
238 bool MatchingInlineAsm)
override;
242#define GET_ASSEMBLER_HEADER
243#include "AArch64GenAsmMatcher.inc"
257 template <
bool IsSVEPrefetch = false>
264 template <
bool AddFPZeroAsLiteral>
272 template <
bool ParseShiftExtend,
273 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
276 template <
bool ParseShiftExtend,
bool ParseSuffix>
278 template <RegKind RK>
282 template <RegKind VectorKind>
284 bool ExpectMatch =
false);
294 enum AArch64MatchResultTy {
296#define GET_OPERAND_DIAGNOSTIC_TYPES
297#include "AArch64GenAsmMatcher.inc"
300 bool IsWindowsArm64EC;
331 SMLoc &EndLoc)
override;
334 unsigned Kind)
override;
338 static bool classifySymbolRef(
const MCExpr *Expr,
371 SMLoc StartLoc, EndLoc;
380 struct ShiftExtendOp {
383 bool HasExplicitAmount;
393 RegConstraintEqualityTy EqualityTy;
409 ShiftExtendOp ShiftExtend;
414 unsigned ElementWidth;
418 struct MatrixTileListOp {
419 unsigned RegMask = 0;
422 struct VectorListOp {
426 unsigned NumElements;
427 unsigned ElementWidth;
428 RegKind RegisterKind;
431 struct VectorIndexOp {
439 struct ShiftedImmOp {
441 unsigned ShiftAmount;
502 unsigned PStateField;
508 struct MatrixRegOp MatrixReg;
509 struct MatrixTileListOp MatrixTileList;
510 struct VectorListOp VectorList;
511 struct VectorIndexOp VectorIndex;
513 struct ShiftedImmOp ShiftedImm;
514 struct ImmRangeOp ImmRange;
516 struct FPImmOp FPImm;
518 struct SysRegOp SysReg;
519 struct SysCRImmOp SysCRImm;
521 struct PSBHintOp PSBHint;
522 struct PHintOp PHint;
523 struct BTIHintOp BTIHint;
524 struct ShiftExtendOp ShiftExtend;
537 StartLoc =
o.StartLoc;
547 ShiftedImm =
o.ShiftedImm;
550 ImmRange =
o.ImmRange;
564 case k_MatrixRegister:
565 MatrixReg =
o.MatrixReg;
567 case k_MatrixTileList:
568 MatrixTileList =
o.MatrixTileList;
571 VectorList =
o.VectorList;
574 VectorIndex =
o.VectorIndex;
580 SysCRImm =
o.SysCRImm;
595 ShiftExtend =
o.ShiftExtend;
604 SMLoc getStartLoc()
const override {
return StartLoc; }
606 SMLoc getEndLoc()
const override {
return EndLoc; }
609 assert(Kind == k_Token &&
"Invalid access!");
613 bool isTokenSuffix()
const {
614 assert(Kind == k_Token &&
"Invalid access!");
618 const MCExpr *getImm()
const {
619 assert(Kind == k_Immediate &&
"Invalid access!");
623 const MCExpr *getShiftedImmVal()
const {
624 assert(Kind == k_ShiftedImm &&
"Invalid access!");
625 return ShiftedImm.Val;
628 unsigned getShiftedImmShift()
const {
629 assert(Kind == k_ShiftedImm &&
"Invalid access!");
630 return ShiftedImm.ShiftAmount;
633 unsigned getFirstImmVal()
const {
634 assert(Kind == k_ImmRange &&
"Invalid access!");
635 return ImmRange.First;
638 unsigned getLastImmVal()
const {
639 assert(Kind == k_ImmRange &&
"Invalid access!");
640 return ImmRange.Last;
644 assert(Kind == k_CondCode &&
"Invalid access!");
649 assert (Kind == k_FPImm &&
"Invalid access!");
650 return APFloat(APFloat::IEEEdouble(),
APInt(64, FPImm.Val,
true));
653 bool getFPImmIsExact()
const {
654 assert (Kind == k_FPImm &&
"Invalid access!");
655 return FPImm.IsExact;
658 unsigned getBarrier()
const {
659 assert(Kind == k_Barrier &&
"Invalid access!");
664 assert(Kind == k_Barrier &&
"Invalid access!");
668 bool getBarriernXSModifier()
const {
669 assert(Kind == k_Barrier &&
"Invalid access!");
674 assert(Kind == k_Register &&
"Invalid access!");
678 unsigned getMatrixReg()
const {
679 assert(Kind == k_MatrixRegister &&
"Invalid access!");
680 return MatrixReg.RegNum;
683 unsigned getMatrixElementWidth()
const {
684 assert(Kind == k_MatrixRegister &&
"Invalid access!");
685 return MatrixReg.ElementWidth;
688 MatrixKind getMatrixKind()
const {
689 assert(Kind == k_MatrixRegister &&
"Invalid access!");
690 return MatrixReg.Kind;
693 unsigned getMatrixTileListRegMask()
const {
694 assert(isMatrixTileList() &&
"Invalid access!");
695 return MatrixTileList.RegMask;
698 RegConstraintEqualityTy getRegEqualityTy()
const {
699 assert(Kind == k_Register &&
"Invalid access!");
700 return Reg.EqualityTy;
703 unsigned getVectorListStart()
const {
704 assert(Kind == k_VectorList &&
"Invalid access!");
705 return VectorList.RegNum;
708 unsigned getVectorListCount()
const {
709 assert(Kind == k_VectorList &&
"Invalid access!");
710 return VectorList.Count;
713 unsigned getVectorListStride()
const {
714 assert(Kind == k_VectorList &&
"Invalid access!");
715 return VectorList.Stride;
718 int getVectorIndex()
const {
719 assert(Kind == k_VectorIndex &&
"Invalid access!");
720 return VectorIndex.Val;
724 assert(Kind == k_SysReg &&
"Invalid access!");
725 return StringRef(SysReg.Data, SysReg.Length);
728 unsigned getSysCR()
const {
729 assert(Kind == k_SysCR &&
"Invalid access!");
733 unsigned getPrefetch()
const {
734 assert(Kind == k_Prefetch &&
"Invalid access!");
738 unsigned getPSBHint()
const {
739 assert(Kind == k_PSBHint &&
"Invalid access!");
743 unsigned getPHint()
const {
744 assert(Kind == k_PHint &&
"Invalid access!");
749 assert(Kind == k_PSBHint &&
"Invalid access!");
750 return StringRef(PSBHint.Data, PSBHint.Length);
754 assert(Kind == k_PHint &&
"Invalid access!");
755 return StringRef(PHint.Data, PHint.Length);
758 unsigned getBTIHint()
const {
759 assert(Kind == k_BTIHint &&
"Invalid access!");
764 assert(Kind == k_BTIHint &&
"Invalid access!");
765 return StringRef(BTIHint.Data, BTIHint.Length);
769 assert(Kind == k_SVCR &&
"Invalid access!");
770 return StringRef(SVCR.Data, SVCR.Length);
774 assert(Kind == k_Prefetch &&
"Invalid access!");
779 if (Kind == k_ShiftExtend)
780 return ShiftExtend.Type;
781 if (Kind == k_Register)
782 return Reg.ShiftExtend.Type;
786 unsigned getShiftExtendAmount()
const {
787 if (Kind == k_ShiftExtend)
788 return ShiftExtend.Amount;
789 if (Kind == k_Register)
790 return Reg.ShiftExtend.Amount;
794 bool hasShiftExtendAmount()
const {
795 if (Kind == k_ShiftExtend)
796 return ShiftExtend.HasExplicitAmount;
797 if (Kind == k_Register)
798 return Reg.ShiftExtend.HasExplicitAmount;
802 bool isImm()
const override {
return Kind == k_Immediate; }
803 bool isMem()
const override {
return false; }
805 bool isUImm6()
const {
812 return (Val >= 0 && Val < 64);
815 template <
int W
idth>
bool isSImm()
const {
return isSImmScaled<Width, 1>(); }
818 return isImmScaled<Bits, Scale>(
true);
821 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
823 if (IsRange && isImmRange() &&
824 (getLastImmVal() != getFirstImmVal() +
Offset))
825 return DiagnosticPredicateTy::NoMatch;
827 return isImmScaled<Bits, Scale, IsRange>(
false);
830 template <
int Bits,
int Scale,
bool IsRange = false>
832 if ((!
isImm() && !isImmRange()) || (
isImm() && IsRange) ||
833 (isImmRange() && !IsRange))
834 return DiagnosticPredicateTy::NoMatch;
838 Val = getFirstImmVal();
842 return DiagnosticPredicateTy::NoMatch;
846 int64_t MinVal, MaxVal;
848 int64_t Shift =
Bits - 1;
849 MinVal = (int64_t(1) << Shift) * -Scale;
850 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
853 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
856 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
857 return DiagnosticPredicateTy::Match;
859 return DiagnosticPredicateTy::NearMatch;
864 return DiagnosticPredicateTy::NoMatch;
865 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
867 return DiagnosticPredicateTy::NoMatch;
869 if (Val >= 0 && Val < 32)
870 return DiagnosticPredicateTy::Match;
871 return DiagnosticPredicateTy::NearMatch;
876 return DiagnosticPredicateTy::NoMatch;
877 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
879 return DiagnosticPredicateTy::NoMatch;
881 if (Val >= 0 && Val <= 1)
882 return DiagnosticPredicateTy::Match;
883 return DiagnosticPredicateTy::NearMatch;
886 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
890 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
924 template <
int Scale>
bool isUImm12Offset()
const {
930 return isSymbolicUImm12Offset(getImm());
933 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
936 template <
int N,
int M>
937 bool isImmInRange()
const {
944 return (Val >=
N && Val <= M);
949 template <
typename T>
950 bool isLogicalImm()
const {
967 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
969 bool isImmRange()
const {
return Kind == k_ImmRange; }
974 template <
unsigned W
idth>
975 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
976 if (isShiftedImm() && Width == getShiftedImmShift())
977 if (
auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
978 return std::make_pair(
CE->getValue(), Width);
981 if (
auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
982 int64_t Val =
CE->getValue();
984 return std::make_pair(Val >> Width, Width);
986 return std::make_pair(Val, 0u);
992 bool isAddSubImm()
const {
993 if (!isShiftedImm() && !
isImm())
999 if (isShiftedImm()) {
1000 unsigned Shift = ShiftedImm.ShiftAmount;
1001 Expr = ShiftedImm.Val;
1002 if (Shift != 0 && Shift != 12)
1011 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
1012 DarwinRefKind, Addend)) {
1031 if (
auto ShiftedVal = getShiftedVal<12>())
1032 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1039 bool isAddSubImmNeg()
const {
1040 if (!isShiftedImm() && !
isImm())
1044 if (
auto ShiftedVal = getShiftedVal<12>())
1045 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1055 template <
typename T>
1057 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1058 return DiagnosticPredicateTy::NoMatch;
1060 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1061 std::is_same<int8_t, T>::value;
1062 if (
auto ShiftedImm = getShiftedVal<8>())
1063 if (!(IsByte && ShiftedImm->second) &&
1064 AArch64_AM::isSVECpyImm<T>(
uint64_t(ShiftedImm->first)
1065 << ShiftedImm->second))
1066 return DiagnosticPredicateTy::Match;
1068 return DiagnosticPredicateTy::NearMatch;
1075 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1076 return DiagnosticPredicateTy::NoMatch;
1078 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1079 std::is_same<int8_t, T>::value;
1080 if (
auto ShiftedImm = getShiftedVal<8>())
1081 if (!(IsByte && ShiftedImm->second) &&
1082 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
1083 << ShiftedImm->second))
1084 return DiagnosticPredicateTy::Match;
1086 return DiagnosticPredicateTy::NearMatch;
1090 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1091 return DiagnosticPredicateTy::Match;
1092 return DiagnosticPredicateTy::NoMatch;
1095 bool isCondCode()
const {
return Kind == k_CondCode; }
1097 bool isSIMDImmType10()
const {
1107 bool isBranchTarget()
const {
1116 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1117 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1128 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1129 DarwinRefKind, Addend)) {
1138 bool isMovWSymbolG3()
const {
1142 bool isMovWSymbolG2()
const {
1143 return isMovWSymbol(
1150 bool isMovWSymbolG1()
const {
1151 return isMovWSymbol(
1159 bool isMovWSymbolG0()
const {
1160 return isMovWSymbol(
1168 template<
int RegW
idth,
int Shift>
1169 bool isMOVZMovAlias()
const {
1170 if (!
isImm())
return false;
1183 template<
int RegW
idth,
int Shift>
1184 bool isMOVNMovAlias()
const {
1185 if (!
isImm())
return false;
1188 if (!CE)
return false;
1194 bool isFPImm()
const {
1195 return Kind == k_FPImm &&
1199 bool isBarrier()
const {
1200 return Kind == k_Barrier && !getBarriernXSModifier();
1202 bool isBarriernXS()
const {
1203 return Kind == k_Barrier && getBarriernXSModifier();
1205 bool isSysReg()
const {
return Kind == k_SysReg; }
1207 bool isMRSSystemRegister()
const {
1208 if (!isSysReg())
return false;
1210 return SysReg.MRSReg != -1U;
1213 bool isMSRSystemRegister()
const {
1214 if (!isSysReg())
return false;
1215 return SysReg.MSRReg != -1U;
1218 bool isSystemPStateFieldWithImm0_1()
const {
1219 if (!isSysReg())
return false;
1220 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1223 bool isSystemPStateFieldWithImm0_15()
const {
1226 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1229 bool isSVCR()
const {
1232 return SVCR.PStateField != -1U;
1235 bool isReg()
const override {
1236 return Kind == k_Register;
1239 bool isVectorList()
const {
return Kind == k_VectorList; }
1241 bool isScalarReg()
const {
1242 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1245 bool isNeonVectorReg()
const {
1246 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1249 bool isNeonVectorRegLo()
const {
1250 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1251 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1253 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1257 bool isNeonVectorReg0to7()
const {
1258 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1259 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1263 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1264 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1266 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1269 case AArch64::PPRRegClassID:
1270 case AArch64::PPR_3bRegClassID:
1271 case AArch64::PPR_p8to15RegClassID:
1272 case AArch64::PNRRegClassID:
1273 case AArch64::PNR_p8to15RegClassID:
1274 case AArch64::PPRorPNRRegClassID:
1275 RK = RegKind::SVEPredicateAsCounter;
1281 return (Kind == k_Register &&
Reg.Kind == RK) &&
1282 AArch64MCRegisterClasses[
Class].contains(
getReg());
1285 template <
unsigned Class>
bool isSVEVectorReg()
const {
1288 case AArch64::ZPRRegClassID:
1289 case AArch64::ZPR_3bRegClassID:
1290 case AArch64::ZPR_4bRegClassID:
1291 case AArch64::ZPRMul2_LoRegClassID:
1292 case AArch64::ZPRMul2_HiRegClassID:
1293 case AArch64::ZPR_KRegClassID:
1294 RK = RegKind::SVEDataVector;
1296 case AArch64::PPRRegClassID:
1297 case AArch64::PPR_3bRegClassID:
1298 case AArch64::PPR_p8to15RegClassID:
1299 case AArch64::PNRRegClassID:
1300 case AArch64::PNR_p8to15RegClassID:
1301 case AArch64::PPRorPNRRegClassID:
1302 RK = RegKind::SVEPredicateVector;
1308 return (Kind == k_Register &&
Reg.Kind == RK) &&
1309 AArch64MCRegisterClasses[
Class].contains(
getReg());
1312 template <
unsigned Class>
bool isFPRasZPR()
const {
1313 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1314 AArch64MCRegisterClasses[
Class].contains(
getReg());
1317 template <
int ElementW
idth,
unsigned Class>
1319 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1320 return DiagnosticPredicateTy::NoMatch;
1322 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1323 return DiagnosticPredicateTy::Match;
1325 return DiagnosticPredicateTy::NearMatch;
1328 template <
int ElementW
idth,
unsigned Class>
1330 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1331 Reg.Kind != RegKind::SVEPredicateVector))
1332 return DiagnosticPredicateTy::NoMatch;
1334 if ((isSVEPredicateAsCounterReg<Class>() ||
1335 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1336 Reg.ElementWidth == ElementWidth)
1337 return DiagnosticPredicateTy::Match;
1339 return DiagnosticPredicateTy::NearMatch;
1342 template <
int ElementW
idth,
unsigned Class>
1344 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1345 return DiagnosticPredicateTy::NoMatch;
1347 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1348 return DiagnosticPredicateTy::Match;
1350 return DiagnosticPredicateTy::NearMatch;
1353 template <
int ElementW
idth,
unsigned Class>
1355 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1356 return DiagnosticPredicateTy::NoMatch;
1358 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1359 return DiagnosticPredicateTy::Match;
1361 return DiagnosticPredicateTy::NearMatch;
1364 template <
int ElementWidth,
unsigned Class,
1366 bool ShiftWidthAlwaysSame>
1368 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1369 if (!VectorMatch.isMatch())
1370 return DiagnosticPredicateTy::NoMatch;
1375 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1378 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1379 return DiagnosticPredicateTy::NoMatch;
1381 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1382 return DiagnosticPredicateTy::Match;
1384 return DiagnosticPredicateTy::NearMatch;
1387 bool isGPR32as64()
const {
1388 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1389 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1392 bool isGPR64as32()
const {
1393 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1394 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1397 bool isGPR64x8()
const {
1398 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1399 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1403 bool isWSeqPair()
const {
1404 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1405 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1409 bool isXSeqPair()
const {
1410 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1411 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1415 bool isSyspXzrPair()
const {
1416 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1419 template<
int64_t Angle,
int64_t Remainder>
1421 if (!
isImm())
return DiagnosticPredicateTy::NoMatch;
1424 if (!CE)
return DiagnosticPredicateTy::NoMatch;
1427 if (
Value % Angle == Remainder &&
Value <= 270)
1428 return DiagnosticPredicateTy::Match;
1429 return DiagnosticPredicateTy::NearMatch;
1432 template <
unsigned RegClassID>
bool isGPR64()
const {
1433 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1434 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1437 template <
unsigned RegClassID,
int ExtW
idth>
1439 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1440 return DiagnosticPredicateTy::NoMatch;
1442 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1443 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1444 return DiagnosticPredicateTy::Match;
1445 return DiagnosticPredicateTy::NearMatch;
1450 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1451 bool isImplicitlyTypedVectorList()
const {
1452 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1453 VectorList.NumElements == 0 &&
1454 VectorList.RegisterKind == VectorKind &&
1455 (!IsConsecutive || (VectorList.Stride == 1));
1458 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1459 unsigned ElementWidth,
unsigned Stride = 1>
1460 bool isTypedVectorList()
const {
1461 if (Kind != k_VectorList)
1463 if (VectorList.Count != NumRegs)
1465 if (VectorList.RegisterKind != VectorKind)
1467 if (VectorList.ElementWidth != ElementWidth)
1469 if (VectorList.Stride != Stride)
1471 return VectorList.NumElements == NumElements;
1474 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1475 unsigned ElementWidth,
unsigned RegClass>
1478 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1480 return DiagnosticPredicateTy::NoMatch;
1481 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.RegNum))
1482 return DiagnosticPredicateTy::NearMatch;
1483 return DiagnosticPredicateTy::Match;
1486 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1487 unsigned ElementWidth>
1489 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1490 ElementWidth, Stride>();
1492 return DiagnosticPredicateTy::NoMatch;
1493 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1494 ((VectorList.RegNum >= AArch64::Z16) &&
1495 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1496 return DiagnosticPredicateTy::Match;
1497 return DiagnosticPredicateTy::NoMatch;
1500 template <
int Min,
int Max>
1502 if (Kind != k_VectorIndex)
1503 return DiagnosticPredicateTy::NoMatch;
1504 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1505 return DiagnosticPredicateTy::Match;
1506 return DiagnosticPredicateTy::NearMatch;
1509 bool isToken()
const override {
return Kind == k_Token; }
1511 bool isTokenEqual(
StringRef Str)
const {
1512 return Kind == k_Token && getToken() == Str;
1514 bool isSysCR()
const {
return Kind == k_SysCR; }
1515 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1516 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1517 bool isPHint()
const {
return Kind == k_PHint; }
1518 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1519 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1520 bool isShifter()
const {
1521 if (!isShiftExtend())
1531 if (Kind != k_FPImm)
1532 return DiagnosticPredicateTy::NoMatch;
1534 if (getFPImmIsExact()) {
1536 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1540 APFloat RealVal(APFloat::IEEEdouble());
1542 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1543 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1546 if (
getFPImm().bitwiseIsEqual(RealVal))
1547 return DiagnosticPredicateTy::Match;
1550 return DiagnosticPredicateTy::NearMatch;
1553 template <
unsigned ImmA,
unsigned ImmB>
1556 if ((Res = isExactFPImm<ImmA>()))
1557 return DiagnosticPredicateTy::Match;
1558 if ((Res = isExactFPImm<ImmB>()))
1559 return DiagnosticPredicateTy::Match;
1563 bool isExtend()
const {
1564 if (!isShiftExtend())
1573 getShiftExtendAmount() <= 4;
1576 bool isExtend64()
const {
1586 bool isExtendLSL64()
const {
1592 getShiftExtendAmount() <= 4;
1595 bool isLSLImm3Shift()
const {
1596 if (!isShiftExtend())
1602 template<
int W
idth>
bool isMemXExtend()
const {
1607 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1608 getShiftExtendAmount() == 0);
1611 template<
int W
idth>
bool isMemWExtend()
const {
1616 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1617 getShiftExtendAmount() == 0);
1620 template <
unsigned w
idth>
1621 bool isArithmeticShifter()
const {
1631 template <
unsigned w
idth>
1632 bool isLogicalShifter()
const {
1640 getShiftExtendAmount() < width;
1643 bool isMovImm32Shifter()
const {
1651 uint64_t Val = getShiftExtendAmount();
1652 return (Val == 0 || Val == 16);
1655 bool isMovImm64Shifter()
const {
1663 uint64_t Val = getShiftExtendAmount();
1664 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1667 bool isLogicalVecShifter()
const {
1672 unsigned Shift = getShiftExtendAmount();
1674 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1677 bool isLogicalVecHalfWordShifter()
const {
1678 if (!isLogicalVecShifter())
1682 unsigned Shift = getShiftExtendAmount();
1684 (Shift == 0 || Shift == 8);
1687 bool isMoveVecShifter()
const {
1688 if (!isShiftExtend())
1692 unsigned Shift = getShiftExtendAmount();
1694 (Shift == 8 || Shift == 16);
1703 bool isSImm9OffsetFB()
const {
1704 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1707 bool isAdrpLabel()
const {
1714 int64_t Val =
CE->getValue();
1715 int64_t Min = - (4096 * (1LL << (21 - 1)));
1716 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1717 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1723 bool isAdrLabel()
const {
1730 int64_t Val =
CE->getValue();
1731 int64_t Min = - (1LL << (21 - 1));
1732 int64_t
Max = ((1LL << (21 - 1)) - 1);
1733 return Val >= Min && Val <=
Max;
1739 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1742 return DiagnosticPredicateTy::NoMatch;
1743 if (getMatrixKind() != Kind ||
1744 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1745 EltSize != getMatrixElementWidth())
1746 return DiagnosticPredicateTy::NearMatch;
1747 return DiagnosticPredicateTy::Match;
1750 bool isPAuthPCRelLabel16Operand()
const {
1762 return (Val <= 0) && (Val > -(1 << 18));
1769 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1775 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1776 assert(
N == 1 &&
"Invalid number of operands!");
1780 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1781 assert(
N == 1 &&
"Invalid number of operands!");
1785 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1786 assert(
N == 1 &&
"Invalid number of operands!");
1788 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1797 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1798 assert(
N == 1 &&
"Invalid number of operands!");
1800 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1809 template <
int W
idth>
1810 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1813 case 8:
Base = AArch64::B0;
break;
1814 case 16:
Base = AArch64::H0;
break;
1815 case 32:
Base = AArch64::S0;
break;
1816 case 64:
Base = AArch64::D0;
break;
1817 case 128:
Base = AArch64::Q0;
break;
1824 void addPPRorPNRRegOperands(
MCInst &Inst,
unsigned N)
const {
1825 assert(
N == 1 &&
"Invalid number of operands!");
1828 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1829 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1833 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1834 assert(
N == 1 &&
"Invalid number of operands!");
1839 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1840 assert(
N == 1 &&
"Invalid number of operands!");
1842 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1846 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1847 assert(
N == 1 &&
"Invalid number of operands!");
1849 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1853 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1854 assert(
N == 1 &&
"Invalid number of operands!");
1858 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1859 assert(
N == 1 &&
"Invalid number of operands!");
1863 enum VecListIndexType {
1864 VecListIdx_DReg = 0,
1865 VecListIdx_QReg = 1,
1866 VecListIdx_ZReg = 2,
1867 VecListIdx_PReg = 3,
1870 template <VecListIndexType RegTy,
unsigned NumRegs,
1871 bool IsConsecutive =
false>
1872 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1873 assert(
N == 1 &&
"Invalid number of operands!");
1874 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1875 "Expected consecutive registers");
1876 static const unsigned FirstRegs[][5] = {
1878 AArch64::D0, AArch64::D0_D1,
1879 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1881 AArch64::Q0, AArch64::Q0_Q1,
1882 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1884 AArch64::Z0, AArch64::Z0_Z1,
1885 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1887 AArch64::P0, AArch64::P0_P1 }
1890 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1891 " NumRegs must be <= 4 for ZRegs");
1893 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1894 " NumRegs must be <= 2 for PRegs");
1896 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1898 FirstRegs[(
unsigned)RegTy][0]));
1901 template <
unsigned NumRegs>
1902 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1903 assert(
N == 1 &&
"Invalid number of operands!");
1904 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1908 if (getVectorListStart() < AArch64::Z16) {
1909 assert((getVectorListStart() < AArch64::Z8) &&
1910 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1912 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1914 assert((getVectorListStart() < AArch64::Z24) &&
1915 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1917 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1921 if (getVectorListStart() < AArch64::Z16) {
1922 assert((getVectorListStart() < AArch64::Z4) &&
1923 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1925 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1927 assert((getVectorListStart() < AArch64::Z20) &&
1928 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1930 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1938 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1939 assert(
N == 1 &&
"Invalid number of operands!");
1940 unsigned RegMask = getMatrixTileListRegMask();
1941 assert(RegMask <= 0xFF &&
"Invalid mask!");
1945 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1946 assert(
N == 1 &&
"Invalid number of operands!");
1950 template <
unsigned ImmIs0,
unsigned ImmIs1>
1951 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1952 assert(
N == 1 &&
"Invalid number of operands!");
1953 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1957 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1958 assert(
N == 1 &&
"Invalid number of operands!");
1962 addExpr(Inst, getImm());
1965 template <
int Shift>
1966 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1967 assert(
N == 2 &&
"Invalid number of operands!");
1968 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1971 }
else if (isShiftedImm()) {
1972 addExpr(Inst, getShiftedImmVal());
1975 addExpr(Inst, getImm());
1980 template <
int Shift>
1981 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1982 assert(
N == 2 &&
"Invalid number of operands!");
1983 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1990 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1991 assert(
N == 1 &&
"Invalid number of operands!");
1995 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1996 assert(
N == 1 &&
"Invalid number of operands!");
1999 addExpr(Inst, getImm());
2004 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2005 addImmOperands(Inst,
N);
2009 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2010 assert(
N == 1 &&
"Invalid number of operands!");
2020 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
2021 assert(
N == 1 &&
"Invalid number of operands!");
2026 template <
int Scale>
2027 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
2028 assert(
N == 1 &&
"Invalid number of operands!");
2033 template <
int Scale>
2034 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
2035 assert(
N == 1 &&
"Invalid number of operands!");
2039 template <
typename T>
2040 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
2041 assert(
N == 1 &&
"Invalid number of operands!");
2043 std::make_unsigned_t<T> Val = MCE->
getValue();
2048 template <
typename T>
2049 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2050 assert(
N == 1 &&
"Invalid number of operands!");
2052 std::make_unsigned_t<T> Val = ~MCE->getValue();
2057 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
2058 assert(
N == 1 &&
"Invalid number of operands!");
2064 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2068 assert(
N == 1 &&
"Invalid number of operands!");
2071 addExpr(Inst, getImm());
2074 assert(MCE &&
"Invalid constant immediate operand!");
2078 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2082 assert(
N == 1 &&
"Invalid number of operands!");
2085 addExpr(Inst, getImm());
2091 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2095 assert(
N == 1 &&
"Invalid number of operands!");
2098 addExpr(Inst, getImm());
2101 assert(MCE &&
"Invalid constant immediate operand!");
2105 void addPCRelLabel9Operands(
MCInst &Inst,
unsigned N)
const {
2109 assert(
N == 1 &&
"Invalid number of operands!");
2112 addExpr(Inst, getImm());
2115 assert(MCE &&
"Invalid constant immediate operand!");
2119 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2123 assert(
N == 1 &&
"Invalid number of operands!");
2126 addExpr(Inst, getImm());
2129 assert(MCE &&
"Invalid constant immediate operand!");
2133 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2134 assert(
N == 1 &&
"Invalid number of operands!");
2139 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2140 assert(
N == 1 &&
"Invalid number of operands!");
2144 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2145 assert(
N == 1 &&
"Invalid number of operands!");
2149 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2150 assert(
N == 1 &&
"Invalid number of operands!");
2155 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2156 assert(
N == 1 &&
"Invalid number of operands!");
2161 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2162 assert(
N == 1 &&
"Invalid number of operands!");
2167 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2168 assert(
N == 1 &&
"Invalid number of operands!");
2173 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2174 assert(
N == 1 &&
"Invalid number of operands!");
2179 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2184 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2185 assert(
N == 1 &&
"Invalid number of operands!");
2189 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2190 assert(
N == 1 &&
"Invalid number of operands!");
2194 void addPHintOperands(
MCInst &Inst,
unsigned N)
const {
2195 assert(
N == 1 &&
"Invalid number of operands!");
2199 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2200 assert(
N == 1 &&
"Invalid number of operands!");
2204 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2205 assert(
N == 1 &&
"Invalid number of operands!");
2211 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2212 assert(
N == 1 &&
"Invalid number of operands!");
2213 unsigned Imm = getShiftExtendAmount();
2217 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2218 assert(
N == 1 &&
"Invalid number of operands!");
2226 if (
Reg != AArch64::XZR)
2232 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2233 assert(
N == 1 &&
"Invalid number of operands!");
2240 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2241 assert(
N == 1 &&
"Invalid number of operands!");
2248 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2249 assert(
N == 2 &&
"Invalid number of operands!");
2260 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2261 assert(
N == 2 &&
"Invalid number of operands!");
2269 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2270 assert(
N == 1 &&
"Invalid number of operands!");
2277 addExpr(Inst, getImm());
2282 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2283 assert(
N == 1 &&
"Invalid number of operands!");
2290 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2291 assert(
N == 1 &&
"Invalid number of operands!");
2296 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2297 assert(
N == 1 &&
"Invalid number of operands!");
2304 static std::unique_ptr<AArch64Operand>
2306 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2307 Op->Tok.Data = Str.data();
2308 Op->Tok.Length = Str.size();
2309 Op->Tok.IsSuffix = IsSuffix;
2315 static std::unique_ptr<AArch64Operand>
2317 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2319 unsigned ShiftAmount = 0,
2320 unsigned HasExplicitAmount =
false) {
2321 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2322 Op->Reg.RegNum = RegNum;
2324 Op->Reg.ElementWidth = 0;
2325 Op->Reg.EqualityTy = EqTy;
2326 Op->Reg.ShiftExtend.Type = ExtTy;
2327 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2328 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2334 static std::unique_ptr<AArch64Operand>
2335 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2338 unsigned ShiftAmount = 0,
2339 unsigned HasExplicitAmount =
false) {
2340 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2341 Kind == RegKind::SVEPredicateVector ||
2342 Kind == RegKind::SVEPredicateAsCounter) &&
2343 "Invalid vector kind");
2344 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2346 Op->Reg.ElementWidth = ElementWidth;
2350 static std::unique_ptr<AArch64Operand>
2351 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2352 unsigned NumElements,
unsigned ElementWidth,
2354 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2355 Op->VectorList.RegNum = RegNum;
2356 Op->VectorList.Count = Count;
2357 Op->VectorList.Stride = Stride;
2358 Op->VectorList.NumElements = NumElements;
2359 Op->VectorList.ElementWidth = ElementWidth;
2360 Op->VectorList.RegisterKind = RegisterKind;
2366 static std::unique_ptr<AArch64Operand>
2368 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2369 Op->VectorIndex.Val =
Idx;
2375 static std::unique_ptr<AArch64Operand>
2377 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2378 Op->MatrixTileList.RegMask = RegMask;
2385 const unsigned ElementWidth) {
2386 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2388 {{0, AArch64::ZAB0},
2389 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2390 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2391 {{8, AArch64::ZAB0},
2392 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2393 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2394 {{16, AArch64::ZAH0},
2395 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2396 {{16, AArch64::ZAH1},
2397 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2398 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2399 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2400 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2401 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2404 if (ElementWidth == 64)
2407 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2408 assert(!Regs.empty() &&
"Invalid tile or element width!");
2409 for (
auto OutReg : Regs)
2414 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2416 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2423 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2424 unsigned ShiftAmount,
2427 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2428 Op->ShiftedImm .Val = Val;
2429 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2435 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2439 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2441 Op->ImmRange.Last =
Last;
2446 static std::unique_ptr<AArch64Operand>
2448 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2449 Op->CondCode.Code =
Code;
2455 static std::unique_ptr<AArch64Operand>
2457 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2459 Op->FPImm.IsExact = IsExact;
2465 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2469 bool HasnXSModifier) {
2470 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2471 Op->Barrier.Val = Val;
2472 Op->Barrier.Data = Str.data();
2473 Op->Barrier.Length = Str.size();
2474 Op->Barrier.HasnXSModifier = HasnXSModifier;
2480 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2485 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2486 Op->SysReg.Data = Str.data();
2487 Op->SysReg.Length = Str.size();
2488 Op->SysReg.MRSReg = MRSReg;
2489 Op->SysReg.MSRReg = MSRReg;
2490 Op->SysReg.PStateField = PStateField;
2496 static std::unique_ptr<AArch64Operand>
2498 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2499 Op->PHint.Val = Val;
2500 Op->PHint.Data = Str.data();
2501 Op->PHint.Length = Str.size();
2507 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2509 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2510 Op->SysCRImm.Val = Val;
2516 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2520 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2521 Op->Prefetch.Val = Val;
2522 Op->Barrier.Data = Str.data();
2523 Op->Barrier.Length = Str.size();
2529 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2533 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2534 Op->PSBHint.Val = Val;
2535 Op->PSBHint.Data = Str.data();
2536 Op->PSBHint.Length = Str.size();
2542 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2546 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2547 Op->BTIHint.Val = Val | 32;
2548 Op->BTIHint.Data = Str.data();
2549 Op->BTIHint.Length = Str.size();
2555 static std::unique_ptr<AArch64Operand>
2556 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2558 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2559 Op->MatrixReg.RegNum = RegNum;
2560 Op->MatrixReg.ElementWidth = ElementWidth;
2561 Op->MatrixReg.Kind =
Kind;
2567 static std::unique_ptr<AArch64Operand>
2569 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2570 Op->SVCR.PStateField = PStateField;
2571 Op->SVCR.Data = Str.data();
2572 Op->SVCR.Length = Str.size();
2578 static std::unique_ptr<AArch64Operand>
2581 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2582 Op->ShiftExtend.Type = ShOp;
2583 Op->ShiftExtend.Amount = Val;
2584 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2596 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2597 if (!getFPImmIsExact())
2604 OS <<
"<barrier " <<
Name <<
">";
2606 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2612 case k_ShiftedImm: {
2613 unsigned Shift = getShiftedImmShift();
2614 OS <<
"<shiftedimm ";
2615 OS << *getShiftedImmVal();
2621 OS << getFirstImmVal();
2622 OS <<
":" << getLastImmVal() <<
">";
2628 case k_VectorList: {
2629 OS <<
"<vectorlist ";
2630 unsigned Reg = getVectorListStart();
2631 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2632 OS <<
Reg + i * getVectorListStride() <<
" ";
2637 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2640 OS <<
"<sysreg: " << getSysReg() <<
'>';
2643 OS <<
"'" << getToken() <<
"'";
2646 OS <<
"c" << getSysCR();
2651 OS <<
"<prfop " <<
Name <<
">";
2653 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2657 OS << getPSBHintName();
2660 OS << getPHintName();
2663 OS << getBTIHintName();
2665 case k_MatrixRegister:
2666 OS <<
"<matrix " << getMatrixReg() <<
">";
2668 case k_MatrixTileList: {
2669 OS <<
"<matrixlist ";
2670 unsigned RegMask = getMatrixTileListRegMask();
2671 unsigned MaxBits = 8;
2672 for (
unsigned I = MaxBits;
I > 0; --
I)
2673 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2682 OS <<
"<register " <<
getReg() <<
">";
2683 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2688 << getShiftExtendAmount();
2689 if (!hasShiftExtendAmount())
2705 .
Case(
"v0", AArch64::Q0)
2706 .
Case(
"v1", AArch64::Q1)
2707 .
Case(
"v2", AArch64::Q2)
2708 .
Case(
"v3", AArch64::Q3)
2709 .
Case(
"v4", AArch64::Q4)
2710 .
Case(
"v5", AArch64::Q5)
2711 .
Case(
"v6", AArch64::Q6)
2712 .
Case(
"v7", AArch64::Q7)
2713 .
Case(
"v8", AArch64::Q8)
2714 .
Case(
"v9", AArch64::Q9)
2715 .
Case(
"v10", AArch64::Q10)
2716 .
Case(
"v11", AArch64::Q11)
2717 .
Case(
"v12", AArch64::Q12)
2718 .
Case(
"v13", AArch64::Q13)
2719 .
Case(
"v14", AArch64::Q14)
2720 .
Case(
"v15", AArch64::Q15)
2721 .
Case(
"v16", AArch64::Q16)
2722 .
Case(
"v17", AArch64::Q17)
2723 .
Case(
"v18", AArch64::Q18)
2724 .
Case(
"v19", AArch64::Q19)
2725 .
Case(
"v20", AArch64::Q20)
2726 .
Case(
"v21", AArch64::Q21)
2727 .
Case(
"v22", AArch64::Q22)
2728 .
Case(
"v23", AArch64::Q23)
2729 .
Case(
"v24", AArch64::Q24)
2730 .
Case(
"v25", AArch64::Q25)
2731 .
Case(
"v26", AArch64::Q26)
2732 .
Case(
"v27", AArch64::Q27)
2733 .
Case(
"v28", AArch64::Q28)
2734 .
Case(
"v29", AArch64::Q29)
2735 .
Case(
"v30", AArch64::Q30)
2736 .
Case(
"v31", AArch64::Q31)
2745 RegKind VectorKind) {
2746 std::pair<int, int> Res = {-1, -1};
2748 switch (VectorKind) {
2749 case RegKind::NeonVector:
2752 .Case(
".1d", {1, 64})
2753 .Case(
".1q", {1, 128})
2755 .Case(
".2h", {2, 16})
2756 .Case(
".2b", {2, 8})
2757 .Case(
".2s", {2, 32})
2758 .Case(
".2d", {2, 64})
2761 .Case(
".4b", {4, 8})
2762 .Case(
".4h", {4, 16})
2763 .Case(
".4s", {4, 32})
2764 .Case(
".8b", {8, 8})
2765 .Case(
".8h", {8, 16})
2766 .Case(
".16b", {16, 8})
2771 .Case(
".h", {0, 16})
2772 .Case(
".s", {0, 32})
2773 .Case(
".d", {0, 64})
2776 case RegKind::SVEPredicateAsCounter:
2777 case RegKind::SVEPredicateVector:
2778 case RegKind::SVEDataVector:
2779 case RegKind::Matrix:
2783 .Case(
".h", {0, 16})
2784 .Case(
".s", {0, 32})
2785 .Case(
".d", {0, 64})
2786 .Case(
".q", {0, 128})
2793 if (Res == std::make_pair(-1, -1))
2794 return std::nullopt;
2796 return std::optional<std::pair<int, int>>(Res);
2805 .
Case(
"z0", AArch64::Z0)
2806 .
Case(
"z1", AArch64::Z1)
2807 .
Case(
"z2", AArch64::Z2)
2808 .
Case(
"z3", AArch64::Z3)
2809 .
Case(
"z4", AArch64::Z4)
2810 .
Case(
"z5", AArch64::Z5)
2811 .
Case(
"z6", AArch64::Z6)
2812 .
Case(
"z7", AArch64::Z7)
2813 .
Case(
"z8", AArch64::Z8)
2814 .
Case(
"z9", AArch64::Z9)
2815 .
Case(
"z10", AArch64::Z10)
2816 .
Case(
"z11", AArch64::Z11)
2817 .
Case(
"z12", AArch64::Z12)
2818 .
Case(
"z13", AArch64::Z13)
2819 .
Case(
"z14", AArch64::Z14)
2820 .
Case(
"z15", AArch64::Z15)
2821 .
Case(
"z16", AArch64::Z16)
2822 .
Case(
"z17", AArch64::Z17)
2823 .
Case(
"z18", AArch64::Z18)
2824 .
Case(
"z19", AArch64::Z19)
2825 .
Case(
"z20", AArch64::Z20)
2826 .
Case(
"z21", AArch64::Z21)
2827 .
Case(
"z22", AArch64::Z22)
2828 .
Case(
"z23", AArch64::Z23)
2829 .
Case(
"z24", AArch64::Z24)
2830 .
Case(
"z25", AArch64::Z25)
2831 .
Case(
"z26", AArch64::Z26)
2832 .
Case(
"z27", AArch64::Z27)
2833 .
Case(
"z28", AArch64::Z28)
2834 .
Case(
"z29", AArch64::Z29)
2835 .
Case(
"z30", AArch64::Z30)
2836 .
Case(
"z31", AArch64::Z31)
2842 .
Case(
"p0", AArch64::P0)
2843 .
Case(
"p1", AArch64::P1)
2844 .
Case(
"p2", AArch64::P2)
2845 .
Case(
"p3", AArch64::P3)
2846 .
Case(
"p4", AArch64::P4)
2847 .
Case(
"p5", AArch64::P5)
2848 .
Case(
"p6", AArch64::P6)
2849 .
Case(
"p7", AArch64::P7)
2850 .
Case(
"p8", AArch64::P8)
2851 .
Case(
"p9", AArch64::P9)
2852 .
Case(
"p10", AArch64::P10)
2853 .
Case(
"p11", AArch64::P11)
2854 .
Case(
"p12", AArch64::P12)
2855 .
Case(
"p13", AArch64::P13)
2856 .
Case(
"p14", AArch64::P14)
2857 .
Case(
"p15", AArch64::P15)
2863 .
Case(
"pn0", AArch64::PN0)
2864 .
Case(
"pn1", AArch64::PN1)
2865 .
Case(
"pn2", AArch64::PN2)
2866 .
Case(
"pn3", AArch64::PN3)
2867 .
Case(
"pn4", AArch64::PN4)
2868 .
Case(
"pn5", AArch64::PN5)
2869 .
Case(
"pn6", AArch64::PN6)
2870 .
Case(
"pn7", AArch64::PN7)
2871 .
Case(
"pn8", AArch64::PN8)
2872 .
Case(
"pn9", AArch64::PN9)
2873 .
Case(
"pn10", AArch64::PN10)
2874 .
Case(
"pn11", AArch64::PN11)
2875 .
Case(
"pn12", AArch64::PN12)
2876 .
Case(
"pn13", AArch64::PN13)
2877 .
Case(
"pn14", AArch64::PN14)
2878 .
Case(
"pn15", AArch64::PN15)
2884 .
Case(
"za0.d", AArch64::ZAD0)
2885 .
Case(
"za1.d", AArch64::ZAD1)
2886 .
Case(
"za2.d", AArch64::ZAD2)
2887 .
Case(
"za3.d", AArch64::ZAD3)
2888 .
Case(
"za4.d", AArch64::ZAD4)
2889 .
Case(
"za5.d", AArch64::ZAD5)
2890 .
Case(
"za6.d", AArch64::ZAD6)
2891 .
Case(
"za7.d", AArch64::ZAD7)
2892 .
Case(
"za0.s", AArch64::ZAS0)
2893 .
Case(
"za1.s", AArch64::ZAS1)
2894 .
Case(
"za2.s", AArch64::ZAS2)
2895 .
Case(
"za3.s", AArch64::ZAS3)
2896 .
Case(
"za0.h", AArch64::ZAH0)
2897 .
Case(
"za1.h", AArch64::ZAH1)
2898 .
Case(
"za0.b", AArch64::ZAB0)
2904 .
Case(
"za", AArch64::ZA)
2905 .
Case(
"za0.q", AArch64::ZAQ0)
2906 .
Case(
"za1.q", AArch64::ZAQ1)
2907 .
Case(
"za2.q", AArch64::ZAQ2)
2908 .
Case(
"za3.q", AArch64::ZAQ3)
2909 .
Case(
"za4.q", AArch64::ZAQ4)
2910 .
Case(
"za5.q", AArch64::ZAQ5)
2911 .
Case(
"za6.q", AArch64::ZAQ6)
2912 .
Case(
"za7.q", AArch64::ZAQ7)
2913 .
Case(
"za8.q", AArch64::ZAQ8)
2914 .
Case(
"za9.q", AArch64::ZAQ9)
2915 .
Case(
"za10.q", AArch64::ZAQ10)
2916 .
Case(
"za11.q", AArch64::ZAQ11)
2917 .
Case(
"za12.q", AArch64::ZAQ12)
2918 .
Case(
"za13.q", AArch64::ZAQ13)
2919 .
Case(
"za14.q", AArch64::ZAQ14)
2920 .
Case(
"za15.q", AArch64::ZAQ15)
2921 .
Case(
"za0.d", AArch64::ZAD0)
2922 .
Case(
"za1.d", AArch64::ZAD1)
2923 .
Case(
"za2.d", AArch64::ZAD2)
2924 .
Case(
"za3.d", AArch64::ZAD3)
2925 .
Case(
"za4.d", AArch64::ZAD4)
2926 .
Case(
"za5.d", AArch64::ZAD5)
2927 .
Case(
"za6.d", AArch64::ZAD6)
2928 .
Case(
"za7.d", AArch64::ZAD7)
2929 .
Case(
"za0.s", AArch64::ZAS0)
2930 .
Case(
"za1.s", AArch64::ZAS1)
2931 .
Case(
"za2.s", AArch64::ZAS2)
2932 .
Case(
"za3.s", AArch64::ZAS3)
2933 .
Case(
"za0.h", AArch64::ZAH0)
2934 .
Case(
"za1.h", AArch64::ZAH1)
2935 .
Case(
"za0.b", AArch64::ZAB0)
2936 .
Case(
"za0h.q", AArch64::ZAQ0)
2937 .
Case(
"za1h.q", AArch64::ZAQ1)
2938 .
Case(
"za2h.q", AArch64::ZAQ2)
2939 .
Case(
"za3h.q", AArch64::ZAQ3)
2940 .
Case(
"za4h.q", AArch64::ZAQ4)
2941 .
Case(
"za5h.q", AArch64::ZAQ5)
2942 .
Case(
"za6h.q", AArch64::ZAQ6)
2943 .
Case(
"za7h.q", AArch64::ZAQ7)
2944 .
Case(
"za8h.q", AArch64::ZAQ8)
2945 .
Case(
"za9h.q", AArch64::ZAQ9)
2946 .
Case(
"za10h.q", AArch64::ZAQ10)
2947 .
Case(
"za11h.q", AArch64::ZAQ11)
2948 .
Case(
"za12h.q", AArch64::ZAQ12)
2949 .
Case(
"za13h.q", AArch64::ZAQ13)
2950 .
Case(
"za14h.q", AArch64::ZAQ14)
2951 .
Case(
"za15h.q", AArch64::ZAQ15)
2952 .
Case(
"za0h.d", AArch64::ZAD0)
2953 .
Case(
"za1h.d", AArch64::ZAD1)
2954 .
Case(
"za2h.d", AArch64::ZAD2)
2955 .
Case(
"za3h.d", AArch64::ZAD3)
2956 .
Case(
"za4h.d", AArch64::ZAD4)
2957 .
Case(
"za5h.d", AArch64::ZAD5)
2958 .
Case(
"za6h.d", AArch64::ZAD6)
2959 .
Case(
"za7h.d", AArch64::ZAD7)
2960 .
Case(
"za0h.s", AArch64::ZAS0)
2961 .
Case(
"za1h.s", AArch64::ZAS1)
2962 .
Case(
"za2h.s", AArch64::ZAS2)
2963 .
Case(
"za3h.s", AArch64::ZAS3)
2964 .
Case(
"za0h.h", AArch64::ZAH0)
2965 .
Case(
"za1h.h", AArch64::ZAH1)
2966 .
Case(
"za0h.b", AArch64::ZAB0)
2967 .
Case(
"za0v.q", AArch64::ZAQ0)
2968 .
Case(
"za1v.q", AArch64::ZAQ1)
2969 .
Case(
"za2v.q", AArch64::ZAQ2)
2970 .
Case(
"za3v.q", AArch64::ZAQ3)
2971 .
Case(
"za4v.q", AArch64::ZAQ4)
2972 .
Case(
"za5v.q", AArch64::ZAQ5)
2973 .
Case(
"za6v.q", AArch64::ZAQ6)
2974 .
Case(
"za7v.q", AArch64::ZAQ7)
2975 .
Case(
"za8v.q", AArch64::ZAQ8)
2976 .
Case(
"za9v.q", AArch64::ZAQ9)
2977 .
Case(
"za10v.q", AArch64::ZAQ10)
2978 .
Case(
"za11v.q", AArch64::ZAQ11)
2979 .
Case(
"za12v.q", AArch64::ZAQ12)
2980 .
Case(
"za13v.q", AArch64::ZAQ13)
2981 .
Case(
"za14v.q", AArch64::ZAQ14)
2982 .
Case(
"za15v.q", AArch64::ZAQ15)
2983 .
Case(
"za0v.d", AArch64::ZAD0)
2984 .
Case(
"za1v.d", AArch64::ZAD1)
2985 .
Case(
"za2v.d", AArch64::ZAD2)
2986 .
Case(
"za3v.d", AArch64::ZAD3)
2987 .
Case(
"za4v.d", AArch64::ZAD4)
2988 .
Case(
"za5v.d", AArch64::ZAD5)
2989 .
Case(
"za6v.d", AArch64::ZAD6)
2990 .
Case(
"za7v.d", AArch64::ZAD7)
2991 .
Case(
"za0v.s", AArch64::ZAS0)
2992 .
Case(
"za1v.s", AArch64::ZAS1)
2993 .
Case(
"za2v.s", AArch64::ZAS2)
2994 .
Case(
"za3v.s", AArch64::ZAS3)
2995 .
Case(
"za0v.h", AArch64::ZAH0)
2996 .
Case(
"za1v.h", AArch64::ZAH1)
2997 .
Case(
"za0v.b", AArch64::ZAB0)
3003 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3008 StartLoc = getLoc();
3015unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
3017 unsigned RegNum = 0;
3019 return Kind == RegKind::SVEDataVector ? RegNum : 0;
3022 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
3025 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
3028 return Kind == RegKind::NeonVector ? RegNum : 0;
3031 return Kind == RegKind::Matrix ? RegNum : 0;
3033 if (
Name.equals_insensitive(
"zt0"))
3034 return Kind == RegKind::LookupTable ?
unsigned(AArch64::ZT0) : 0;
3038 return (Kind == RegKind::Scalar) ? RegNum : 0;
3043 .
Case(
"fp", AArch64::FP)
3044 .
Case(
"lr", AArch64::LR)
3045 .
Case(
"x31", AArch64::XZR)
3046 .
Case(
"w31", AArch64::WZR)
3048 return Kind == RegKind::Scalar ? RegNum : 0;
3054 if (Entry == RegisterReqs.
end())
3058 if (Kind ==
Entry->getValue().first)
3059 RegNum =
Entry->getValue().second;
3064unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3066 case RegKind::Scalar:
3067 case RegKind::NeonVector:
3068 case RegKind::SVEDataVector:
3070 case RegKind::Matrix:
3071 case RegKind::SVEPredicateVector:
3072 case RegKind::SVEPredicateAsCounter:
3074 case RegKind::LookupTable:
3089 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3103 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3106 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3107 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3111 if (BadNum || CRNum > 15)
3112 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3116 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3125 unsigned MaxVal = 63;
3131 if (getParser().parseExpression(ImmVal))
3136 return TokError(
"immediate value expected for prefetch operand");
3139 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3142 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3143 Operands.push_back(AArch64Operand::CreatePrefetch(
3144 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3149 return TokError(
"prefetch hint expected");
3151 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3153 return TokError(
"prefetch hint expected");
3155 Operands.push_back(AArch64Operand::CreatePrefetch(
3156 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3162template <
bool IsSVEPrefetch>
3168 if (IsSVEPrefetch) {
3169 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3170 return std::optional<unsigned>(Res->Encoding);
3171 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3172 return std::optional<unsigned>(Res->Encoding);
3173 return std::optional<unsigned>();
3176 auto LookupByEncoding = [](
unsigned E) {
3177 if (IsSVEPrefetch) {
3178 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3179 return std::optional<StringRef>(Res->Name);
3180 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3181 return std::optional<StringRef>(Res->Name);
3182 return std::optional<StringRef>();
3184 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3191 if (getParser().parseExpression(ImmVal))
3196 return TokError(
"immediate value expected for prefetch operand");
3199 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3202 auto PRFM = LookupByEncoding(MCE->
getValue());
3203 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3209 return TokError(
"prefetch hint expected");
3211 auto PRFM = LookupByName(Tok.
getString());
3213 return TokError(
"prefetch hint expected");
3215 Operands.push_back(AArch64Operand::CreatePrefetch(
3216 *PRFM, Tok.
getString(), S, getContext()));
3226 return TokError(
"invalid operand for instruction");
3228 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3230 return TokError(
"invalid operand for instruction");
3232 Operands.push_back(AArch64Operand::CreatePSBHint(
3233 PSB->Encoding, Tok.
getString(), S, getContext()));
3239 SMLoc StartLoc = getLoc();
3245 auto RegTok = getTok();
3246 if (!tryParseScalarRegister(RegNum).isSuccess())
3249 if (RegNum != AArch64::XZR) {
3250 getLexer().UnLex(RegTok);
3257 if (!tryParseScalarRegister(RegNum).isSuccess())
3258 return TokError(
"expected register operand");
3260 if (RegNum != AArch64::XZR)
3261 return TokError(
"xzr must be followed by xzr");
3265 Operands.push_back(AArch64Operand::CreateReg(
3266 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3276 return TokError(
"invalid operand for instruction");
3278 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3280 return TokError(
"invalid operand for instruction");
3282 Operands.push_back(AArch64Operand::CreateBTIHint(
3283 BTI->Encoding, Tok.
getString(), S, getContext()));
3292 const MCExpr *Expr =
nullptr;
3298 if (parseSymbolicImmVal(Expr))
3304 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3314 return Error(S,
"gotpage label reference not allowed an addend");
3326 return Error(S,
"page or gotpage label reference expected");
3334 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3343 const MCExpr *Expr =
nullptr;
3352 if (parseSymbolicImmVal(Expr))
3358 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3371 return Error(S,
"unexpected adr label");
3376 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3381template <
bool AddFPZeroAsLiteral>
3394 return TokError(
"invalid floating point immediate");
3399 if (Tok.
getIntVal() > 255 || isNegative)
3400 return TokError(
"encoded floating point value out of range");
3404 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3407 APFloat RealVal(APFloat::IEEEdouble());
3409 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3411 return TokError(
"invalid floating point representation");
3414 RealVal.changeSign();
3416 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3417 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3418 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3420 Operands.push_back(AArch64Operand::CreateFPImm(
3421 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3446 if (parseSymbolicImmVal(Imm))
3450 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3457 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3459 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3461 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3467 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3468 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3476 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3478 int64_t ShiftAmount = getTok().getIntVal();
3480 if (ShiftAmount < 0)
3481 return Error(getLoc(),
"positive shift amount required");
3485 if (ShiftAmount == 0 && Imm !=
nullptr) {
3487 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3491 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3492 getLoc(), getContext()));
3499AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3536 Suggestion =
"nfrst";
3543 bool invertCondCode) {
3549 std::string Suggestion;
3552 std::string Msg =
"invalid condition code";
3553 if (!Suggestion.empty())
3554 Msg +=
", did you mean " + Suggestion +
"?";
3555 return TokError(Msg);
3559 if (invertCondCode) {
3561 return TokError(
"condition codes AL and NV are invalid for this instruction");
3566 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3575 return TokError(
"invalid operand for instruction");
3577 unsigned PStateImm = -1;
3578 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3581 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3582 PStateImm = SVCR->Encoding;
3585 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3596 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3598 unsigned ElementWidth = 0;
3599 auto DotPosition =
Name.find(
'.');
3601 const auto &KindRes =
3605 "Expected the register to be followed by element width suffix");
3606 ElementWidth = KindRes->second;
3608 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3609 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3614 if (parseOperand(
Operands,
false,
false))
3621 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3625 size_t DotPosition =
Name.find(
'.');
3633 .
Case(
"h", MatrixKind::Row)
3634 .
Case(
"v", MatrixKind::Col)
3641 "Expected the register to be followed by element width suffix");
3642 unsigned ElementWidth = KindRes->second;
3646 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3647 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3652 if (parseOperand(
Operands,
false,
false))
3694 return TokError(
"expected #imm after shift specifier");
3700 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3709 return Error(
E,
"expected integer shift amount");
3712 if (getParser().parseExpression(ImmVal))
3717 return Error(
E,
"expected constant '#imm' after shift specifier");
3720 Operands.push_back(AArch64Operand::CreateShiftExtend(
3721 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3729 {
"crc", {AArch64::FeatureCRC}},
3730 {
"sm4", {AArch64::FeatureSM4}},
3731 {
"sha3", {AArch64::FeatureSHA3}},
3732 {
"sha2", {AArch64::FeatureSHA2}},
3733 {
"aes", {AArch64::FeatureAES}},
3734 {
"crypto", {AArch64::FeatureCrypto}},
3735 {
"fp", {AArch64::FeatureFPARMv8}},
3736 {
"simd", {AArch64::FeatureNEON}},
3737 {
"ras", {AArch64::FeatureRAS}},
3738 {
"rasv2", {AArch64::FeatureRASv2}},
3739 {
"lse", {AArch64::FeatureLSE}},
3740 {
"predres", {AArch64::FeaturePredRes}},
3741 {
"predres2", {AArch64::FeatureSPECRES2}},
3742 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3743 {
"mte", {AArch64::FeatureMTE}},
3744 {
"memtag", {AArch64::FeatureMTE}},
3745 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3746 {
"pan", {AArch64::FeaturePAN}},
3747 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3748 {
"ccpp", {AArch64::FeatureCCPP}},
3749 {
"rcpc", {AArch64::FeatureRCPC}},
3750 {
"rng", {AArch64::FeatureRandGen}},
3751 {
"sve", {AArch64::FeatureSVE}},
3752 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3753 {
"sve2", {AArch64::FeatureSVE2}},
3754 {
"sve-aes", {AArch64::FeatureSVEAES}},
3755 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3756 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3757 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3758 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3760 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3761 AArch64::FeatureSVE2}},
3762 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3763 {
"ls64", {AArch64::FeatureLS64}},
3764 {
"xs", {AArch64::FeatureXS}},
3765 {
"pauth", {AArch64::FeaturePAuth}},
3766 {
"flagm", {AArch64::FeatureFlagM}},
3767 {
"rme", {AArch64::FeatureRME}},
3768 {
"sme", {AArch64::FeatureSME}},
3769 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3770 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3771 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3772 {
"sme2", {AArch64::FeatureSME2}},
3773 {
"sme2p1", {AArch64::FeatureSME2p1}},
3774 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3775 {
"hbc", {AArch64::FeatureHBC}},
3776 {
"mops", {AArch64::FeatureMOPS}},
3777 {
"mec", {AArch64::FeatureMEC}},
3778 {
"the", {AArch64::FeatureTHE}},
3779 {
"d128", {AArch64::FeatureD128}},
3780 {
"lse128", {AArch64::FeatureLSE128}},
3781 {
"ite", {AArch64::FeatureITE}},
3782 {
"cssc", {AArch64::FeatureCSSC}},
3783 {
"rcpc3", {AArch64::FeatureRCPC3}},
3784 {
"gcs", {AArch64::FeatureGCS}},
3785 {
"bf16", {AArch64::FeatureBF16}},
3786 {
"compnum", {AArch64::FeatureComplxNum}},
3787 {
"dotprod", {AArch64::FeatureDotProd}},
3788 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3789 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3790 {
"fp16", {AArch64::FeatureFullFP16}},
3791 {
"fp16fml", {AArch64::FeatureFP16FML}},
3792 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3793 {
"lor", {AArch64::FeatureLOR}},
3794 {
"profile", {AArch64::FeatureSPE}},
3798 {
"rdm", {AArch64::FeatureRDM}},
3799 {
"rdma", {AArch64::FeatureRDM}},
3800 {
"sb", {AArch64::FeatureSB}},
3801 {
"ssbs", {AArch64::FeatureSSBS}},
3802 {
"tme", {AArch64::FeatureTME}},
3803 {
"fp8", {AArch64::FeatureFP8}},
3804 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3805 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3806 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3807 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3808 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3809 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3810 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3811 {
"lut", {AArch64::FeatureLUT}},
3812 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3813 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3814 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3815 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3816 {
"cpa", {AArch64::FeatureCPA}},
3817 {
"tlbiw", {AArch64::FeatureTLBIW}},
3818 {
"pops", {AArch64::FeaturePoPS}},
3819 {
"cmpbr", {AArch64::FeatureCMPBR}},
3820 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3821 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3822 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3823 {
"lsfe", {AArch64::FeatureLSFE}},
3824 {
"sme2p2", {AArch64::FeatureSME2p2}},
3825 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3826 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3827 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3828 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3829 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3830 {
"lsui", {AArch64::FeatureLSUI}},
3831 {
"occmo", {AArch64::FeatureOCCMO}},
3832 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3833 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3834 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3835 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3839 if (FBS[AArch64::HasV8_0aOps])
3841 if (FBS[AArch64::HasV8_1aOps])
3843 else if (FBS[AArch64::HasV8_2aOps])
3845 else if (FBS[AArch64::HasV8_3aOps])
3847 else if (FBS[AArch64::HasV8_4aOps])
3849 else if (FBS[AArch64::HasV8_5aOps])
3851 else if (FBS[AArch64::HasV8_6aOps])
3853 else if (FBS[AArch64::HasV8_7aOps])
3855 else if (FBS[AArch64::HasV8_8aOps])
3857 else if (FBS[AArch64::HasV8_9aOps])
3859 else if (FBS[AArch64::HasV9_0aOps])
3861 else if (FBS[AArch64::HasV9_1aOps])
3863 else if (FBS[AArch64::HasV9_2aOps])
3865 else if (FBS[AArch64::HasV9_3aOps])
3867 else if (FBS[AArch64::HasV9_4aOps])
3869 else if (FBS[AArch64::HasV9_5aOps])
3871 else if (FBS[AArch64::HasV9_6aOps])
3873 else if (FBS[AArch64::HasV8_0rOps])
3882 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3889 const uint16_t Cm = (Encoding & 0x78) >> 3;
3890 const uint16_t Cn = (Encoding & 0x780) >> 7;
3891 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3896 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3898 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3900 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3903 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3910 if (
Name.contains(
'.'))
3911 return TokError(
"invalid operand");
3914 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3920 if (Mnemonic ==
"ic") {
3923 return TokError(
"invalid operand for IC instruction");
3924 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3925 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3927 return TokError(Str);
3930 }
else if (Mnemonic ==
"dc") {
3933 return TokError(
"invalid operand for DC instruction");
3934 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3935 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3937 return TokError(Str);
3940 }
else if (Mnemonic ==
"at") {
3943 return TokError(
"invalid operand for AT instruction");
3944 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3945 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3947 return TokError(Str);
3950 }
else if (Mnemonic ==
"tlbi") {
3953 return TokError(
"invalid operand for TLBI instruction");
3954 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3955 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3957 return TokError(Str);
3960 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3962 if (
Op.lower() !=
"rctx")
3963 return TokError(
"invalid operand for prediction restriction instruction");
3965 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3966 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3967 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3969 if (Mnemonic ==
"cosp" && !hasSpecres2)
3970 return TokError(
"COSP requires: predres2");
3972 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3974 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3975 : Mnemonic ==
"dvp" ? 0b101
3976 : Mnemonic ==
"cosp" ? 0b110
3977 : Mnemonic ==
"cpp" ? 0b111
3980 "Invalid mnemonic for prediction restriction instruction");
3981 const auto SYS_3_7_3 = 0b01101110011;
3982 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3984 createSysAlias(Encoding,
Operands, S);
3989 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3990 bool HasRegister =
false;
3995 return TokError(
"expected register operand");
3999 if (ExpectRegister && !HasRegister)
4000 return TokError(
"specified " + Mnemonic +
" op requires a register");
4001 else if (!ExpectRegister && HasRegister)
4002 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4014 if (
Name.contains(
'.'))
4015 return TokError(
"invalid operand");
4019 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
4025 if (Mnemonic ==
"tlbip") {
4026 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4027 if (HasnXSQualifier) {
4028 Op =
Op.drop_back(3);
4032 return TokError(
"invalid operand for TLBIP instruction");
4034 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4041 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
4042 std::string Str(
"TLBIP " +
Name +
" requires: ");
4044 return TokError(Str);
4055 return TokError(
"expected register identifier");
4060 return TokError(
"specified " + Mnemonic +
4061 " op requires a pair of registers");
4074 return TokError(
"'csync' operand expected");
4078 SMLoc ExprLoc = getLoc();
4080 if (getParser().parseExpression(ImmVal))
4084 return Error(ExprLoc,
"immediate value expected for barrier operand");
4086 if (Mnemonic ==
"dsb" &&
Value > 15) {
4093 if (Value < 0 || Value > 15)
4094 return Error(ExprLoc,
"barrier operand out of range");
4095 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4096 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4097 ExprLoc, getContext(),
4103 return TokError(
"invalid operand for instruction");
4106 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4107 auto DB = AArch64DB::lookupDBByName(Operand);
4109 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4110 return TokError(
"'sy' or #imm operand expected");
4112 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4113 return TokError(
"'csync' operand expected");
4115 if (Mnemonic ==
"dsb") {
4120 return TokError(
"invalid barrier option name");
4123 Operands.push_back(AArch64Operand::CreateBarrier(
4124 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4125 getContext(),
false ));
4135 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4136 if (Mnemonic !=
"dsb")
4142 SMLoc ExprLoc = getLoc();
4143 if (getParser().parseExpression(ImmVal))
4147 return Error(ExprLoc,
"immediate value expected for barrier operand");
4152 return Error(ExprLoc,
"barrier operand out of range");
4153 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4154 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4155 ExprLoc, getContext(),
4161 return TokError(
"invalid operand for instruction");
4164 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4167 return TokError(
"invalid barrier option name");
4170 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4171 getContext(),
true ));
4183 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4187 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4188 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4189 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4190 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4194 unsigned PStateImm = -1;
4195 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4196 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4197 PStateImm = PState15->Encoding;
4199 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4200 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4201 PStateImm = PState1->Encoding;
4205 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4206 PStateImm, getContext()));
4217 return TokError(
"invalid operand for instruction");
4221 return TokError(
"invalid operand for instruction");
4223 Operands.push_back(AArch64Operand::CreatePHintInst(
4224 PH->Encoding, Tok.
getString(), S, getContext()));
4238 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4246 unsigned ElementWidth = KindRes->second;
4248 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4249 S, getLoc(), getContext()));
4254 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4256 return tryParseVectorIndex(
Operands).isFailure();
4260 SMLoc SIdx = getLoc();
4263 if (getParser().parseExpression(ImmVal))
4267 return TokError(
"immediate value expected for vector index");
4274 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4287 RegKind MatchKind) {
4296 size_t Start = 0, Next =
Name.find(
'.');
4298 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4304 return TokError(
"invalid vector kind qualifier");
4315ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4318 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4320 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4325template <RegKind RK>
4329 const SMLoc S = getLoc();
4332 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4340 unsigned ElementWidth = KindRes->second;
4341 Operands.push_back(AArch64Operand::CreateVectorReg(
4342 RegNum, RK, ElementWidth, S,
4343 getLoc(), getContext()));
4346 if (RK == RegKind::SVEPredicateAsCounter) {
4353 if (parseOperand(
Operands,
false,
false))
4364 return Error(S,
"not expecting size suffix");
4367 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4372 auto Pred = getTok().getString().lower();
4373 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4374 return Error(getLoc(),
"expecting 'z' predication");
4376 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4377 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4380 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4381 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4390 if (!tryParseNeonVectorRegister(
Operands))
4393 if (tryParseZTOperand(
Operands).isSuccess())
4397 if (tryParseGPROperand<false>(
Operands).isSuccess())
4403bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4404 bool HasELFModifier =
false;
4408 HasELFModifier =
true;
4411 return TokError(
"expect relocation specifier in operand after ':'");
4413 std::string LowerCase = getTok().getIdentifier().lower();
4469 return TokError(
"expect relocation specifier in operand after ':'");
4473 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4477 if (getParser().parseExpression(ImmVal))
4490 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4493 size_t DotPosition =
Name.find(
'.');
4502 const std::optional<std::pair<int, int>> &KindRes =
4506 "Expected the register to be followed by element width suffix");
4507 ElementWidth = KindRes->second;
4514 auto LCurly = getTok();
4519 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4520 0, S, getLoc(), getContext()));
4525 if (getTok().getString().equals_insensitive(
"za")) {
4531 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4532 0xFF, S, getLoc(), getContext()));
4536 SMLoc TileLoc = getLoc();
4538 unsigned FirstReg, ElementWidth;
4539 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4540 if (!ParseRes.isSuccess()) {
4541 getLexer().UnLex(LCurly);
4547 unsigned PrevReg = FirstReg;
4550 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4553 SeenRegs.
insert(FirstReg);
4557 unsigned Reg, NextElementWidth;
4558 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4559 if (!ParseRes.isSuccess())
4563 if (ElementWidth != NextElementWidth)
4564 return Error(TileLoc,
"mismatched register size suffix");
4567 Warning(TileLoc,
"tile list not in ascending order");
4570 Warning(TileLoc,
"duplicate tile in list");
4573 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4582 unsigned RegMask = 0;
4583 for (
auto Reg : DRegs)
4587 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4592template <RegKind VectorKind>
4602 auto RegTok = getTok();
4603 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4604 if (ParseRes.isSuccess()) {
4611 RegTok.getString().equals_insensitive(
"zt0"))
4615 (ParseRes.isNoMatch() && NoMatchIsError &&
4616 !RegTok.getString().starts_with_insensitive(
"za")))
4617 return Error(Loc,
"vector register expected");
4622 int NumRegs = getNumRegsForRegKind(VectorKind);
4624 auto LCurly = getTok();
4629 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4633 if (ParseRes.isNoMatch())
4636 if (!ParseRes.isSuccess())
4639 int64_t PrevReg = FirstReg;
4644 SMLoc Loc = getLoc();
4648 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4649 if (!ParseRes.isSuccess())
4653 if (Kind != NextKind)
4654 return Error(Loc,
"mismatched register size suffix");
4657 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4659 if (Space == 0 || Space > 3)
4660 return Error(Loc,
"invalid number of vectors");
4665 bool HasCalculatedStride =
false;
4667 SMLoc Loc = getLoc();
4670 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4671 if (!ParseRes.isSuccess())
4675 if (Kind != NextKind)
4676 return Error(Loc,
"mismatched register size suffix");
4678 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4679 unsigned PrevRegVal =
4680 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4681 if (!HasCalculatedStride) {
4682 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4683 : (RegVal + NumRegs - PrevRegVal);
4684 HasCalculatedStride =
true;
4688 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4689 return Error(Loc,
"registers must have the same sequential stride");
4700 return Error(S,
"invalid number of vectors");
4702 unsigned NumElements = 0;
4703 unsigned ElementWidth = 0;
4704 if (!
Kind.empty()) {
4706 std::tie(NumElements, ElementWidth) = *VK;
4709 Operands.push_back(AArch64Operand::CreateVectorList(
4710 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4711 getLoc(), getContext()));
4718 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4719 if (!ParseRes.isSuccess())
4722 return tryParseVectorIndex(
Operands).isFailure();
4726 SMLoc StartLoc = getLoc();
4734 Operands.push_back(AArch64Operand::CreateReg(
4735 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4742 return Error(getLoc(),
"index must be absent or #0");
4745 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4746 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4747 return Error(getLoc(),
"index must be absent or #0");
4749 Operands.push_back(AArch64Operand::CreateReg(
4750 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4755 SMLoc StartLoc = getLoc();
4759 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4764 Operands.push_back(AArch64Operand::CreateReg(
4765 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4771 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4773 if (getParser().parseExpression(ImmVal))
4777 return TokError(
"immediate value expected for vector index");
4778 Operands.push_back(AArch64Operand::CreateImm(
4780 getLoc(), getContext()));
4782 if (parseOptionalMulOperand(
Operands))
4787 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4792template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4794 SMLoc StartLoc = getLoc();
4803 Operands.push_back(AArch64Operand::CreateReg(
4804 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4813 Res = tryParseOptionalShiftExtend(ExtOpnd);
4817 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4818 Operands.push_back(AArch64Operand::CreateReg(
4819 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4820 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4821 Ext->hasShiftExtendAmount()));
4835 if (!getTok().getString().equals_insensitive(
"mul") ||
4836 !(NextIsVL || NextIsHash))
4840 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4845 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4857 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4858 Operands.push_back(AArch64Operand::CreateImm(
4865 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4871 auto Tok = Parser.
getTok();
4876 .
Case(
"vgx2",
"vgx2")
4877 .
Case(
"vgx4",
"vgx4")
4889 auto Tok = getTok();
4899 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4908 bool invertCondCode) {
4912 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4926 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4931 getLexer().UnLex(SavedTok);
4935 switch (getLexer().getKind()) {
4939 if (parseSymbolicImmVal(Expr))
4940 return Error(S,
"invalid operand");
4943 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4944 return parseOptionalShiftExtend(getTok());
4948 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4953 return parseOperand(
Operands,
false,
false);
4956 if (!parseNeonVectorList(
Operands))
4960 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4965 return parseOperand(
Operands,
false,
false);
4970 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4972 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4977 return parseCondCode(
Operands, invertCondCode);
4991 Res = tryParseOptionalShiftExtend(
Operands);
4994 getLexer().UnLex(SavedTok);
5001 if (!parseOptionalMulOperand(
Operands))
5006 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5008 return parseKeywordOperand(
Operands);
5014 if (getParser().parseExpression(IdVal))
5017 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
5029 bool isNegative =
false;
5045 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5046 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5047 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5048 return TokError(
"unexpected floating point literal");
5049 else if (IntVal != 0 || isNegative)
5050 return TokError(
"expected floating-point constant #0.0");
5053 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
5054 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
5059 if (parseSymbolicImmVal(ImmVal))
5063 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
5066 return parseOptionalShiftExtend(Tok);
5069 SMLoc Loc = getLoc();
5070 if (Mnemonic !=
"ldr")
5071 return TokError(
"unexpected token in operand");
5073 const MCExpr *SubExprVal;
5074 if (getParser().parseExpression(SubExprVal))
5078 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5079 return Error(Loc,
"Only valid when first operand is register");
5082 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5088 if (isa<MCConstantExpr>(SubExprVal)) {
5089 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
5090 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5095 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5096 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5097 Operands.push_back(AArch64Operand::CreateImm(
5101 ShiftAmt,
true, S, E, Ctx));
5107 return Error(Loc,
"Immediate too large for register");
5111 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5112 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
5118bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5119 const MCExpr *Expr =
nullptr;
5121 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5124 if (check(!
Value, L,
"expected constant expression"))
5126 Out =
Value->getValue();
5130bool AArch64AsmParser::parseComma() {
5138bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5142 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5147 unsigned RangeEnd =
Last;
5148 if (
Base == AArch64::X0) {
5149 if (
Last == AArch64::FP) {
5150 RangeEnd = AArch64::X28;
5151 if (Reg == AArch64::FP) {
5156 if (
Last == AArch64::LR) {
5157 RangeEnd = AArch64::X28;
5158 if (Reg == AArch64::FP) {
5161 }
else if (Reg == AArch64::LR) {
5168 if (check(Reg < First || Reg > RangeEnd, Start,
5169 Twine(
"expected register in range ") +
5179 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5180 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5182 if (AOp1.isVectorList() && AOp2.isVectorList())
5183 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5184 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5185 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5187 if (!AOp1.isReg() || !AOp2.isReg())
5190 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5191 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5194 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5195 "Testing equality of non-scalar registers not supported");
5198 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5200 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5202 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5204 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5215 .
Case(
"beq",
"b.eq")
5216 .
Case(
"bne",
"b.ne")
5217 .
Case(
"bhs",
"b.hs")
5218 .
Case(
"bcs",
"b.cs")
5219 .
Case(
"blo",
"b.lo")
5220 .
Case(
"bcc",
"b.cc")
5221 .
Case(
"bmi",
"b.mi")
5222 .
Case(
"bpl",
"b.pl")
5223 .
Case(
"bvs",
"b.vs")
5224 .
Case(
"bvc",
"b.vc")
5225 .
Case(
"bhi",
"b.hi")
5226 .
Case(
"bls",
"b.ls")
5227 .
Case(
"bge",
"b.ge")
5228 .
Case(
"blt",
"b.lt")
5229 .
Case(
"bgt",
"b.gt")
5230 .
Case(
"ble",
"b.le")
5231 .
Case(
"bal",
"b.al")
5232 .
Case(
"bnv",
"b.nv")
5237 getTok().getIdentifier().lower() ==
".req") {
5238 parseDirectiveReq(
Name, NameLoc);
5245 size_t Start = 0, Next =
Name.find(
'.');
5250 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5251 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5252 return parseSysAlias(Head, NameLoc,
Operands);
5255 if (Head ==
"tlbip")
5256 return parseSyspAlias(Head, NameLoc,
Operands);
5258 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5264 Next =
Name.find(
'.', Start + 1);
5265 Head =
Name.slice(Start + 1, Next);
5269 std::string Suggestion;
5272 std::string Msg =
"invalid condition code";
5273 if (!Suggestion.empty())
5274 Msg +=
", did you mean " + Suggestion +
"?";
5275 return Error(SuffixLoc, Msg);
5277 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5280 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5286 Next =
Name.find(
'.', Start + 1);
5287 Head =
Name.slice(Start, Next);
5290 Operands.push_back(AArch64Operand::CreateToken(
5291 Head, SuffixLoc, getContext(),
true));
5296 bool condCodeFourthOperand =
5297 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5298 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5299 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5307 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5308 bool condCodeThirdOperand =
5309 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5317 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5318 (
N == 3 && condCodeThirdOperand) ||
5319 (
N == 2 && condCodeSecondOperand),
5320 condCodeSecondOperand || condCodeThirdOperand)) {
5340 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5343 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5346 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5359 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5360 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5361 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5362 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5363 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5364 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5365 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5371bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5380 PrefixInfo
Prefix = NextPrefix;
5381 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5393 return Error(IDLoc,
"instruction is unpredictable when following a"
5394 " movprfx, suggest replacing movprfx with mov");
5398 return Error(Loc[0],
"instruction is unpredictable when following a"
5399 " movprfx writing to a different destination");
5406 return Error(Loc[0],
"instruction is unpredictable when following a"
5407 " movprfx and destination also used as non-destructive"
5411 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5412 if (
Prefix.isPredicated()) {
5426 return Error(IDLoc,
"instruction is unpredictable when following a"
5427 " predicated movprfx, suggest using unpredicated movprfx");
5431 return Error(IDLoc,
"instruction is unpredictable when following a"
5432 " predicated movprfx using a different general predicate");
5436 return Error(IDLoc,
"instruction is unpredictable when following a"
5437 " predicated movprfx with a different element size");
5443 if (IsWindowsArm64EC) {
5449 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5450 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5451 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5452 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5453 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5454 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5455 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5456 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5457 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5458 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5460 " is disallowed on ARM64EC.");
5470 case AArch64::LDPSWpre:
5471 case AArch64::LDPWpost:
5472 case AArch64::LDPWpre:
5473 case AArch64::LDPXpost:
5474 case AArch64::LDPXpre: {
5479 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5480 "is also a destination");
5482 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5483 "is also a destination");
5486 case AArch64::LDR_ZA:
5487 case AArch64::STR_ZA: {
5490 return Error(Loc[1],
5491 "unpredictable instruction, immediate and offset mismatch.");
5494 case AArch64::LDPDi:
5495 case AArch64::LDPQi:
5496 case AArch64::LDPSi:
5497 case AArch64::LDPSWi:
5498 case AArch64::LDPWi:
5499 case AArch64::LDPXi: {
5503 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5506 case AArch64::LDPDpost:
5507 case AArch64::LDPDpre:
5508 case AArch64::LDPQpost:
5509 case AArch64::LDPQpre:
5510 case AArch64::LDPSpost:
5511 case AArch64::LDPSpre:
5512 case AArch64::LDPSWpost: {
5516 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5519 case AArch64::STPDpost:
5520 case AArch64::STPDpre:
5521 case AArch64::STPQpost:
5522 case AArch64::STPQpre:
5523 case AArch64::STPSpost:
5524 case AArch64::STPSpre:
5525 case AArch64::STPWpost:
5526 case AArch64::STPWpre:
5527 case AArch64::STPXpost:
5528 case AArch64::STPXpre: {
5533 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5534 "is also a source");
5536 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5537 "is also a source");
5540 case AArch64::LDRBBpre:
5541 case AArch64::LDRBpre:
5542 case AArch64::LDRHHpre:
5543 case AArch64::LDRHpre:
5544 case AArch64::LDRSBWpre:
5545 case AArch64::LDRSBXpre:
5546 case AArch64::LDRSHWpre:
5547 case AArch64::LDRSHXpre:
5548 case AArch64::LDRSWpre:
5549 case AArch64::LDRWpre:
5550 case AArch64::LDRXpre:
5551 case AArch64::LDRBBpost:
5552 case AArch64::LDRBpost:
5553 case AArch64::LDRHHpost:
5554 case AArch64::LDRHpost:
5555 case AArch64::LDRSBWpost:
5556 case AArch64::LDRSBXpost:
5557 case AArch64::LDRSHWpost:
5558 case AArch64::LDRSHXpost:
5559 case AArch64::LDRSWpost:
5560 case AArch64::LDRWpost:
5561 case AArch64::LDRXpost: {
5565 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5566 "is also a source");
5569 case AArch64::STRBBpost:
5570 case AArch64::STRBpost:
5571 case AArch64::STRHHpost:
5572 case AArch64::STRHpost:
5573 case AArch64::STRWpost:
5574 case AArch64::STRXpost:
5575 case AArch64::STRBBpre:
5576 case AArch64::STRBpre:
5577 case AArch64::STRHHpre:
5578 case AArch64::STRHpre:
5579 case AArch64::STRWpre:
5580 case AArch64::STRXpre: {
5584 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5585 "is also a source");
5588 case AArch64::STXRB:
5589 case AArch64::STXRH:
5590 case AArch64::STXRW:
5591 case AArch64::STXRX:
5592 case AArch64::STLXRB:
5593 case AArch64::STLXRH:
5594 case AArch64::STLXRW:
5595 case AArch64::STLXRX: {
5601 return Error(Loc[0],
5602 "unpredictable STXR instruction, status is also a source");
5605 case AArch64::STXPW:
5606 case AArch64::STXPX:
5607 case AArch64::STLXPW:
5608 case AArch64::STLXPX: {
5615 return Error(Loc[0],
5616 "unpredictable STXP instruction, status is also a source");
5619 case AArch64::LDRABwriteback:
5620 case AArch64::LDRAAwriteback: {
5624 return Error(Loc[0],
5625 "unpredictable LDRA instruction, writeback base"
5626 " is also a destination");
5633 case AArch64::CPYFP:
5634 case AArch64::CPYFPWN:
5635 case AArch64::CPYFPRN:
5636 case AArch64::CPYFPN:
5637 case AArch64::CPYFPWT:
5638 case AArch64::CPYFPWTWN:
5639 case AArch64::CPYFPWTRN:
5640 case AArch64::CPYFPWTN:
5641 case AArch64::CPYFPRT:
5642 case AArch64::CPYFPRTWN:
5643 case AArch64::CPYFPRTRN:
5644 case AArch64::CPYFPRTN:
5645 case AArch64::CPYFPT:
5646 case AArch64::CPYFPTWN:
5647 case AArch64::CPYFPTRN:
5648 case AArch64::CPYFPTN:
5649 case AArch64::CPYFM:
5650 case AArch64::CPYFMWN:
5651 case AArch64::CPYFMRN:
5652 case AArch64::CPYFMN:
5653 case AArch64::CPYFMWT:
5654 case AArch64::CPYFMWTWN:
5655 case AArch64::CPYFMWTRN:
5656 case AArch64::CPYFMWTN:
5657 case AArch64::CPYFMRT:
5658 case AArch64::CPYFMRTWN:
5659 case AArch64::CPYFMRTRN:
5660 case AArch64::CPYFMRTN:
5661 case AArch64::CPYFMT:
5662 case AArch64::CPYFMTWN:
5663 case AArch64::CPYFMTRN:
5664 case AArch64::CPYFMTN:
5665 case AArch64::CPYFE:
5666 case AArch64::CPYFEWN:
5667 case AArch64::CPYFERN:
5668 case AArch64::CPYFEN:
5669 case AArch64::CPYFEWT:
5670 case AArch64::CPYFEWTWN:
5671 case AArch64::CPYFEWTRN:
5672 case AArch64::CPYFEWTN:
5673 case AArch64::CPYFERT:
5674 case AArch64::CPYFERTWN:
5675 case AArch64::CPYFERTRN:
5676 case AArch64::CPYFERTN:
5677 case AArch64::CPYFET:
5678 case AArch64::CPYFETWN:
5679 case AArch64::CPYFETRN:
5680 case AArch64::CPYFETN:
5682 case AArch64::CPYPWN:
5683 case AArch64::CPYPRN:
5684 case AArch64::CPYPN:
5685 case AArch64::CPYPWT:
5686 case AArch64::CPYPWTWN:
5687 case AArch64::CPYPWTRN:
5688 case AArch64::CPYPWTN:
5689 case AArch64::CPYPRT:
5690 case AArch64::CPYPRTWN:
5691 case AArch64::CPYPRTRN:
5692 case AArch64::CPYPRTN:
5693 case AArch64::CPYPT:
5694 case AArch64::CPYPTWN:
5695 case AArch64::CPYPTRN:
5696 case AArch64::CPYPTN:
5698 case AArch64::CPYMWN:
5699 case AArch64::CPYMRN:
5700 case AArch64::CPYMN:
5701 case AArch64::CPYMWT:
5702 case AArch64::CPYMWTWN:
5703 case AArch64::CPYMWTRN:
5704 case AArch64::CPYMWTN:
5705 case AArch64::CPYMRT:
5706 case AArch64::CPYMRTWN:
5707 case AArch64::CPYMRTRN:
5708 case AArch64::CPYMRTN:
5709 case AArch64::CPYMT:
5710 case AArch64::CPYMTWN:
5711 case AArch64::CPYMTRN:
5712 case AArch64::CPYMTN:
5714 case AArch64::CPYEWN:
5715 case AArch64::CPYERN:
5716 case AArch64::CPYEN:
5717 case AArch64::CPYEWT:
5718 case AArch64::CPYEWTWN:
5719 case AArch64::CPYEWTRN:
5720 case AArch64::CPYEWTN:
5721 case AArch64::CPYERT:
5722 case AArch64::CPYERTWN:
5723 case AArch64::CPYERTRN:
5724 case AArch64::CPYERTN:
5725 case AArch64::CPYET:
5726 case AArch64::CPYETWN:
5727 case AArch64::CPYETRN:
5728 case AArch64::CPYETN: {
5736 return Error(Loc[0],
5737 "invalid CPY instruction, Xd_wb and Xd do not match");
5739 return Error(Loc[0],
5740 "invalid CPY instruction, Xs_wb and Xs do not match");
5742 return Error(Loc[0],
5743 "invalid CPY instruction, Xn_wb and Xn do not match");
5745 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5746 " registers are the same");
5748 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5749 " registers are the same");
5751 return Error(Loc[0],
"invalid CPY instruction, source and size"
5752 " registers are the same");
5756 case AArch64::SETPT:
5757 case AArch64::SETPN:
5758 case AArch64::SETPTN:
5760 case AArch64::SETMT:
5761 case AArch64::SETMN:
5762 case AArch64::SETMTN:
5764 case AArch64::SETET:
5765 case AArch64::SETEN:
5766 case AArch64::SETETN:
5767 case AArch64::SETGP:
5768 case AArch64::SETGPT:
5769 case AArch64::SETGPN:
5770 case AArch64::SETGPTN:
5771 case AArch64::SETGM:
5772 case AArch64::SETGMT:
5773 case AArch64::SETGMN:
5774 case AArch64::SETGMTN:
5775 case AArch64::MOPSSETGE:
5776 case AArch64::MOPSSETGET:
5777 case AArch64::MOPSSETGEN:
5778 case AArch64::MOPSSETGETN: {
5785 return Error(Loc[0],
5786 "invalid SET instruction, Xd_wb and Xd do not match");
5788 return Error(Loc[0],
5789 "invalid SET instruction, Xn_wb and Xn do not match");
5791 return Error(Loc[0],
"invalid SET instruction, destination and size"
5792 " registers are the same");
5794 return Error(Loc[0],
"invalid SET instruction, destination and source"
5795 " registers are the same");
5797 return Error(Loc[0],
"invalid SET instruction, source and size"
5798 " registers are the same");
5807 case AArch64::ADDSWri:
5808 case AArch64::ADDSXri:
5809 case AArch64::ADDWri:
5810 case AArch64::ADDXri:
5811 case AArch64::SUBSWri:
5812 case AArch64::SUBSXri:
5813 case AArch64::SUBWri:
5814 case AArch64::SUBXri: {
5822 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5851 return Error(Loc.
back(),
"invalid immediate expression");
5864 unsigned VariantID = 0);
5866bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5870 case Match_InvalidTiedOperand: {
5872 if (
Op.isVectorList())
5873 return Error(Loc,
"operand must match destination register list");
5875 assert(
Op.isReg() &&
"Unexpected operand type");
5876 switch (
Op.getRegEqualityTy()) {
5877 case RegConstraintEqualityTy::EqualsSubReg:
5878 return Error(Loc,
"operand must be 64-bit form of destination register");
5879 case RegConstraintEqualityTy::EqualsSuperReg:
5880 return Error(Loc,
"operand must be 32-bit form of destination register");
5881 case RegConstraintEqualityTy::EqualsReg:
5882 return Error(Loc,
"operand must match destination register");
5886 case Match_MissingFeature:
5888 "instruction requires a CPU feature not currently enabled");
5889 case Match_InvalidOperand:
5890 return Error(Loc,
"invalid operand for instruction");
5891 case Match_InvalidSuffix:
5892 return Error(Loc,
"invalid type suffix for instruction");
5893 case Match_InvalidCondCode:
5894 return Error(Loc,
"expected AArch64 condition code");
5895 case Match_AddSubRegExtendSmall:
5897 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5898 case Match_AddSubRegExtendLarge:
5900 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5901 case Match_AddSubSecondSource:
5903 "expected compatible register, symbol or integer in range [0, 4095]");
5904 case Match_LogicalSecondSource:
5905 return Error(Loc,
"expected compatible register or logical immediate");
5906 case Match_InvalidMovImm32Shift:
5907 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5908 case Match_InvalidMovImm64Shift:
5909 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5910 case Match_AddSubRegShift32:
5912 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5913 case Match_AddSubRegShift64:
5915 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5916 case Match_InvalidFPImm:
5918 "expected compatible register or floating-point constant");
5919 case Match_InvalidMemoryIndexedSImm6:
5920 return Error(Loc,
"index must be an integer in range [-32, 31].");
5921 case Match_InvalidMemoryIndexedSImm5:
5922 return Error(Loc,
"index must be an integer in range [-16, 15].");
5923 case Match_InvalidMemoryIndexed1SImm4:
5924 return Error(Loc,
"index must be an integer in range [-8, 7].");
5925 case Match_InvalidMemoryIndexed2SImm4:
5926 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5927 case Match_InvalidMemoryIndexed3SImm4:
5928 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5929 case Match_InvalidMemoryIndexed4SImm4:
5930 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5931 case Match_InvalidMemoryIndexed16SImm4:
5932 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5933 case Match_InvalidMemoryIndexed32SImm4:
5934 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5935 case Match_InvalidMemoryIndexed1SImm6:
5936 return Error(Loc,
"index must be an integer in range [-32, 31].");
5937 case Match_InvalidMemoryIndexedSImm8:
5938 return Error(Loc,
"index must be an integer in range [-128, 127].");
5939 case Match_InvalidMemoryIndexedSImm9:
5940 return Error(Loc,
"index must be an integer in range [-256, 255].");
5941 case Match_InvalidMemoryIndexed16SImm9:
5942 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5943 case Match_InvalidMemoryIndexed8SImm10:
5944 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5945 case Match_InvalidMemoryIndexed4SImm7:
5946 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5947 case Match_InvalidMemoryIndexed8SImm7:
5948 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5949 case Match_InvalidMemoryIndexed16SImm7:
5950 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5951 case Match_InvalidMemoryIndexed8UImm5:
5952 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5953 case Match_InvalidMemoryIndexed8UImm3:
5954 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5955 case Match_InvalidMemoryIndexed4UImm5:
5956 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5957 case Match_InvalidMemoryIndexed2UImm5:
5958 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5959 case Match_InvalidMemoryIndexed8UImm6:
5960 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5961 case Match_InvalidMemoryIndexed16UImm6:
5962 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5963 case Match_InvalidMemoryIndexed4UImm6:
5964 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5965 case Match_InvalidMemoryIndexed2UImm6:
5966 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5967 case Match_InvalidMemoryIndexed1UImm6:
5968 return Error(Loc,
"index must be in range [0, 63].");
5969 case Match_InvalidMemoryWExtend8:
5971 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5972 case Match_InvalidMemoryWExtend16:
5974 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5975 case Match_InvalidMemoryWExtend32:
5977 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5978 case Match_InvalidMemoryWExtend64:
5980 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5981 case Match_InvalidMemoryWExtend128:
5983 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5984 case Match_InvalidMemoryXExtend8:
5986 "expected 'lsl' or 'sxtx' with optional shift of #0");
5987 case Match_InvalidMemoryXExtend16:
5989 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5990 case Match_InvalidMemoryXExtend32:
5992 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5993 case Match_InvalidMemoryXExtend64:
5995 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5996 case Match_InvalidMemoryXExtend128:
5998 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5999 case Match_InvalidMemoryIndexed1:
6000 return Error(Loc,
"index must be an integer in range [0, 4095].");
6001 case Match_InvalidMemoryIndexed2:
6002 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6003 case Match_InvalidMemoryIndexed4:
6004 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6005 case Match_InvalidMemoryIndexed8:
6006 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6007 case Match_InvalidMemoryIndexed16:
6008 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6009 case Match_InvalidImm0_0:
6010 return Error(Loc,
"immediate must be 0.");
6011 case Match_InvalidImm0_1:
6012 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6013 case Match_InvalidImm0_3:
6014 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6015 case Match_InvalidImm0_7:
6016 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6017 case Match_InvalidImm0_15:
6018 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6019 case Match_InvalidImm0_31:
6020 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6021 case Match_InvalidImm0_63:
6022 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6023 case Match_InvalidImm0_127:
6024 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6025 case Match_InvalidImm0_255:
6026 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6027 case Match_InvalidImm0_65535:
6028 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6029 case Match_InvalidImm1_8:
6030 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6031 case Match_InvalidImm1_16:
6032 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6033 case Match_InvalidImm1_32:
6034 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6035 case Match_InvalidImm1_64:
6036 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6037 case Match_InvalidImmM1_62:
6038 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6039 case Match_InvalidMemoryIndexedRange2UImm0:
6040 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6041 case Match_InvalidMemoryIndexedRange2UImm1:
6042 return Error(Loc,
"vector select offset must be an immediate range of the "
6043 "form <immf>:<imml>, where the first "
6044 "immediate is a multiple of 2 in the range [0, 2], and "
6045 "the second immediate is immf + 1.");
6046 case Match_InvalidMemoryIndexedRange2UImm2:
6047 case Match_InvalidMemoryIndexedRange2UImm3:
6050 "vector select offset must be an immediate range of the form "
6052 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6054 "depending on the instruction, and the second immediate is immf + 1.");
6055 case Match_InvalidMemoryIndexedRange4UImm0:
6056 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6057 case Match_InvalidMemoryIndexedRange4UImm1:
6058 case Match_InvalidMemoryIndexedRange4UImm2:
6061 "vector select offset must be an immediate range of the form "
6063 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6065 "depending on the instruction, and the second immediate is immf + 3.");
6066 case Match_InvalidSVEAddSubImm8:
6067 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6068 " with a shift amount of 0");
6069 case Match_InvalidSVEAddSubImm16:
6070 case Match_InvalidSVEAddSubImm32:
6071 case Match_InvalidSVEAddSubImm64:
6072 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6073 "multiple of 256 in range [256, 65280]");
6074 case Match_InvalidSVECpyImm8:
6075 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6076 " with a shift amount of 0");
6077 case Match_InvalidSVECpyImm16:
6078 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6079 "multiple of 256 in range [-32768, 65280]");
6080 case Match_InvalidSVECpyImm32:
6081 case Match_InvalidSVECpyImm64:
6082 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6083 "multiple of 256 in range [-32768, 32512]");
6084 case Match_InvalidIndexRange0_0:
6085 return Error(Loc,
"expected lane specifier '[0]'");
6086 case Match_InvalidIndexRange1_1:
6087 return Error(Loc,
"expected lane specifier '[1]'");
6088 case Match_InvalidIndexRange0_15:
6089 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6090 case Match_InvalidIndexRange0_7:
6091 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6092 case Match_InvalidIndexRange0_3:
6093 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6094 case Match_InvalidIndexRange0_1:
6095 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6096 case Match_InvalidSVEIndexRange0_63:
6097 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6098 case Match_InvalidSVEIndexRange0_31:
6099 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6100 case Match_InvalidSVEIndexRange0_15:
6101 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6102 case Match_InvalidSVEIndexRange0_7:
6103 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6104 case Match_InvalidSVEIndexRange0_3:
6105 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6106 case Match_InvalidLabel:
6107 return Error(Loc,
"expected label or encodable integer pc offset");
6109 return Error(Loc,
"expected readable system register");
6111 case Match_InvalidSVCR:
6112 return Error(Loc,
"expected writable system register or pstate");
6113 case Match_InvalidComplexRotationEven:
6114 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6115 case Match_InvalidComplexRotationOdd:
6116 return Error(Loc,
"complex rotation must be 90 or 270.");
6117 case Match_MnemonicFail: {
6119 ((AArch64Operand &)*
Operands[0]).getToken(),
6120 ComputeAvailableFeatures(STI->getFeatureBits()));
6121 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6123 case Match_InvalidGPR64shifted8:
6124 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6125 case Match_InvalidGPR64shifted16:
6126 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6127 case Match_InvalidGPR64shifted32:
6128 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6129 case Match_InvalidGPR64shifted64:
6130 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6131 case Match_InvalidGPR64shifted128:
6133 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6134 case Match_InvalidGPR64NoXZRshifted8:
6135 return Error(Loc,
"register must be x0..x30 without shift");
6136 case Match_InvalidGPR64NoXZRshifted16:
6137 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6138 case Match_InvalidGPR64NoXZRshifted32:
6139 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6140 case Match_InvalidGPR64NoXZRshifted64:
6141 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6142 case Match_InvalidGPR64NoXZRshifted128:
6143 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6144 case Match_InvalidZPR32UXTW8:
6145 case Match_InvalidZPR32SXTW8:
6146 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6147 case Match_InvalidZPR32UXTW16:
6148 case Match_InvalidZPR32SXTW16:
6149 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6150 case Match_InvalidZPR32UXTW32:
6151 case Match_InvalidZPR32SXTW32:
6152 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6153 case Match_InvalidZPR32UXTW64:
6154 case Match_InvalidZPR32SXTW64:
6155 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6156 case Match_InvalidZPR64UXTW8:
6157 case Match_InvalidZPR64SXTW8:
6158 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6159 case Match_InvalidZPR64UXTW16:
6160 case Match_InvalidZPR64SXTW16:
6161 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6162 case Match_InvalidZPR64UXTW32:
6163 case Match_InvalidZPR64SXTW32:
6164 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6165 case Match_InvalidZPR64UXTW64:
6166 case Match_InvalidZPR64SXTW64:
6167 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6168 case Match_InvalidZPR32LSL8:
6169 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6170 case Match_InvalidZPR32LSL16:
6171 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6172 case Match_InvalidZPR32LSL32:
6173 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6174 case Match_InvalidZPR32LSL64:
6175 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6176 case Match_InvalidZPR64LSL8:
6177 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6178 case Match_InvalidZPR64LSL16:
6179 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6180 case Match_InvalidZPR64LSL32:
6181 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6182 case Match_InvalidZPR64LSL64:
6183 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6184 case Match_InvalidZPR0:
6185 return Error(Loc,
"expected register without element width suffix");
6186 case Match_InvalidZPR8:
6187 case Match_InvalidZPR16:
6188 case Match_InvalidZPR32:
6189 case Match_InvalidZPR64:
6190 case Match_InvalidZPR128:
6191 return Error(Loc,
"invalid element width");
6192 case Match_InvalidZPR_3b8:
6193 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6194 case Match_InvalidZPR_3b16:
6195 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6196 case Match_InvalidZPR_3b32:
6197 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6198 case Match_InvalidZPR_4b8:
6200 "Invalid restricted vector register, expected z0.b..z15.b");
6201 case Match_InvalidZPR_4b16:
6202 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6203 case Match_InvalidZPR_4b32:
6204 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6205 case Match_InvalidZPR_4b64:
6206 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6207 case Match_InvalidZPRMul2_Lo8:
6208 return Error(Loc,
"Invalid restricted vector register, expected even "
6209 "register in z0.b..z14.b");
6210 case Match_InvalidZPRMul2_Hi8:
6211 return Error(Loc,
"Invalid restricted vector register, expected even "
6212 "register in z16.b..z30.b");
6213 case Match_InvalidZPRMul2_Lo16:
6214 return Error(Loc,
"Invalid restricted vector register, expected even "
6215 "register in z0.h..z14.h");
6216 case Match_InvalidZPRMul2_Hi16:
6217 return Error(Loc,
"Invalid restricted vector register, expected even "
6218 "register in z16.h..z30.h");
6219 case Match_InvalidZPRMul2_Lo32:
6220 return Error(Loc,
"Invalid restricted vector register, expected even "
6221 "register in z0.s..z14.s");
6222 case Match_InvalidZPRMul2_Hi32:
6223 return Error(Loc,
"Invalid restricted vector register, expected even "
6224 "register in z16.s..z30.s");
6225 case Match_InvalidZPRMul2_Lo64:
6226 return Error(Loc,
"Invalid restricted vector register, expected even "
6227 "register in z0.d..z14.d");
6228 case Match_InvalidZPRMul2_Hi64:
6229 return Error(Loc,
"Invalid restricted vector register, expected even "
6230 "register in z16.d..z30.d");
6231 case Match_InvalidZPR_K0:
6232 return Error(Loc,
"invalid restricted vector register, expected register "
6233 "in z20..z23 or z28..z31");
6234 case Match_InvalidSVEPattern:
6235 return Error(Loc,
"invalid predicate pattern");
6236 case Match_InvalidSVEPPRorPNRAnyReg:
6237 case Match_InvalidSVEPPRorPNRBReg:
6238 case Match_InvalidSVEPredicateAnyReg:
6239 case Match_InvalidSVEPredicateBReg:
6240 case Match_InvalidSVEPredicateHReg:
6241 case Match_InvalidSVEPredicateSReg:
6242 case Match_InvalidSVEPredicateDReg:
6243 return Error(Loc,
"invalid predicate register.");
6244 case Match_InvalidSVEPredicate3bAnyReg:
6245 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6246 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6247 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6248 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6249 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6250 return Error(Loc,
"Invalid predicate register, expected PN in range "
6251 "pn8..pn15 with element suffix.");
6252 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6253 return Error(Loc,
"invalid restricted predicate-as-counter register "
6254 "expected pn8..pn15");
6255 case Match_InvalidSVEPNPredicateBReg:
6256 case Match_InvalidSVEPNPredicateHReg:
6257 case Match_InvalidSVEPNPredicateSReg:
6258 case Match_InvalidSVEPNPredicateDReg:
6259 return Error(Loc,
"Invalid predicate register, expected PN in range "
6260 "pn0..pn15 with element suffix.");
6261 case Match_InvalidSVEVecLenSpecifier:
6262 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6263 case Match_InvalidSVEPredicateListMul2x8:
6264 case Match_InvalidSVEPredicateListMul2x16:
6265 case Match_InvalidSVEPredicateListMul2x32:
6266 case Match_InvalidSVEPredicateListMul2x64:
6267 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6268 "predicate registers, where the first vector is a multiple of 2 "
6269 "and with correct element type");
6270 case Match_InvalidSVEExactFPImmOperandHalfOne:
6271 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6272 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6273 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6274 case Match_InvalidSVEExactFPImmOperandZeroOne:
6275 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6276 case Match_InvalidMatrixTileVectorH8:
6277 case Match_InvalidMatrixTileVectorV8:
6278 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6279 case Match_InvalidMatrixTileVectorH16:
6280 case Match_InvalidMatrixTileVectorV16:
6282 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6283 case Match_InvalidMatrixTileVectorH32:
6284 case Match_InvalidMatrixTileVectorV32:
6286 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6287 case Match_InvalidMatrixTileVectorH64:
6288 case Match_InvalidMatrixTileVectorV64:
6290 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6291 case Match_InvalidMatrixTileVectorH128:
6292 case Match_InvalidMatrixTileVectorV128:
6294 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6295 case Match_InvalidMatrixTile16:
6296 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6297 case Match_InvalidMatrixTile32:
6298 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6299 case Match_InvalidMatrixTile64:
6300 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6301 case Match_InvalidMatrix:
6302 return Error(Loc,
"invalid matrix operand, expected za");
6303 case Match_InvalidMatrix8:
6304 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6305 case Match_InvalidMatrix16:
6306 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6307 case Match_InvalidMatrix32:
6308 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6309 case Match_InvalidMatrix64:
6310 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6311 case Match_InvalidMatrixIndexGPR32_12_15:
6312 return Error(Loc,
"operand must be a register in range [w12, w15]");
6313 case Match_InvalidMatrixIndexGPR32_8_11:
6314 return Error(Loc,
"operand must be a register in range [w8, w11]");
6315 case Match_InvalidSVEVectorList2x8Mul2:
6316 case Match_InvalidSVEVectorList2x16Mul2:
6317 case Match_InvalidSVEVectorList2x32Mul2:
6318 case Match_InvalidSVEVectorList2x64Mul2:
6319 case Match_InvalidSVEVectorList2x128Mul2:
6320 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6321 "SVE vectors, where the first vector is a multiple of 2 "
6322 "and with matching element types");
6323 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6324 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6325 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6326 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6327 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6328 "SVE vectors in the range z0-z14, where the first vector "
6329 "is a multiple of 2 "
6330 "and with matching element types");
6331 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6332 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6333 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6334 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6336 "Invalid vector list, expected list with 2 consecutive "
6337 "SVE vectors in the range z16-z30, where the first vector "
6338 "is a multiple of 2 "
6339 "and with matching element types");
6340 case Match_InvalidSVEVectorList4x8Mul4:
6341 case Match_InvalidSVEVectorList4x16Mul4:
6342 case Match_InvalidSVEVectorList4x32Mul4:
6343 case Match_InvalidSVEVectorList4x64Mul4:
6344 case Match_InvalidSVEVectorList4x128Mul4:
6345 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6346 "SVE vectors, where the first vector is a multiple of 4 "
6347 "and with matching element types");
6348 case Match_InvalidLookupTable:
6349 return Error(Loc,
"Invalid lookup table, expected zt0");
6350 case Match_InvalidSVEVectorListStrided2x8:
6351 case Match_InvalidSVEVectorListStrided2x16:
6352 case Match_InvalidSVEVectorListStrided2x32:
6353 case Match_InvalidSVEVectorListStrided2x64:
6356 "Invalid vector list, expected list with each SVE vector in the list "
6357 "8 registers apart, and the first register in the range [z0, z7] or "
6358 "[z16, z23] and with correct element type");
6359 case Match_InvalidSVEVectorListStrided4x8:
6360 case Match_InvalidSVEVectorListStrided4x16:
6361 case Match_InvalidSVEVectorListStrided4x32:
6362 case Match_InvalidSVEVectorListStrided4x64:
6365 "Invalid vector list, expected list with each SVE vector in the list "
6366 "4 registers apart, and the first register in the range [z0, z3] or "
6367 "[z16, z19] and with correct element type");
6368 case Match_AddSubLSLImm3ShiftLarge:
6370 "expected 'lsl' with optional integer in range [0, 7]");
6378bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6382 bool MatchingInlineAsm) {
6384 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6385 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6388 unsigned NumOperands =
Operands.size();
6390 if (NumOperands == 4 && Tok ==
"lsl") {
6391 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6392 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6393 if (Op2.isScalarReg() && Op3.isImm()) {
6394 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6399 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6401 NewOp3Val = (32 - Op3Val) & 0x1f;
6402 NewOp4Val = 31 - Op3Val;
6404 NewOp3Val = (64 - Op3Val) & 0x3f;
6405 NewOp4Val = 63 - Op3Val;
6412 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6413 Operands.push_back(AArch64Operand::CreateImm(
6414 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6415 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6416 Op3.getEndLoc(), getContext());
6419 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6421 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6422 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6423 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6425 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6426 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6427 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6429 if (LSBCE && WidthCE) {
6434 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6440 if (LSB >= RegWidth)
6441 return Error(LSBOp.getStartLoc(),
6442 "expected integer in range [0, 31]");
6443 if (Width < 1 || Width > RegWidth)
6444 return Error(WidthOp.getStartLoc(),
6445 "expected integer in range [1, 32]");
6449 ImmR = (32 - LSB) & 0x1f;
6451 ImmR = (64 - LSB) & 0x3f;
6455 if (ImmR != 0 && ImmS >= ImmR)
6456 return Error(WidthOp.getStartLoc(),
6457 "requested insert overflows register");
6462 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6463 Operands[2] = AArch64Operand::CreateReg(
6464 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6466 Operands[3] = AArch64Operand::CreateImm(
6467 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6469 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6470 WidthOp.getEndLoc(), getContext()));
6473 }
else if (NumOperands == 5) {
6476 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6477 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6478 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6479 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6481 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6482 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6483 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6485 if (Op3CE && Op4CE) {
6490 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6496 if (Op3Val >= RegWidth)
6497 return Error(Op3.getStartLoc(),
6498 "expected integer in range [0, 31]");
6499 if (Op4Val < 1 || Op4Val > RegWidth)
6500 return Error(Op4.getStartLoc(),
6501 "expected integer in range [1, 32]");
6505 NewOp3Val = (32 - Op3Val) & 0x1f;
6507 NewOp3Val = (64 - Op3Val) & 0x3f;
6511 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6512 return Error(Op4.getStartLoc(),
6513 "requested insert overflows register");
6519 Operands[3] = AArch64Operand::CreateImm(
6520 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6521 Operands[4] = AArch64Operand::CreateImm(
6522 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6524 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6526 else if (Tok ==
"sbfiz")
6527 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6529 else if (Tok ==
"ubfiz")
6530 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6539 }
else if (NumOperands == 5 &&
6540 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6541 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6542 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6543 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6545 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6546 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6547 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6549 if (Op3CE && Op4CE) {
6554 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6560 if (Op3Val >= RegWidth)
6561 return Error(Op3.getStartLoc(),
6562 "expected integer in range [0, 31]");
6563 if (Op4Val < 1 || Op4Val > RegWidth)
6564 return Error(Op4.getStartLoc(),
6565 "expected integer in range [1, 32]");
6567 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6569 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6570 return Error(Op4.getStartLoc(),
6571 "requested extract overflows register");
6575 Operands[4] = AArch64Operand::CreateImm(
6576 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6578 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6580 else if (Tok ==
"sbfx")
6581 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6583 else if (Tok ==
"ubfx")
6584 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6597 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6598 NumOperands == 4 && Tok ==
"movi") {
6599 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6600 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6601 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6602 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6603 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6604 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6605 if (Suffix.
lower() ==
".2d" &&
6606 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6607 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6608 " correctly on this CPU, converting to equivalent movi.16b");
6610 unsigned Idx = Op1.isToken() ? 1 : 2;
6612 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6620 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6623 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6624 if (
Op.isScalarReg()) {
6626 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6627 Op.getStartLoc(),
Op.getEndLoc(),
6632 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6633 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6634 if (
Op.isScalarReg() &&
6635 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6639 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6640 if (
Op.isScalarReg()) {
6642 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6644 Op.getEndLoc(), getContext());
6649 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6650 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6651 if (
Op.isScalarReg() &&
6652 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6656 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6657 if (
Op.isScalarReg()) {
6659 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6661 Op.getEndLoc(), getContext());
6670 unsigned MatchResult =
6672 MatchingInlineAsm, 1);
6676 if (MatchResult != Match_Success) {
6679 auto ShortFormNEONErrorInfo =
ErrorInfo;
6680 auto ShortFormNEONMatchResult = MatchResult;
6681 auto ShortFormNEONMissingFeatures = MissingFeatures;
6685 MatchingInlineAsm, 0);
6690 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6692 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6693 MatchResult = ShortFormNEONMatchResult;
6695 MissingFeatures = ShortFormNEONMissingFeatures;
6699 switch (MatchResult) {
6700 case Match_Success: {
6704 for (
unsigned i = 1; i < NumOperands; ++i)
6706 if (validateInstruction(Inst, IDLoc, OperandLocs))
6713 case Match_MissingFeature: {
6714 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6717 std::string Msg =
"instruction requires:";
6718 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6719 if (MissingFeatures[i]) {
6724 return Error(IDLoc, Msg);
6726 case Match_MnemonicFail:
6728 case Match_InvalidOperand: {
6729 SMLoc ErrorLoc = IDLoc;
6733 return Error(IDLoc,
"too few operands for instruction",
6734 SMRange(IDLoc, getTok().getLoc()));
6737 if (ErrorLoc ==
SMLoc())
6744 MatchResult = Match_InvalidSuffix;
6748 case Match_InvalidTiedOperand:
6749 case Match_InvalidMemoryIndexed1:
6750 case Match_InvalidMemoryIndexed2:
6751 case Match_InvalidMemoryIndexed4:
6752 case Match_InvalidMemoryIndexed8:
6753 case Match_InvalidMemoryIndexed16:
6754 case Match_InvalidCondCode:
6755 case Match_AddSubLSLImm3ShiftLarge:
6756 case Match_AddSubRegExtendSmall:
6757 case Match_AddSubRegExtendLarge:
6758 case Match_AddSubSecondSource:
6759 case Match_LogicalSecondSource:
6760 case Match_AddSubRegShift32:
6761 case Match_AddSubRegShift64:
6762 case Match_InvalidMovImm32Shift:
6763 case Match_InvalidMovImm64Shift:
6764 case Match_InvalidFPImm:
6765 case Match_InvalidMemoryWExtend8:
6766 case Match_InvalidMemoryWExtend16:
6767 case Match_InvalidMemoryWExtend32:
6768 case Match_InvalidMemoryWExtend64:
6769 case Match_InvalidMemoryWExtend128:
6770 case Match_InvalidMemoryXExtend8:
6771 case Match_InvalidMemoryXExtend16:
6772 case Match_InvalidMemoryXExtend32:
6773 case Match_InvalidMemoryXExtend64:
6774 case Match_InvalidMemoryXExtend128:
6775 case Match_InvalidMemoryIndexed1SImm4:
6776 case Match_InvalidMemoryIndexed2SImm4:
6777 case Match_InvalidMemoryIndexed3SImm4:
6778 case Match_InvalidMemoryIndexed4SImm4:
6779 case Match_InvalidMemoryIndexed1SImm6:
6780 case Match_InvalidMemoryIndexed16SImm4:
6781 case Match_InvalidMemoryIndexed32SImm4:
6782 case Match_InvalidMemoryIndexed4SImm7:
6783 case Match_InvalidMemoryIndexed8SImm7:
6784 case Match_InvalidMemoryIndexed16SImm7:
6785 case Match_InvalidMemoryIndexed8UImm5:
6786 case Match_InvalidMemoryIndexed8UImm3:
6787 case Match_InvalidMemoryIndexed4UImm5:
6788 case Match_InvalidMemoryIndexed2UImm5:
6789 case Match_InvalidMemoryIndexed1UImm6:
6790 case Match_InvalidMemoryIndexed2UImm6:
6791 case Match_InvalidMemoryIndexed4UImm6:
6792 case Match_InvalidMemoryIndexed8UImm6:
6793 case Match_InvalidMemoryIndexed16UImm6:
6794 case Match_InvalidMemoryIndexedSImm6:
6795 case Match_InvalidMemoryIndexedSImm5:
6796 case Match_InvalidMemoryIndexedSImm8:
6797 case Match_InvalidMemoryIndexedSImm9:
6798 case Match_InvalidMemoryIndexed16SImm9:
6799 case Match_InvalidMemoryIndexed8SImm10:
6800 case Match_InvalidImm0_0:
6801 case Match_InvalidImm0_1:
6802 case Match_InvalidImm0_3:
6803 case Match_InvalidImm0_7:
6804 case Match_InvalidImm0_15:
6805 case Match_InvalidImm0_31:
6806 case Match_InvalidImm0_63:
6807 case Match_InvalidImm0_127:
6808 case Match_InvalidImm0_255:
6809 case Match_InvalidImm0_65535:
6810 case Match_InvalidImm1_8:
6811 case Match_InvalidImm1_16:
6812 case Match_InvalidImm1_32:
6813 case Match_InvalidImm1_64:
6814 case Match_InvalidImmM1_62:
6815 case Match_InvalidMemoryIndexedRange2UImm0:
6816 case Match_InvalidMemoryIndexedRange2UImm1:
6817 case Match_InvalidMemoryIndexedRange2UImm2:
6818 case Match_InvalidMemoryIndexedRange2UImm3:
6819 case Match_InvalidMemoryIndexedRange4UImm0:
6820 case Match_InvalidMemoryIndexedRange4UImm1:
6821 case Match_InvalidMemoryIndexedRange4UImm2:
6822 case Match_InvalidSVEAddSubImm8:
6823 case Match_InvalidSVEAddSubImm16:
6824 case Match_InvalidSVEAddSubImm32:
6825 case Match_InvalidSVEAddSubImm64:
6826 case Match_InvalidSVECpyImm8:
6827 case Match_InvalidSVECpyImm16:
6828 case Match_InvalidSVECpyImm32:
6829 case Match_InvalidSVECpyImm64:
6830 case Match_InvalidIndexRange0_0:
6831 case Match_InvalidIndexRange1_1:
6832 case Match_InvalidIndexRange0_15:
6833 case Match_InvalidIndexRange0_7:
6834 case Match_InvalidIndexRange0_3:
6835 case Match_InvalidIndexRange0_1:
6836 case Match_InvalidSVEIndexRange0_63:
6837 case Match_InvalidSVEIndexRange0_31:
6838 case Match_InvalidSVEIndexRange0_15:
6839 case Match_InvalidSVEIndexRange0_7:
6840 case Match_InvalidSVEIndexRange0_3:
6841 case Match_InvalidLabel:
6842 case Match_InvalidComplexRotationEven:
6843 case Match_InvalidComplexRotationOdd:
6844 case Match_InvalidGPR64shifted8:
6845 case Match_InvalidGPR64shifted16:
6846 case Match_InvalidGPR64shifted32:
6847 case Match_InvalidGPR64shifted64:
6848 case Match_InvalidGPR64shifted128:
6849 case Match_InvalidGPR64NoXZRshifted8:
6850 case Match_InvalidGPR64NoXZRshifted16:
6851 case Match_InvalidGPR64NoXZRshifted32:
6852 case Match_InvalidGPR64NoXZRshifted64:
6853 case Match_InvalidGPR64NoXZRshifted128:
6854 case Match_InvalidZPR32UXTW8:
6855 case Match_InvalidZPR32UXTW16:
6856 case Match_InvalidZPR32UXTW32:
6857 case Match_InvalidZPR32UXTW64:
6858 case Match_InvalidZPR32SXTW8:
6859 case Match_InvalidZPR32SXTW16:
6860 case Match_InvalidZPR32SXTW32:
6861 case Match_InvalidZPR32SXTW64:
6862 case Match_InvalidZPR64UXTW8:
6863 case Match_InvalidZPR64SXTW8:
6864 case Match_InvalidZPR64UXTW16:
6865 case Match_InvalidZPR64SXTW16:
6866 case Match_InvalidZPR64UXTW32:
6867 case Match_InvalidZPR64SXTW32:
6868 case Match_InvalidZPR64UXTW64:
6869 case Match_InvalidZPR64SXTW64:
6870 case Match_InvalidZPR32LSL8:
6871 case Match_InvalidZPR32LSL16:
6872 case Match_InvalidZPR32LSL32:
6873 case Match_InvalidZPR32LSL64:
6874 case Match_InvalidZPR64LSL8:
6875 case Match_InvalidZPR64LSL16:
6876 case Match_InvalidZPR64LSL32:
6877 case Match_InvalidZPR64LSL64:
6878 case Match_InvalidZPR0:
6879 case Match_InvalidZPR8:
6880 case Match_InvalidZPR16:
6881 case Match_InvalidZPR32:
6882 case Match_InvalidZPR64:
6883 case Match_InvalidZPR128:
6884 case Match_InvalidZPR_3b8:
6885 case Match_InvalidZPR_3b16:
6886 case Match_InvalidZPR_3b32:
6887 case Match_InvalidZPR_4b8:
6888 case Match_InvalidZPR_4b16:
6889 case Match_InvalidZPR_4b32:
6890 case Match_InvalidZPR_4b64:
6891 case Match_InvalidSVEPPRorPNRAnyReg:
6892 case Match_InvalidSVEPPRorPNRBReg:
6893 case Match_InvalidSVEPredicateAnyReg:
6894 case Match_InvalidSVEPattern:
6895 case Match_InvalidSVEVecLenSpecifier:
6896 case Match_InvalidSVEPredicateBReg:
6897 case Match_InvalidSVEPredicateHReg:
6898 case Match_InvalidSVEPredicateSReg:
6899 case Match_InvalidSVEPredicateDReg:
6900 case Match_InvalidSVEPredicate3bAnyReg:
6901 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6902 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6903 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6904 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6905 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6906 case Match_InvalidSVEPNPredicateBReg:
6907 case Match_InvalidSVEPNPredicateHReg:
6908 case Match_InvalidSVEPNPredicateSReg:
6909 case Match_InvalidSVEPNPredicateDReg:
6910 case Match_InvalidSVEPredicateListMul2x8:
6911 case Match_InvalidSVEPredicateListMul2x16:
6912 case Match_InvalidSVEPredicateListMul2x32:
6913 case Match_InvalidSVEPredicateListMul2x64:
6914 case Match_InvalidSVEExactFPImmOperandHalfOne:
6915 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6916 case Match_InvalidSVEExactFPImmOperandZeroOne:
6917 case Match_InvalidMatrixTile16:
6918 case Match_InvalidMatrixTile32:
6919 case Match_InvalidMatrixTile64:
6920 case Match_InvalidMatrix:
6921 case Match_InvalidMatrix8:
6922 case Match_InvalidMatrix16:
6923 case Match_InvalidMatrix32:
6924 case Match_InvalidMatrix64:
6925 case Match_InvalidMatrixTileVectorH8:
6926 case Match_InvalidMatrixTileVectorH16:
6927 case Match_InvalidMatrixTileVectorH32:
6928 case Match_InvalidMatrixTileVectorH64:
6929 case Match_InvalidMatrixTileVectorH128:
6930 case Match_InvalidMatrixTileVectorV8:
6931 case Match_InvalidMatrixTileVectorV16:
6932 case Match_InvalidMatrixTileVectorV32:
6933 case Match_InvalidMatrixTileVectorV64:
6934 case Match_InvalidMatrixTileVectorV128:
6935 case Match_InvalidSVCR:
6936 case Match_InvalidMatrixIndexGPR32_12_15:
6937 case Match_InvalidMatrixIndexGPR32_8_11:
6938 case Match_InvalidLookupTable:
6939 case Match_InvalidZPRMul2_Lo8:
6940 case Match_InvalidZPRMul2_Hi8:
6941 case Match_InvalidZPRMul2_Lo16:
6942 case Match_InvalidZPRMul2_Hi16:
6943 case Match_InvalidZPRMul2_Lo32:
6944 case Match_InvalidZPRMul2_Hi32:
6945 case Match_InvalidZPRMul2_Lo64:
6946 case Match_InvalidZPRMul2_Hi64:
6947 case Match_InvalidZPR_K0:
6948 case Match_InvalidSVEVectorList2x8Mul2:
6949 case Match_InvalidSVEVectorList2x16Mul2:
6950 case Match_InvalidSVEVectorList2x32Mul2:
6951 case Match_InvalidSVEVectorList2x64Mul2:
6952 case Match_InvalidSVEVectorList2x128Mul2:
6953 case Match_InvalidSVEVectorList4x8Mul4:
6954 case Match_InvalidSVEVectorList4x16Mul4:
6955 case Match_InvalidSVEVectorList4x32Mul4:
6956 case Match_InvalidSVEVectorList4x64Mul4:
6957 case Match_InvalidSVEVectorList4x128Mul4:
6958 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6959 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6960 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6961 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6962 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6963 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6964 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6965 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6966 case Match_InvalidSVEVectorListStrided2x8:
6967 case Match_InvalidSVEVectorListStrided2x16:
6968 case Match_InvalidSVEVectorListStrided2x32:
6969 case Match_InvalidSVEVectorListStrided2x64:
6970 case Match_InvalidSVEVectorListStrided4x8:
6971 case Match_InvalidSVEVectorListStrided4x16:
6972 case Match_InvalidSVEVectorListStrided4x32:
6973 case Match_InvalidSVEVectorListStrided4x64:
6977 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6981 if (ErrorLoc ==
SMLoc())
6991bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6998 if (IDVal ==
".arch")
6999 parseDirectiveArch(Loc);
7000 else if (IDVal ==
".cpu")
7001 parseDirectiveCPU(Loc);
7002 else if (IDVal ==
".tlsdesccall")
7003 parseDirectiveTLSDescCall(Loc);
7004 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7005 parseDirectiveLtorg(Loc);
7006 else if (IDVal ==
".unreq")
7007 parseDirectiveUnreq(Loc);
7008 else if (IDVal ==
".inst")
7009 parseDirectiveInst(Loc);
7010 else if (IDVal ==
".cfi_negate_ra_state")
7011 parseDirectiveCFINegateRAState();
7012 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7013 parseDirectiveCFINegateRAStateWithPC();
7014 else if (IDVal ==
".cfi_b_key_frame")
7015 parseDirectiveCFIBKeyFrame();
7016 else if (IDVal ==
".cfi_mte_tagged_frame")
7017 parseDirectiveCFIMTETaggedFrame();
7018 else if (IDVal ==
".arch_extension")
7019 parseDirectiveArchExtension(Loc);
7020 else if (IDVal ==
".variant_pcs")
7021 parseDirectiveVariantPCS(Loc);
7024 parseDirectiveLOH(IDVal, Loc);
7027 }
else if (IsCOFF) {
7028 if (IDVal ==
".seh_stackalloc")
7029 parseDirectiveSEHAllocStack(Loc);
7030 else if (IDVal ==
".seh_endprologue")
7031 parseDirectiveSEHPrologEnd(Loc);
7032 else if (IDVal ==
".seh_save_r19r20_x")
7033 parseDirectiveSEHSaveR19R20X(Loc);
7034 else if (IDVal ==
".seh_save_fplr")
7035 parseDirectiveSEHSaveFPLR(Loc);
7036 else if (IDVal ==
".seh_save_fplr_x")
7037 parseDirectiveSEHSaveFPLRX(Loc);
7038 else if (IDVal ==
".seh_save_reg")
7039 parseDirectiveSEHSaveReg(Loc);
7040 else if (IDVal ==
".seh_save_reg_x")
7041 parseDirectiveSEHSaveRegX(Loc);
7042 else if (IDVal ==
".seh_save_regp")
7043 parseDirectiveSEHSaveRegP(Loc);
7044 else if (IDVal ==
".seh_save_regp_x")
7045 parseDirectiveSEHSaveRegPX(Loc);
7046 else if (IDVal ==
".seh_save_lrpair")
7047 parseDirectiveSEHSaveLRPair(Loc);
7048 else if (IDVal ==
".seh_save_freg")
7049 parseDirectiveSEHSaveFReg(Loc);
7050 else if (IDVal ==
".seh_save_freg_x")
7051 parseDirectiveSEHSaveFRegX(Loc);
7052 else if (IDVal ==
".seh_save_fregp")
7053 parseDirectiveSEHSaveFRegP(Loc);
7054 else if (IDVal ==
".seh_save_fregp_x")
7055 parseDirectiveSEHSaveFRegPX(Loc);
7056 else if (IDVal ==
".seh_set_fp")
7057 parseDirectiveSEHSetFP(Loc);
7058 else if (IDVal ==
".seh_add_fp")
7059 parseDirectiveSEHAddFP(Loc);
7060 else if (IDVal ==
".seh_nop")
7061 parseDirectiveSEHNop(Loc);
7062 else if (IDVal ==
".seh_save_next")
7063 parseDirectiveSEHSaveNext(Loc);
7064 else if (IDVal ==
".seh_startepilogue")
7065 parseDirectiveSEHEpilogStart(Loc);
7066 else if (IDVal ==
".seh_endepilogue")
7067 parseDirectiveSEHEpilogEnd(Loc);
7068 else if (IDVal ==
".seh_trap_frame")
7069 parseDirectiveSEHTrapFrame(Loc);
7070 else if (IDVal ==
".seh_pushframe")
7071 parseDirectiveSEHMachineFrame(Loc);
7072 else if (IDVal ==
".seh_context")
7073 parseDirectiveSEHContext(Loc);
7074 else if (IDVal ==
".seh_ec_context")
7075 parseDirectiveSEHECContext(Loc);
7076 else if (IDVal ==
".seh_clear_unwound_to_call")
7077 parseDirectiveSEHClearUnwoundToCall(Loc);
7078 else if (IDVal ==
".seh_pac_sign_lr")
7079 parseDirectiveSEHPACSignLR(Loc);
7080 else if (IDVal ==
".seh_save_any_reg")
7081 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7082 else if (IDVal ==
".seh_save_any_reg_p")
7083 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7084 else if (IDVal ==
".seh_save_any_reg_x")
7085 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7086 else if (IDVal ==
".seh_save_any_reg_px")
7087 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7100 if (!NoCrypto && Crypto) {
7103 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7104 ArchInfo == AArch64::ARMV8_3A) {
7108 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7109 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7110 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7111 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7112 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7113 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7119 }
else if (NoCrypto) {
7122 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7123 ArchInfo == AArch64::ARMV8_3A) {
7124 RequestedExtensions.
push_back(
"nosha2");
7127 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7128 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7129 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7130 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7131 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7132 ArchInfo == AArch64::ARMV9_4A) {
7134 RequestedExtensions.
push_back(
"nosha3");
7135 RequestedExtensions.
push_back(
"nosha2");
7147bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
7148 SMLoc CurLoc = getLoc();
7151 std::tie(Arch, ExtensionString) =
7152 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7156 return Error(CurLoc,
"unknown arch name");
7162 std::vector<StringRef> AArch64Features;
7167 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7169 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7172 if (!ExtensionString.
empty())
7173 ExtensionString.
split(RequestedExtensions,
'+');
7178 for (
auto Name : RequestedExtensions) {
7182 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7189 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7198 setAvailableFeatures(Features);
7204bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7205 SMLoc ExtLoc = getLoc();
7207 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7212 bool EnableFeature =
true;
7213 if (
Name.starts_with_insensitive(
"no")) {
7214 EnableFeature =
false;
7223 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7231 setAvailableFeatures(Features);
7237bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7238 SMLoc CurLoc = getLoc();
7241 std::tie(CPU, ExtensionString) =
7242 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7248 if (!ExtensionString.
empty())
7249 ExtensionString.
split(RequestedExtensions,
'+');
7253 Error(CurLoc,
"unknown CPU name");
7262 for (
auto Name : RequestedExtensions) {
7266 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7273 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7282 setAvailableFeatures(Features);
7288bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7290 return Error(Loc,
"expected expression following '.inst' directive");
7292 auto parseOp = [&]() ->
bool {
7294 const MCExpr *Expr =
nullptr;
7295 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7298 if (check(!
Value, L,
"expected constant expression"))
7300 getTargetStreamer().emitInst(
Value->getValue());
7304 return parseMany(parseOp);
7309bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7311 if (check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7323 getParser().getStreamer().emitInstruction(Inst, getSTI());
7329bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7333 return TokError(
"expected an identifier or a number in directive");
7336 int64_t
Id = getTok().getIntVal();
7338 return TokError(
"invalid numeric identifier in directive");
7347 return TokError(
"invalid identifier in directive");
7355 assert(NbArgs != -1 &&
"Invalid number of arguments");
7358 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7360 if (getParser().parseIdentifier(
Name))
7361 return TokError(
"expected identifier in directive");
7362 Args.push_back(getContext().getOrCreateSymbol(
Name));
7364 if (
Idx + 1 == NbArgs)
7372 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7378bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7381 getTargetStreamer().emitCurrentConstantPool();
7389 SMLoc SRegLoc = getLoc();
7390 RegKind RegisterKind = RegKind::Scalar;
7392 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7396 RegisterKind = RegKind::NeonVector;
7397 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7403 return Error(SRegLoc,
"vector register without type specifier expected");
7408 RegisterKind = RegKind::SVEDataVector;
7410 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7416 return Error(SRegLoc,
7417 "sve vector register without type specifier expected");
7422 RegisterKind = RegKind::SVEPredicateVector;
7423 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7429 return Error(SRegLoc,
7430 "sve predicate register without type specifier expected");
7434 return Error(SRegLoc,
"register name or alias expected");
7440 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7441 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7442 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7449bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7451 return TokError(
"unexpected input in .unreq directive.");
7452 RegisterReqs.
erase(getTok().getIdentifier().lower());
7457bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7460 getStreamer().emitCFINegateRAState();
7464bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7467 getStreamer().emitCFINegateRAStateWithPC();
7473bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7476 getStreamer().emitCFIBKeyFrame();
7482bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7485 getStreamer().emitCFIMTETaggedFrame();
7491bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7493 if (getParser().parseIdentifier(
Name))
7494 return TokError(
"expected symbol name");
7497 getTargetStreamer().emitDirectiveVariantPCS(
7498 getContext().getOrCreateSymbol(
Name));
7504bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7506 if (parseImmExpr(
Size))
7508 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7514bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7515 getTargetStreamer().emitARM64WinCFIPrologEnd();
7521bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7523 if (parseImmExpr(
Offset))
7525 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7531bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7533 if (parseImmExpr(
Offset))
7535 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7541bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7543 if (parseImmExpr(
Offset))
7545 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7551bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7554 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7555 parseComma() || parseImmExpr(
Offset))
7557 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7563bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7566 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7567 parseComma() || parseImmExpr(
Offset))
7569 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7575bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7578 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7579 parseComma() || parseImmExpr(
Offset))
7581 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7587bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7590 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7591 parseComma() || parseImmExpr(
Offset))
7593 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7599bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7603 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7604 parseComma() || parseImmExpr(
Offset))
7606 if (check(((Reg - 19) % 2 != 0), L,
7607 "expected register with even offset from x19"))
7609 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7615bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7618 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7619 parseComma() || parseImmExpr(
Offset))
7621 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7627bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7630 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7631 parseComma() || parseImmExpr(
Offset))
7633 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7639bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7642 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7643 parseComma() || parseImmExpr(
Offset))
7645 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7651bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7654 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7655 parseComma() || parseImmExpr(
Offset))
7657 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7663bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7664 getTargetStreamer().emitARM64WinCFISetFP();
7670bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7672 if (parseImmExpr(
Size))
7674 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7680bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7681 getTargetStreamer().emitARM64WinCFINop();
7687bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7688 getTargetStreamer().emitARM64WinCFISaveNext();
7694bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7695 getTargetStreamer().emitARM64WinCFIEpilogStart();
7701bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7702 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7708bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7709 getTargetStreamer().emitARM64WinCFITrapFrame();
7715bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7716 getTargetStreamer().emitARM64WinCFIMachineFrame();
7722bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7723 getTargetStreamer().emitARM64WinCFIContext();
7729bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7730 getTargetStreamer().emitARM64WinCFIECContext();
7736bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7737 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7743bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7744 getTargetStreamer().emitARM64WinCFIPACSignLR();
7753bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7758 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7759 parseComma() || parseImmExpr(
Offset))
7762 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7763 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7764 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7765 return Error(L,
"invalid save_any_reg offset");
7766 unsigned EncodedReg;
7767 if (Reg == AArch64::FP)
7769 else if (Reg == AArch64::LR)
7772 EncodedReg =
Reg - AArch64::X0;
7774 if (Reg == AArch64::LR)
7775 return Error(Start,
"lr cannot be paired with another register");
7777 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7779 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7782 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7784 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7786 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7787 unsigned EncodedReg =
Reg - AArch64::D0;
7788 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7789 return Error(L,
"invalid save_any_reg offset");
7791 if (Reg == AArch64::D31)
7792 return Error(Start,
"d31 cannot be paired with another register");
7794 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7796 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7799 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7801 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7803 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7804 unsigned EncodedReg =
Reg - AArch64::Q0;
7806 return Error(L,
"invalid save_any_reg offset");
7808 if (Reg == AArch64::Q31)
7809 return Error(Start,
"q31 cannot be paired with another register");
7811 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7813 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7816 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7818 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7821 return Error(Start,
"save_any_reg register must be x, q or d register");
7826bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7828 if (!parseAuthExpr(Res, EndLoc))
7830 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7837bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7848 "combination of @AUTH with other modifiers not supported");
7871 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7893 return TokError(
"expected key name");
7898 return TokError(
"invalid key '" + KeyStr +
"'");
7905 return TokError(
"expected integer discriminator");
7908 if (!isUInt<16>(Discriminator))
7909 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7910 " out of range [0, 0xFFFF]");
7913 bool UseAddressDiversity =
false;
7918 return TokError(
"expected 'addr'");
7919 UseAddressDiversity =
true;
7928 UseAddressDiversity, Ctx);
7933AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7941 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7942 ELFRefKind = AE->getKind();
7943 Expr = AE->getSubExpr();
7949 DarwinRefKind = SE->
getKind();
7956 if (!Relocatable || Res.
getSymB())
7983#define GET_REGISTER_MATCHER
7984#define GET_SUBTARGET_FEATURE_NAME
7985#define GET_MATCHER_IMPLEMENTATION
7986#define GET_MNEMONIC_SPELL_CHECKER
7987#include "AArch64GenAsmMatcher.inc"
7993 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7995 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7997 return Match_InvalidOperand;
8000 return Match_InvalidOperand;
8001 if (CE->getValue() == ExpectedVal)
8002 return Match_Success;
8003 return Match_InvalidOperand;
8008 return Match_InvalidOperand;
8014 if (
Op.isTokenEqual(
"za"))
8015 return Match_Success;
8016 return Match_InvalidOperand;
8022#define MATCH_HASH(N) \
8023 case MCK__HASH_##N: \
8024 return MatchesOpImmediate(N);
8050#define MATCH_HASH_MINUS(N) \
8051 case MCK__HASH__MINUS_##N: \
8052 return MatchesOpImmediate(-N);
8056#undef MATCH_HASH_MINUS
8065 return Error(S,
"expected register");
8068 ParseStatus Res = tryParseScalarRegister(FirstReg);
8070 return Error(S,
"expected first even register of a consecutive same-size "
8071 "even/odd register pair");
8074 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8076 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8078 bool isXReg = XRegClass.
contains(FirstReg),
8079 isWReg = WRegClass.
contains(FirstReg);
8080 if (!isXReg && !isWReg)
8081 return Error(S,
"expected first even register of a consecutive same-size "
8082 "even/odd register pair");
8087 if (FirstEncoding & 0x1)
8088 return Error(S,
"expected first even register of a consecutive same-size "
8089 "even/odd register pair");
8092 return Error(getLoc(),
"expected comma");
8098 Res = tryParseScalarRegister(SecondReg);
8100 return Error(E,
"expected second odd register of a consecutive same-size "
8101 "even/odd register pair");
8104 (isXReg && !XRegClass.
contains(SecondReg)) ||
8105 (isWReg && !WRegClass.
contains(SecondReg)))
8106 return Error(E,
"expected second odd register of a consecutive same-size "
8107 "even/odd register pair");
8112 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8115 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8118 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8119 getLoc(), getContext()));
8124template <
bool ParseShiftExtend,
bool ParseSuffix>
8126 const SMLoc S = getLoc();
8132 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8137 if (ParseSuffix &&
Kind.empty())
8144 unsigned ElementWidth = KindRes->second;
8148 Operands.push_back(AArch64Operand::CreateVectorReg(
8149 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
8162 Res = tryParseOptionalShiftExtend(ExtOpnd);
8166 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
8167 Operands.push_back(AArch64Operand::CreateVectorReg(
8168 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8169 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
8170 Ext->hasShiftExtendAmount()));
8195 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8197 return TokError(
"invalid operand for instruction");
8202 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8213 SS, getLoc(), getContext()));
8224 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8235 SS, getLoc(), getContext()));
8244 if (!tryParseScalarRegister(XReg).isSuccess())
8250 XReg, AArch64::x8sub_0,
8251 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8254 "expected an even-numbered x-register in the range [x0,x22]");
8257 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8271 if (getParser().parseExpression(ImmF))
8281 SMLoc E = getTok().getLoc();
8283 if (getParser().parseExpression(ImmL))
8286 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8287 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8290 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
8305 if (getParser().parseExpression(Ex))
8308 int64_t
Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
8315 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8322 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.
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