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>
1451 bool isImplicitlyTypedVectorList()
const {
1452 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1453 VectorList.NumElements == 0 &&
1454 VectorList.RegisterKind == VectorKind;
1457 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1458 unsigned ElementWidth,
unsigned Stride = 1>
1459 bool isTypedVectorList()
const {
1460 if (Kind != k_VectorList)
1462 if (VectorList.Count != NumRegs)
1464 if (VectorList.RegisterKind != VectorKind)
1466 if (VectorList.ElementWidth != ElementWidth)
1468 if (VectorList.Stride != Stride)
1470 return VectorList.NumElements == NumElements;
1473 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1474 unsigned ElementWidth,
unsigned RegClass>
1477 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1479 return DiagnosticPredicateTy::NoMatch;
1480 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.RegNum))
1481 return DiagnosticPredicateTy::NearMatch;
1482 return DiagnosticPredicateTy::Match;
1485 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1486 unsigned ElementWidth>
1488 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1489 ElementWidth, Stride>();
1491 return DiagnosticPredicateTy::NoMatch;
1492 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1493 ((VectorList.RegNum >= AArch64::Z16) &&
1494 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1495 return DiagnosticPredicateTy::Match;
1496 return DiagnosticPredicateTy::NoMatch;
1499 template <
int Min,
int Max>
1501 if (Kind != k_VectorIndex)
1502 return DiagnosticPredicateTy::NoMatch;
1503 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1504 return DiagnosticPredicateTy::Match;
1505 return DiagnosticPredicateTy::NearMatch;
1508 bool isToken()
const override {
return Kind == k_Token; }
1510 bool isTokenEqual(
StringRef Str)
const {
1511 return Kind == k_Token && getToken() == Str;
1513 bool isSysCR()
const {
return Kind == k_SysCR; }
1514 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1515 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1516 bool isPHint()
const {
return Kind == k_PHint; }
1517 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1518 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1519 bool isShifter()
const {
1520 if (!isShiftExtend())
1530 if (Kind != k_FPImm)
1531 return DiagnosticPredicateTy::NoMatch;
1533 if (getFPImmIsExact()) {
1535 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1539 APFloat RealVal(APFloat::IEEEdouble());
1541 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1542 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1545 if (
getFPImm().bitwiseIsEqual(RealVal))
1546 return DiagnosticPredicateTy::Match;
1549 return DiagnosticPredicateTy::NearMatch;
1552 template <
unsigned ImmA,
unsigned ImmB>
1555 if ((Res = isExactFPImm<ImmA>()))
1556 return DiagnosticPredicateTy::Match;
1557 if ((Res = isExactFPImm<ImmB>()))
1558 return DiagnosticPredicateTy::Match;
1562 bool isExtend()
const {
1563 if (!isShiftExtend())
1572 getShiftExtendAmount() <= 4;
1575 bool isExtend64()
const {
1585 bool isExtendLSL64()
const {
1591 getShiftExtendAmount() <= 4;
1594 bool isLSLImm3Shift()
const {
1595 if (!isShiftExtend())
1601 template<
int W
idth>
bool isMemXExtend()
const {
1606 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1607 getShiftExtendAmount() == 0);
1610 template<
int W
idth>
bool isMemWExtend()
const {
1615 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1616 getShiftExtendAmount() == 0);
1619 template <
unsigned w
idth>
1620 bool isArithmeticShifter()
const {
1630 template <
unsigned w
idth>
1631 bool isLogicalShifter()
const {
1639 getShiftExtendAmount() < width;
1642 bool isMovImm32Shifter()
const {
1650 uint64_t Val = getShiftExtendAmount();
1651 return (Val == 0 || Val == 16);
1654 bool isMovImm64Shifter()
const {
1662 uint64_t Val = getShiftExtendAmount();
1663 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1666 bool isLogicalVecShifter()
const {
1671 unsigned Shift = getShiftExtendAmount();
1673 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1676 bool isLogicalVecHalfWordShifter()
const {
1677 if (!isLogicalVecShifter())
1681 unsigned Shift = getShiftExtendAmount();
1683 (Shift == 0 || Shift == 8);
1686 bool isMoveVecShifter()
const {
1687 if (!isShiftExtend())
1691 unsigned Shift = getShiftExtendAmount();
1693 (Shift == 8 || Shift == 16);
1702 bool isSImm9OffsetFB()
const {
1703 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1706 bool isAdrpLabel()
const {
1713 int64_t Val =
CE->getValue();
1714 int64_t Min = - (4096 * (1LL << (21 - 1)));
1715 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1716 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1722 bool isAdrLabel()
const {
1729 int64_t Val =
CE->getValue();
1730 int64_t Min = - (1LL << (21 - 1));
1731 int64_t
Max = ((1LL << (21 - 1)) - 1);
1732 return Val >= Min && Val <=
Max;
1738 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1741 return DiagnosticPredicateTy::NoMatch;
1742 if (getMatrixKind() != Kind ||
1743 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1744 EltSize != getMatrixElementWidth())
1745 return DiagnosticPredicateTy::NearMatch;
1746 return DiagnosticPredicateTy::Match;
1749 bool isPAuthPCRelLabel16Operand()
const {
1761 return (Val <= 0) && (Val > -(1 << 18));
1768 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1774 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1775 assert(
N == 1 &&
"Invalid number of operands!");
1779 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1780 assert(
N == 1 &&
"Invalid number of operands!");
1784 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1785 assert(
N == 1 &&
"Invalid number of operands!");
1787 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1796 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1797 assert(
N == 1 &&
"Invalid number of operands!");
1799 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1808 template <
int W
idth>
1809 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1812 case 8:
Base = AArch64::B0;
break;
1813 case 16:
Base = AArch64::H0;
break;
1814 case 32:
Base = AArch64::S0;
break;
1815 case 64:
Base = AArch64::D0;
break;
1816 case 128:
Base = AArch64::Q0;
break;
1823 void addPPRorPNRRegOperands(
MCInst &Inst,
unsigned N)
const {
1824 assert(
N == 1 &&
"Invalid number of operands!");
1827 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1828 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1832 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1833 assert(
N == 1 &&
"Invalid number of operands!");
1838 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1839 assert(
N == 1 &&
"Invalid number of operands!");
1841 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1845 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1846 assert(
N == 1 &&
"Invalid number of operands!");
1848 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1852 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1853 assert(
N == 1 &&
"Invalid number of operands!");
1857 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1858 assert(
N == 1 &&
"Invalid number of operands!");
1862 enum VecListIndexType {
1863 VecListIdx_DReg = 0,
1864 VecListIdx_QReg = 1,
1865 VecListIdx_ZReg = 2,
1866 VecListIdx_PReg = 3,
1869 template <VecListIndexType RegTy,
unsigned NumRegs>
1870 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1871 assert(
N == 1 &&
"Invalid number of operands!");
1872 static const unsigned FirstRegs[][5] = {
1874 AArch64::D0, AArch64::D0_D1,
1875 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1877 AArch64::Q0, AArch64::Q0_Q1,
1878 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1880 AArch64::Z0, AArch64::Z0_Z1,
1881 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1883 AArch64::P0, AArch64::P0_P1 }
1886 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1887 " NumRegs must be <= 4 for ZRegs");
1889 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1890 " NumRegs must be <= 2 for PRegs");
1892 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1894 FirstRegs[(
unsigned)RegTy][0]));
1897 template <
unsigned NumRegs>
1898 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1899 assert(
N == 1 &&
"Invalid number of operands!");
1900 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1904 if (getVectorListStart() < AArch64::Z16) {
1905 assert((getVectorListStart() < AArch64::Z8) &&
1906 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1908 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1910 assert((getVectorListStart() < AArch64::Z24) &&
1911 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1913 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1917 if (getVectorListStart() < AArch64::Z16) {
1918 assert((getVectorListStart() < AArch64::Z4) &&
1919 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1921 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1923 assert((getVectorListStart() < AArch64::Z20) &&
1924 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1926 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1934 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1935 assert(
N == 1 &&
"Invalid number of operands!");
1936 unsigned RegMask = getMatrixTileListRegMask();
1937 assert(RegMask <= 0xFF &&
"Invalid mask!");
1941 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1942 assert(
N == 1 &&
"Invalid number of operands!");
1946 template <
unsigned ImmIs0,
unsigned ImmIs1>
1947 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1948 assert(
N == 1 &&
"Invalid number of operands!");
1949 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1953 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1954 assert(
N == 1 &&
"Invalid number of operands!");
1958 addExpr(Inst, getImm());
1961 template <
int Shift>
1962 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1963 assert(
N == 2 &&
"Invalid number of operands!");
1964 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1967 }
else if (isShiftedImm()) {
1968 addExpr(Inst, getShiftedImmVal());
1971 addExpr(Inst, getImm());
1976 template <
int Shift>
1977 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1978 assert(
N == 2 &&
"Invalid number of operands!");
1979 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1986 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1987 assert(
N == 1 &&
"Invalid number of operands!");
1991 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1992 assert(
N == 1 &&
"Invalid number of operands!");
1995 addExpr(Inst, getImm());
2000 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2001 addImmOperands(Inst,
N);
2005 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2006 assert(
N == 1 &&
"Invalid number of operands!");
2016 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
2017 assert(
N == 1 &&
"Invalid number of operands!");
2022 template <
int Scale>
2023 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
2024 assert(
N == 1 &&
"Invalid number of operands!");
2029 template <
int Scale>
2030 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
2031 assert(
N == 1 &&
"Invalid number of operands!");
2035 template <
typename T>
2036 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
2037 assert(
N == 1 &&
"Invalid number of operands!");
2039 std::make_unsigned_t<T> Val = MCE->
getValue();
2044 template <
typename T>
2045 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2046 assert(
N == 1 &&
"Invalid number of operands!");
2048 std::make_unsigned_t<T> Val = ~MCE->getValue();
2053 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
2054 assert(
N == 1 &&
"Invalid number of operands!");
2060 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2064 assert(
N == 1 &&
"Invalid number of operands!");
2067 addExpr(Inst, getImm());
2070 assert(MCE &&
"Invalid constant immediate operand!");
2074 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2078 assert(
N == 1 &&
"Invalid number of operands!");
2081 addExpr(Inst, getImm());
2087 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2091 assert(
N == 1 &&
"Invalid number of operands!");
2094 addExpr(Inst, getImm());
2097 assert(MCE &&
"Invalid constant immediate operand!");
2101 void addPCRelLabel9Operands(
MCInst &Inst,
unsigned N)
const {
2105 assert(
N == 1 &&
"Invalid number of operands!");
2108 addExpr(Inst, getImm());
2111 assert(MCE &&
"Invalid constant immediate operand!");
2115 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2119 assert(
N == 1 &&
"Invalid number of operands!");
2122 addExpr(Inst, getImm());
2125 assert(MCE &&
"Invalid constant immediate operand!");
2129 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2130 assert(
N == 1 &&
"Invalid number of operands!");
2135 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2140 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2141 assert(
N == 1 &&
"Invalid number of operands!");
2145 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2146 assert(
N == 1 &&
"Invalid number of operands!");
2151 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2152 assert(
N == 1 &&
"Invalid number of operands!");
2157 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2158 assert(
N == 1 &&
"Invalid number of operands!");
2163 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2164 assert(
N == 1 &&
"Invalid number of operands!");
2169 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2170 assert(
N == 1 &&
"Invalid number of operands!");
2175 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2176 assert(
N == 1 &&
"Invalid number of operands!");
2180 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2181 assert(
N == 1 &&
"Invalid number of operands!");
2185 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2186 assert(
N == 1 &&
"Invalid number of operands!");
2190 void addPHintOperands(
MCInst &Inst,
unsigned N)
const {
2191 assert(
N == 1 &&
"Invalid number of operands!");
2195 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2196 assert(
N == 1 &&
"Invalid number of operands!");
2200 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2201 assert(
N == 1 &&
"Invalid number of operands!");
2207 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2208 assert(
N == 1 &&
"Invalid number of operands!");
2209 unsigned Imm = getShiftExtendAmount();
2213 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2214 assert(
N == 1 &&
"Invalid number of operands!");
2222 if (
Reg != AArch64::XZR)
2228 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2229 assert(
N == 1 &&
"Invalid number of operands!");
2236 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2237 assert(
N == 1 &&
"Invalid number of operands!");
2244 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2245 assert(
N == 2 &&
"Invalid number of operands!");
2256 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2257 assert(
N == 2 &&
"Invalid number of operands!");
2265 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2266 assert(
N == 1 &&
"Invalid number of operands!");
2273 addExpr(Inst, getImm());
2278 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2279 assert(
N == 1 &&
"Invalid number of operands!");
2286 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2287 assert(
N == 1 &&
"Invalid number of operands!");
2292 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2293 assert(
N == 1 &&
"Invalid number of operands!");
2300 static std::unique_ptr<AArch64Operand>
2302 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2303 Op->Tok.Data = Str.data();
2304 Op->Tok.Length = Str.size();
2305 Op->Tok.IsSuffix = IsSuffix;
2311 static std::unique_ptr<AArch64Operand>
2313 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2315 unsigned ShiftAmount = 0,
2316 unsigned HasExplicitAmount =
false) {
2317 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2318 Op->Reg.RegNum = RegNum;
2320 Op->Reg.ElementWidth = 0;
2321 Op->Reg.EqualityTy = EqTy;
2322 Op->Reg.ShiftExtend.Type = ExtTy;
2323 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2324 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2330 static std::unique_ptr<AArch64Operand>
2331 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2334 unsigned ShiftAmount = 0,
2335 unsigned HasExplicitAmount =
false) {
2336 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2337 Kind == RegKind::SVEPredicateVector ||
2338 Kind == RegKind::SVEPredicateAsCounter) &&
2339 "Invalid vector kind");
2340 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2342 Op->Reg.ElementWidth = ElementWidth;
2346 static std::unique_ptr<AArch64Operand>
2347 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2348 unsigned NumElements,
unsigned ElementWidth,
2350 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2351 Op->VectorList.RegNum = RegNum;
2352 Op->VectorList.Count = Count;
2353 Op->VectorList.Stride = Stride;
2354 Op->VectorList.NumElements = NumElements;
2355 Op->VectorList.ElementWidth = ElementWidth;
2356 Op->VectorList.RegisterKind = RegisterKind;
2362 static std::unique_ptr<AArch64Operand>
2364 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2365 Op->VectorIndex.Val =
Idx;
2371 static std::unique_ptr<AArch64Operand>
2373 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2374 Op->MatrixTileList.RegMask = RegMask;
2381 const unsigned ElementWidth) {
2382 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2384 {{0, AArch64::ZAB0},
2385 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2386 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2387 {{8, AArch64::ZAB0},
2388 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2389 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2390 {{16, AArch64::ZAH0},
2391 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2392 {{16, AArch64::ZAH1},
2393 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2394 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2395 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2396 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2397 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2400 if (ElementWidth == 64)
2403 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2404 assert(!Regs.empty() &&
"Invalid tile or element width!");
2405 for (
auto OutReg : Regs)
2410 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2412 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2419 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2420 unsigned ShiftAmount,
2423 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2424 Op->ShiftedImm .Val = Val;
2425 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2431 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2435 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2437 Op->ImmRange.Last =
Last;
2442 static std::unique_ptr<AArch64Operand>
2444 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2445 Op->CondCode.Code =
Code;
2451 static std::unique_ptr<AArch64Operand>
2453 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2455 Op->FPImm.IsExact = IsExact;
2461 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2465 bool HasnXSModifier) {
2466 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2467 Op->Barrier.Val = Val;
2468 Op->Barrier.Data = Str.data();
2469 Op->Barrier.Length = Str.size();
2470 Op->Barrier.HasnXSModifier = HasnXSModifier;
2476 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2481 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2482 Op->SysReg.Data = Str.data();
2483 Op->SysReg.Length = Str.size();
2484 Op->SysReg.MRSReg = MRSReg;
2485 Op->SysReg.MSRReg = MSRReg;
2486 Op->SysReg.PStateField = PStateField;
2492 static std::unique_ptr<AArch64Operand>
2494 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2495 Op->PHint.Val = Val;
2496 Op->PHint.Data = Str.data();
2497 Op->PHint.Length = Str.size();
2503 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2505 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2506 Op->SysCRImm.Val = Val;
2512 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2516 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2517 Op->Prefetch.Val = Val;
2518 Op->Barrier.Data = Str.data();
2519 Op->Barrier.Length = Str.size();
2525 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2529 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2530 Op->PSBHint.Val = Val;
2531 Op->PSBHint.Data = Str.data();
2532 Op->PSBHint.Length = Str.size();
2538 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2542 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2543 Op->BTIHint.Val = Val | 32;
2544 Op->BTIHint.Data = Str.data();
2545 Op->BTIHint.Length = Str.size();
2551 static std::unique_ptr<AArch64Operand>
2552 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2554 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2555 Op->MatrixReg.RegNum = RegNum;
2556 Op->MatrixReg.ElementWidth = ElementWidth;
2557 Op->MatrixReg.Kind =
Kind;
2563 static std::unique_ptr<AArch64Operand>
2565 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2566 Op->SVCR.PStateField = PStateField;
2567 Op->SVCR.Data = Str.data();
2568 Op->SVCR.Length = Str.size();
2574 static std::unique_ptr<AArch64Operand>
2577 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2578 Op->ShiftExtend.Type = ShOp;
2579 Op->ShiftExtend.Amount = Val;
2580 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2592 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2593 if (!getFPImmIsExact())
2600 OS <<
"<barrier " <<
Name <<
">";
2602 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2608 case k_ShiftedImm: {
2609 unsigned Shift = getShiftedImmShift();
2610 OS <<
"<shiftedimm ";
2611 OS << *getShiftedImmVal();
2617 OS << getFirstImmVal();
2618 OS <<
":" << getLastImmVal() <<
">";
2624 case k_VectorList: {
2625 OS <<
"<vectorlist ";
2626 unsigned Reg = getVectorListStart();
2627 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2628 OS <<
Reg + i * getVectorListStride() <<
" ";
2633 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2636 OS <<
"<sysreg: " << getSysReg() <<
'>';
2639 OS <<
"'" << getToken() <<
"'";
2642 OS <<
"c" << getSysCR();
2647 OS <<
"<prfop " <<
Name <<
">";
2649 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2653 OS << getPSBHintName();
2656 OS << getPHintName();
2659 OS << getBTIHintName();
2661 case k_MatrixRegister:
2662 OS <<
"<matrix " << getMatrixReg() <<
">";
2664 case k_MatrixTileList: {
2665 OS <<
"<matrixlist ";
2666 unsigned RegMask = getMatrixTileListRegMask();
2667 unsigned MaxBits = 8;
2668 for (
unsigned I = MaxBits;
I > 0; --
I)
2669 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2678 OS <<
"<register " <<
getReg() <<
">";
2679 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2684 << getShiftExtendAmount();
2685 if (!hasShiftExtendAmount())
2701 .
Case(
"v0", AArch64::Q0)
2702 .
Case(
"v1", AArch64::Q1)
2703 .
Case(
"v2", AArch64::Q2)
2704 .
Case(
"v3", AArch64::Q3)
2705 .
Case(
"v4", AArch64::Q4)
2706 .
Case(
"v5", AArch64::Q5)
2707 .
Case(
"v6", AArch64::Q6)
2708 .
Case(
"v7", AArch64::Q7)
2709 .
Case(
"v8", AArch64::Q8)
2710 .
Case(
"v9", AArch64::Q9)
2711 .
Case(
"v10", AArch64::Q10)
2712 .
Case(
"v11", AArch64::Q11)
2713 .
Case(
"v12", AArch64::Q12)
2714 .
Case(
"v13", AArch64::Q13)
2715 .
Case(
"v14", AArch64::Q14)
2716 .
Case(
"v15", AArch64::Q15)
2717 .
Case(
"v16", AArch64::Q16)
2718 .
Case(
"v17", AArch64::Q17)
2719 .
Case(
"v18", AArch64::Q18)
2720 .
Case(
"v19", AArch64::Q19)
2721 .
Case(
"v20", AArch64::Q20)
2722 .
Case(
"v21", AArch64::Q21)
2723 .
Case(
"v22", AArch64::Q22)
2724 .
Case(
"v23", AArch64::Q23)
2725 .
Case(
"v24", AArch64::Q24)
2726 .
Case(
"v25", AArch64::Q25)
2727 .
Case(
"v26", AArch64::Q26)
2728 .
Case(
"v27", AArch64::Q27)
2729 .
Case(
"v28", AArch64::Q28)
2730 .
Case(
"v29", AArch64::Q29)
2731 .
Case(
"v30", AArch64::Q30)
2732 .
Case(
"v31", AArch64::Q31)
2741 RegKind VectorKind) {
2742 std::pair<int, int> Res = {-1, -1};
2744 switch (VectorKind) {
2745 case RegKind::NeonVector:
2748 .Case(
".1d", {1, 64})
2749 .Case(
".1q", {1, 128})
2751 .Case(
".2h", {2, 16})
2752 .Case(
".2b", {2, 8})
2753 .Case(
".2s", {2, 32})
2754 .Case(
".2d", {2, 64})
2757 .Case(
".4b", {4, 8})
2758 .Case(
".4h", {4, 16})
2759 .Case(
".4s", {4, 32})
2760 .Case(
".8b", {8, 8})
2761 .Case(
".8h", {8, 16})
2762 .Case(
".16b", {16, 8})
2767 .Case(
".h", {0, 16})
2768 .Case(
".s", {0, 32})
2769 .Case(
".d", {0, 64})
2772 case RegKind::SVEPredicateAsCounter:
2773 case RegKind::SVEPredicateVector:
2774 case RegKind::SVEDataVector:
2775 case RegKind::Matrix:
2779 .Case(
".h", {0, 16})
2780 .Case(
".s", {0, 32})
2781 .Case(
".d", {0, 64})
2782 .Case(
".q", {0, 128})
2789 if (Res == std::make_pair(-1, -1))
2790 return std::nullopt;
2792 return std::optional<std::pair<int, int>>(Res);
2801 .
Case(
"z0", AArch64::Z0)
2802 .
Case(
"z1", AArch64::Z1)
2803 .
Case(
"z2", AArch64::Z2)
2804 .
Case(
"z3", AArch64::Z3)
2805 .
Case(
"z4", AArch64::Z4)
2806 .
Case(
"z5", AArch64::Z5)
2807 .
Case(
"z6", AArch64::Z6)
2808 .
Case(
"z7", AArch64::Z7)
2809 .
Case(
"z8", AArch64::Z8)
2810 .
Case(
"z9", AArch64::Z9)
2811 .
Case(
"z10", AArch64::Z10)
2812 .
Case(
"z11", AArch64::Z11)
2813 .
Case(
"z12", AArch64::Z12)
2814 .
Case(
"z13", AArch64::Z13)
2815 .
Case(
"z14", AArch64::Z14)
2816 .
Case(
"z15", AArch64::Z15)
2817 .
Case(
"z16", AArch64::Z16)
2818 .
Case(
"z17", AArch64::Z17)
2819 .
Case(
"z18", AArch64::Z18)
2820 .
Case(
"z19", AArch64::Z19)
2821 .
Case(
"z20", AArch64::Z20)
2822 .
Case(
"z21", AArch64::Z21)
2823 .
Case(
"z22", AArch64::Z22)
2824 .
Case(
"z23", AArch64::Z23)
2825 .
Case(
"z24", AArch64::Z24)
2826 .
Case(
"z25", AArch64::Z25)
2827 .
Case(
"z26", AArch64::Z26)
2828 .
Case(
"z27", AArch64::Z27)
2829 .
Case(
"z28", AArch64::Z28)
2830 .
Case(
"z29", AArch64::Z29)
2831 .
Case(
"z30", AArch64::Z30)
2832 .
Case(
"z31", AArch64::Z31)
2838 .
Case(
"p0", AArch64::P0)
2839 .
Case(
"p1", AArch64::P1)
2840 .
Case(
"p2", AArch64::P2)
2841 .
Case(
"p3", AArch64::P3)
2842 .
Case(
"p4", AArch64::P4)
2843 .
Case(
"p5", AArch64::P5)
2844 .
Case(
"p6", AArch64::P6)
2845 .
Case(
"p7", AArch64::P7)
2846 .
Case(
"p8", AArch64::P8)
2847 .
Case(
"p9", AArch64::P9)
2848 .
Case(
"p10", AArch64::P10)
2849 .
Case(
"p11", AArch64::P11)
2850 .
Case(
"p12", AArch64::P12)
2851 .
Case(
"p13", AArch64::P13)
2852 .
Case(
"p14", AArch64::P14)
2853 .
Case(
"p15", AArch64::P15)
2859 .
Case(
"pn0", AArch64::PN0)
2860 .
Case(
"pn1", AArch64::PN1)
2861 .
Case(
"pn2", AArch64::PN2)
2862 .
Case(
"pn3", AArch64::PN3)
2863 .
Case(
"pn4", AArch64::PN4)
2864 .
Case(
"pn5", AArch64::PN5)
2865 .
Case(
"pn6", AArch64::PN6)
2866 .
Case(
"pn7", AArch64::PN7)
2867 .
Case(
"pn8", AArch64::PN8)
2868 .
Case(
"pn9", AArch64::PN9)
2869 .
Case(
"pn10", AArch64::PN10)
2870 .
Case(
"pn11", AArch64::PN11)
2871 .
Case(
"pn12", AArch64::PN12)
2872 .
Case(
"pn13", AArch64::PN13)
2873 .
Case(
"pn14", AArch64::PN14)
2874 .
Case(
"pn15", AArch64::PN15)
2880 .
Case(
"za0.d", AArch64::ZAD0)
2881 .
Case(
"za1.d", AArch64::ZAD1)
2882 .
Case(
"za2.d", AArch64::ZAD2)
2883 .
Case(
"za3.d", AArch64::ZAD3)
2884 .
Case(
"za4.d", AArch64::ZAD4)
2885 .
Case(
"za5.d", AArch64::ZAD5)
2886 .
Case(
"za6.d", AArch64::ZAD6)
2887 .
Case(
"za7.d", AArch64::ZAD7)
2888 .
Case(
"za0.s", AArch64::ZAS0)
2889 .
Case(
"za1.s", AArch64::ZAS1)
2890 .
Case(
"za2.s", AArch64::ZAS2)
2891 .
Case(
"za3.s", AArch64::ZAS3)
2892 .
Case(
"za0.h", AArch64::ZAH0)
2893 .
Case(
"za1.h", AArch64::ZAH1)
2894 .
Case(
"za0.b", AArch64::ZAB0)
2900 .
Case(
"za", AArch64::ZA)
2901 .
Case(
"za0.q", AArch64::ZAQ0)
2902 .
Case(
"za1.q", AArch64::ZAQ1)
2903 .
Case(
"za2.q", AArch64::ZAQ2)
2904 .
Case(
"za3.q", AArch64::ZAQ3)
2905 .
Case(
"za4.q", AArch64::ZAQ4)
2906 .
Case(
"za5.q", AArch64::ZAQ5)
2907 .
Case(
"za6.q", AArch64::ZAQ6)
2908 .
Case(
"za7.q", AArch64::ZAQ7)
2909 .
Case(
"za8.q", AArch64::ZAQ8)
2910 .
Case(
"za9.q", AArch64::ZAQ9)
2911 .
Case(
"za10.q", AArch64::ZAQ10)
2912 .
Case(
"za11.q", AArch64::ZAQ11)
2913 .
Case(
"za12.q", AArch64::ZAQ12)
2914 .
Case(
"za13.q", AArch64::ZAQ13)
2915 .
Case(
"za14.q", AArch64::ZAQ14)
2916 .
Case(
"za15.q", AArch64::ZAQ15)
2917 .
Case(
"za0.d", AArch64::ZAD0)
2918 .
Case(
"za1.d", AArch64::ZAD1)
2919 .
Case(
"za2.d", AArch64::ZAD2)
2920 .
Case(
"za3.d", AArch64::ZAD3)
2921 .
Case(
"za4.d", AArch64::ZAD4)
2922 .
Case(
"za5.d", AArch64::ZAD5)
2923 .
Case(
"za6.d", AArch64::ZAD6)
2924 .
Case(
"za7.d", AArch64::ZAD7)
2925 .
Case(
"za0.s", AArch64::ZAS0)
2926 .
Case(
"za1.s", AArch64::ZAS1)
2927 .
Case(
"za2.s", AArch64::ZAS2)
2928 .
Case(
"za3.s", AArch64::ZAS3)
2929 .
Case(
"za0.h", AArch64::ZAH0)
2930 .
Case(
"za1.h", AArch64::ZAH1)
2931 .
Case(
"za0.b", AArch64::ZAB0)
2932 .
Case(
"za0h.q", AArch64::ZAQ0)
2933 .
Case(
"za1h.q", AArch64::ZAQ1)
2934 .
Case(
"za2h.q", AArch64::ZAQ2)
2935 .
Case(
"za3h.q", AArch64::ZAQ3)
2936 .
Case(
"za4h.q", AArch64::ZAQ4)
2937 .
Case(
"za5h.q", AArch64::ZAQ5)
2938 .
Case(
"za6h.q", AArch64::ZAQ6)
2939 .
Case(
"za7h.q", AArch64::ZAQ7)
2940 .
Case(
"za8h.q", AArch64::ZAQ8)
2941 .
Case(
"za9h.q", AArch64::ZAQ9)
2942 .
Case(
"za10h.q", AArch64::ZAQ10)
2943 .
Case(
"za11h.q", AArch64::ZAQ11)
2944 .
Case(
"za12h.q", AArch64::ZAQ12)
2945 .
Case(
"za13h.q", AArch64::ZAQ13)
2946 .
Case(
"za14h.q", AArch64::ZAQ14)
2947 .
Case(
"za15h.q", AArch64::ZAQ15)
2948 .
Case(
"za0h.d", AArch64::ZAD0)
2949 .
Case(
"za1h.d", AArch64::ZAD1)
2950 .
Case(
"za2h.d", AArch64::ZAD2)
2951 .
Case(
"za3h.d", AArch64::ZAD3)
2952 .
Case(
"za4h.d", AArch64::ZAD4)
2953 .
Case(
"za5h.d", AArch64::ZAD5)
2954 .
Case(
"za6h.d", AArch64::ZAD6)
2955 .
Case(
"za7h.d", AArch64::ZAD7)
2956 .
Case(
"za0h.s", AArch64::ZAS0)
2957 .
Case(
"za1h.s", AArch64::ZAS1)
2958 .
Case(
"za2h.s", AArch64::ZAS2)
2959 .
Case(
"za3h.s", AArch64::ZAS3)
2960 .
Case(
"za0h.h", AArch64::ZAH0)
2961 .
Case(
"za1h.h", AArch64::ZAH1)
2962 .
Case(
"za0h.b", AArch64::ZAB0)
2963 .
Case(
"za0v.q", AArch64::ZAQ0)
2964 .
Case(
"za1v.q", AArch64::ZAQ1)
2965 .
Case(
"za2v.q", AArch64::ZAQ2)
2966 .
Case(
"za3v.q", AArch64::ZAQ3)
2967 .
Case(
"za4v.q", AArch64::ZAQ4)
2968 .
Case(
"za5v.q", AArch64::ZAQ5)
2969 .
Case(
"za6v.q", AArch64::ZAQ6)
2970 .
Case(
"za7v.q", AArch64::ZAQ7)
2971 .
Case(
"za8v.q", AArch64::ZAQ8)
2972 .
Case(
"za9v.q", AArch64::ZAQ9)
2973 .
Case(
"za10v.q", AArch64::ZAQ10)
2974 .
Case(
"za11v.q", AArch64::ZAQ11)
2975 .
Case(
"za12v.q", AArch64::ZAQ12)
2976 .
Case(
"za13v.q", AArch64::ZAQ13)
2977 .
Case(
"za14v.q", AArch64::ZAQ14)
2978 .
Case(
"za15v.q", AArch64::ZAQ15)
2979 .
Case(
"za0v.d", AArch64::ZAD0)
2980 .
Case(
"za1v.d", AArch64::ZAD1)
2981 .
Case(
"za2v.d", AArch64::ZAD2)
2982 .
Case(
"za3v.d", AArch64::ZAD3)
2983 .
Case(
"za4v.d", AArch64::ZAD4)
2984 .
Case(
"za5v.d", AArch64::ZAD5)
2985 .
Case(
"za6v.d", AArch64::ZAD6)
2986 .
Case(
"za7v.d", AArch64::ZAD7)
2987 .
Case(
"za0v.s", AArch64::ZAS0)
2988 .
Case(
"za1v.s", AArch64::ZAS1)
2989 .
Case(
"za2v.s", AArch64::ZAS2)
2990 .
Case(
"za3v.s", AArch64::ZAS3)
2991 .
Case(
"za0v.h", AArch64::ZAH0)
2992 .
Case(
"za1v.h", AArch64::ZAH1)
2993 .
Case(
"za0v.b", AArch64::ZAB0)
2999 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3004 StartLoc = getLoc();
3011unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
3013 unsigned RegNum = 0;
3015 return Kind == RegKind::SVEDataVector ? RegNum : 0;
3018 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
3021 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
3024 return Kind == RegKind::NeonVector ? RegNum : 0;
3027 return Kind == RegKind::Matrix ? RegNum : 0;
3029 if (
Name.equals_insensitive(
"zt0"))
3030 return Kind == RegKind::LookupTable ?
unsigned(AArch64::ZT0) : 0;
3034 return (Kind == RegKind::Scalar) ? RegNum : 0;
3039 .
Case(
"fp", AArch64::FP)
3040 .
Case(
"lr", AArch64::LR)
3041 .
Case(
"x31", AArch64::XZR)
3042 .
Case(
"w31", AArch64::WZR)
3044 return Kind == RegKind::Scalar ? RegNum : 0;
3050 if (Entry == RegisterReqs.
end())
3054 if (Kind ==
Entry->getValue().first)
3055 RegNum =
Entry->getValue().second;
3060unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3062 case RegKind::Scalar:
3063 case RegKind::NeonVector:
3064 case RegKind::SVEDataVector:
3066 case RegKind::Matrix:
3067 case RegKind::SVEPredicateVector:
3068 case RegKind::SVEPredicateAsCounter:
3070 case RegKind::LookupTable:
3085 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3099 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3102 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3103 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3107 if (BadNum || CRNum > 15)
3108 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3112 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3121 unsigned MaxVal = 63;
3127 if (getParser().parseExpression(ImmVal))
3132 return TokError(
"immediate value expected for prefetch operand");
3135 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3138 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3139 Operands.push_back(AArch64Operand::CreatePrefetch(
3140 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3145 return TokError(
"prefetch hint expected");
3147 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3149 return TokError(
"prefetch hint expected");
3151 Operands.push_back(AArch64Operand::CreatePrefetch(
3152 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3158template <
bool IsSVEPrefetch>
3164 if (IsSVEPrefetch) {
3165 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3166 return std::optional<unsigned>(Res->Encoding);
3167 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3168 return std::optional<unsigned>(Res->Encoding);
3169 return std::optional<unsigned>();
3172 auto LookupByEncoding = [](
unsigned E) {
3173 if (IsSVEPrefetch) {
3174 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3175 return std::optional<StringRef>(Res->Name);
3176 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3177 return std::optional<StringRef>(Res->Name);
3178 return std::optional<StringRef>();
3180 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3187 if (getParser().parseExpression(ImmVal))
3192 return TokError(
"immediate value expected for prefetch operand");
3195 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3198 auto PRFM = LookupByEncoding(MCE->
getValue());
3199 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3205 return TokError(
"prefetch hint expected");
3207 auto PRFM = LookupByName(Tok.
getString());
3209 return TokError(
"prefetch hint expected");
3211 Operands.push_back(AArch64Operand::CreatePrefetch(
3212 *PRFM, Tok.
getString(), S, getContext()));
3222 return TokError(
"invalid operand for instruction");
3224 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3226 return TokError(
"invalid operand for instruction");
3228 Operands.push_back(AArch64Operand::CreatePSBHint(
3229 PSB->Encoding, Tok.
getString(), S, getContext()));
3235 SMLoc StartLoc = getLoc();
3241 auto RegTok = getTok();
3242 if (!tryParseScalarRegister(RegNum).isSuccess())
3245 if (RegNum != AArch64::XZR) {
3246 getLexer().UnLex(RegTok);
3253 if (!tryParseScalarRegister(RegNum).isSuccess())
3254 return TokError(
"expected register operand");
3256 if (RegNum != AArch64::XZR)
3257 return TokError(
"xzr must be followed by xzr");
3261 Operands.push_back(AArch64Operand::CreateReg(
3262 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3272 return TokError(
"invalid operand for instruction");
3274 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3276 return TokError(
"invalid operand for instruction");
3278 Operands.push_back(AArch64Operand::CreateBTIHint(
3279 BTI->Encoding, Tok.
getString(), S, getContext()));
3288 const MCExpr *Expr =
nullptr;
3294 if (parseSymbolicImmVal(Expr))
3300 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3310 return Error(S,
"gotpage label reference not allowed an addend");
3322 return Error(S,
"page or gotpage label reference expected");
3330 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3339 const MCExpr *Expr =
nullptr;
3348 if (parseSymbolicImmVal(Expr))
3354 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3367 return Error(S,
"unexpected adr label");
3372 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3377template <
bool AddFPZeroAsLiteral>
3390 return TokError(
"invalid floating point immediate");
3395 if (Tok.
getIntVal() > 255 || isNegative)
3396 return TokError(
"encoded floating point value out of range");
3400 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3403 APFloat RealVal(APFloat::IEEEdouble());
3405 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3407 return TokError(
"invalid floating point representation");
3410 RealVal.changeSign();
3412 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3413 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3414 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3416 Operands.push_back(AArch64Operand::CreateFPImm(
3417 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3442 if (parseSymbolicImmVal(Imm))
3446 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3453 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3455 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3457 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3463 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3464 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3472 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3474 int64_t ShiftAmount = getTok().getIntVal();
3476 if (ShiftAmount < 0)
3477 return Error(getLoc(),
"positive shift amount required");
3481 if (ShiftAmount == 0 && Imm !=
nullptr) {
3483 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3487 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3488 getLoc(), getContext()));
3495AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3532 Suggestion =
"nfrst";
3539 bool invertCondCode) {
3545 std::string Suggestion;
3548 std::string Msg =
"invalid condition code";
3549 if (!Suggestion.empty())
3550 Msg +=
", did you mean " + Suggestion +
"?";
3551 return TokError(Msg);
3555 if (invertCondCode) {
3557 return TokError(
"condition codes AL and NV are invalid for this instruction");
3562 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3571 return TokError(
"invalid operand for instruction");
3573 unsigned PStateImm = -1;
3574 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3577 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3578 PStateImm = SVCR->Encoding;
3581 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3592 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3594 unsigned ElementWidth = 0;
3595 auto DotPosition =
Name.find(
'.');
3597 const auto &KindRes =
3601 "Expected the register to be followed by element width suffix");
3602 ElementWidth = KindRes->second;
3604 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3605 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3610 if (parseOperand(
Operands,
false,
false))
3617 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3621 size_t DotPosition =
Name.find(
'.');
3629 .
Case(
"h", MatrixKind::Row)
3630 .
Case(
"v", MatrixKind::Col)
3637 "Expected the register to be followed by element width suffix");
3638 unsigned ElementWidth = KindRes->second;
3642 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3643 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3648 if (parseOperand(
Operands,
false,
false))
3690 return TokError(
"expected #imm after shift specifier");
3696 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3705 return Error(
E,
"expected integer shift amount");
3708 if (getParser().parseExpression(ImmVal))
3713 return Error(
E,
"expected constant '#imm' after shift specifier");
3716 Operands.push_back(AArch64Operand::CreateShiftExtend(
3717 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3725 {
"crc", {AArch64::FeatureCRC}},
3726 {
"sm4", {AArch64::FeatureSM4}},
3727 {
"sha3", {AArch64::FeatureSHA3}},
3728 {
"sha2", {AArch64::FeatureSHA2}},
3729 {
"aes", {AArch64::FeatureAES}},
3730 {
"crypto", {AArch64::FeatureCrypto}},
3731 {
"fp", {AArch64::FeatureFPARMv8}},
3732 {
"simd", {AArch64::FeatureNEON}},
3733 {
"ras", {AArch64::FeatureRAS}},
3734 {
"rasv2", {AArch64::FeatureRASv2}},
3735 {
"lse", {AArch64::FeatureLSE}},
3736 {
"predres", {AArch64::FeaturePredRes}},
3737 {
"predres2", {AArch64::FeatureSPECRES2}},
3738 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3739 {
"mte", {AArch64::FeatureMTE}},
3740 {
"memtag", {AArch64::FeatureMTE}},
3741 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3742 {
"pan", {AArch64::FeaturePAN}},
3743 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3744 {
"ccpp", {AArch64::FeatureCCPP}},
3745 {
"rcpc", {AArch64::FeatureRCPC}},
3746 {
"rng", {AArch64::FeatureRandGen}},
3747 {
"sve", {AArch64::FeatureSVE}},
3748 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3749 {
"sve2", {AArch64::FeatureSVE2}},
3750 {
"sve-aes", {AArch64::FeatureSVEAES}},
3751 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3752 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3753 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3754 {
"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3755 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3756 {
"ls64", {AArch64::FeatureLS64}},
3757 {
"xs", {AArch64::FeatureXS}},
3758 {
"pauth", {AArch64::FeaturePAuth}},
3759 {
"flagm", {AArch64::FeatureFlagM}},
3760 {
"rme", {AArch64::FeatureRME}},
3761 {
"sme", {AArch64::FeatureSME}},
3762 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3763 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3764 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3765 {
"sme2", {AArch64::FeatureSME2}},
3766 {
"sme2p1", {AArch64::FeatureSME2p1}},
3767 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3768 {
"hbc", {AArch64::FeatureHBC}},
3769 {
"mops", {AArch64::FeatureMOPS}},
3770 {
"mec", {AArch64::FeatureMEC}},
3771 {
"the", {AArch64::FeatureTHE}},
3772 {
"d128", {AArch64::FeatureD128}},
3773 {
"lse128", {AArch64::FeatureLSE128}},
3774 {
"ite", {AArch64::FeatureITE}},
3775 {
"cssc", {AArch64::FeatureCSSC}},
3776 {
"rcpc3", {AArch64::FeatureRCPC3}},
3777 {
"gcs", {AArch64::FeatureGCS}},
3778 {
"bf16", {AArch64::FeatureBF16}},
3779 {
"compnum", {AArch64::FeatureComplxNum}},
3780 {
"dotprod", {AArch64::FeatureDotProd}},
3781 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3782 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3783 {
"fp16", {AArch64::FeatureFullFP16}},
3784 {
"fp16fml", {AArch64::FeatureFP16FML}},
3785 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3786 {
"lor", {AArch64::FeatureLOR}},
3787 {
"profile", {AArch64::FeatureSPE}},
3791 {
"rdm", {AArch64::FeatureRDM}},
3792 {
"rdma", {AArch64::FeatureRDM}},
3793 {
"sb", {AArch64::FeatureSB}},
3794 {
"ssbs", {AArch64::FeatureSSBS}},
3795 {
"tme", {AArch64::FeatureTME}},
3796 {
"fp8", {AArch64::FeatureFP8}},
3797 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3798 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3799 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3800 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3801 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3802 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3803 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3804 {
"lut", {AArch64::FeatureLUT}},
3805 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3806 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3807 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3808 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3809 {
"cpa", {AArch64::FeatureCPA}},
3810 {
"tlbiw", {AArch64::FeatureTLBIW}},
3811 {
"pops", {AArch64::FeaturePoPS}},
3812 {
"cmpbr", {AArch64::FeatureCMPBR}},
3813 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3814 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3815 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3816 {
"lsfe", {AArch64::FeatureLSFE}},
3817 {
"sme2p2", {AArch64::FeatureSME2p2}},
3818 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3819 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3820 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3821 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3822 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3823 {
"lsui", {AArch64::FeatureLSUI}},
3824 {
"occmo", {AArch64::FeatureOCCMO}},
3825 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3829 if (FBS[AArch64::HasV8_0aOps])
3831 if (FBS[AArch64::HasV8_1aOps])
3833 else if (FBS[AArch64::HasV8_2aOps])
3835 else if (FBS[AArch64::HasV8_3aOps])
3837 else if (FBS[AArch64::HasV8_4aOps])
3839 else if (FBS[AArch64::HasV8_5aOps])
3841 else if (FBS[AArch64::HasV8_6aOps])
3843 else if (FBS[AArch64::HasV8_7aOps])
3845 else if (FBS[AArch64::HasV8_8aOps])
3847 else if (FBS[AArch64::HasV8_9aOps])
3849 else if (FBS[AArch64::HasV9_0aOps])
3851 else if (FBS[AArch64::HasV9_1aOps])
3853 else if (FBS[AArch64::HasV9_2aOps])
3855 else if (FBS[AArch64::HasV9_3aOps])
3857 else if (FBS[AArch64::HasV9_4aOps])
3859 else if (FBS[AArch64::HasV9_5aOps])
3861 else if (FBS[AArch64::HasV9_6aOps])
3863 else if (FBS[AArch64::HasV8_0rOps])
3872 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3879 const uint16_t Cm = (Encoding & 0x78) >> 3;
3880 const uint16_t Cn = (Encoding & 0x780) >> 7;
3881 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3886 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3888 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3890 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3893 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3900 if (
Name.contains(
'.'))
3901 return TokError(
"invalid operand");
3904 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3910 if (Mnemonic ==
"ic") {
3913 return TokError(
"invalid operand for IC instruction");
3914 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3915 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3917 return TokError(Str);
3920 }
else if (Mnemonic ==
"dc") {
3923 return TokError(
"invalid operand for DC instruction");
3924 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3925 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3927 return TokError(Str);
3930 }
else if (Mnemonic ==
"at") {
3933 return TokError(
"invalid operand for AT instruction");
3934 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3935 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3937 return TokError(Str);
3940 }
else if (Mnemonic ==
"tlbi") {
3943 return TokError(
"invalid operand for TLBI instruction");
3944 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3945 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3947 return TokError(Str);
3950 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3952 if (
Op.lower() !=
"rctx")
3953 return TokError(
"invalid operand for prediction restriction instruction");
3955 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3956 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3957 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3959 if (Mnemonic ==
"cosp" && !hasSpecres2)
3960 return TokError(
"COSP requires: predres2");
3962 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3964 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3965 : Mnemonic ==
"dvp" ? 0b101
3966 : Mnemonic ==
"cosp" ? 0b110
3967 : Mnemonic ==
"cpp" ? 0b111
3970 "Invalid mnemonic for prediction restriction instruction");
3971 const auto SYS_3_7_3 = 0b01101110011;
3972 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3974 createSysAlias(Encoding,
Operands, S);
3979 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3980 bool HasRegister =
false;
3985 return TokError(
"expected register operand");
3989 if (ExpectRegister && !HasRegister)
3990 return TokError(
"specified " + Mnemonic +
" op requires a register");
3991 else if (!ExpectRegister && HasRegister)
3992 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4004 if (
Name.contains(
'.'))
4005 return TokError(
"invalid operand");
4009 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
4015 if (Mnemonic ==
"tlbip") {
4016 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4017 if (HasnXSQualifier) {
4018 Op =
Op.drop_back(3);
4022 return TokError(
"invalid operand for TLBIP instruction");
4024 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4031 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
4032 std::string Str(
"TLBIP " +
Name +
" requires: ");
4034 return TokError(Str);
4045 return TokError(
"expected register identifier");
4050 return TokError(
"specified " + Mnemonic +
4051 " op requires a pair of registers");
4064 return TokError(
"'csync' operand expected");
4068 SMLoc ExprLoc = getLoc();
4070 if (getParser().parseExpression(ImmVal))
4074 return Error(ExprLoc,
"immediate value expected for barrier operand");
4076 if (Mnemonic ==
"dsb" &&
Value > 15) {
4083 if (Value < 0 || Value > 15)
4084 return Error(ExprLoc,
"barrier operand out of range");
4085 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4086 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4087 ExprLoc, getContext(),
4093 return TokError(
"invalid operand for instruction");
4096 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4097 auto DB = AArch64DB::lookupDBByName(Operand);
4099 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4100 return TokError(
"'sy' or #imm operand expected");
4102 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4103 return TokError(
"'csync' operand expected");
4105 if (Mnemonic ==
"dsb") {
4110 return TokError(
"invalid barrier option name");
4113 Operands.push_back(AArch64Operand::CreateBarrier(
4114 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4115 getContext(),
false ));
4125 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4126 if (Mnemonic !=
"dsb")
4132 SMLoc ExprLoc = getLoc();
4133 if (getParser().parseExpression(ImmVal))
4137 return Error(ExprLoc,
"immediate value expected for barrier operand");
4142 return Error(ExprLoc,
"barrier operand out of range");
4143 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4144 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4145 ExprLoc, getContext(),
4151 return TokError(
"invalid operand for instruction");
4154 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4157 return TokError(
"invalid barrier option name");
4160 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4161 getContext(),
true ));
4173 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4178 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4179 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4180 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4184 unsigned PStateImm = -1;
4185 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4186 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4187 PStateImm = PState15->Encoding;
4189 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4190 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4191 PStateImm = PState1->Encoding;
4195 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4196 PStateImm, getContext()));
4207 return TokError(
"invalid operand for instruction");
4211 return TokError(
"invalid operand for instruction");
4213 Operands.push_back(AArch64Operand::CreatePHintInst(
4214 PH->Encoding, Tok.
getString(), S, getContext()));
4228 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4236 unsigned ElementWidth = KindRes->second;
4238 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4239 S, getLoc(), getContext()));
4244 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4246 return tryParseVectorIndex(
Operands).isFailure();
4250 SMLoc SIdx = getLoc();
4253 if (getParser().parseExpression(ImmVal))
4257 return TokError(
"immediate value expected for vector index");
4264 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4277 RegKind MatchKind) {
4286 size_t Start = 0, Next =
Name.find(
'.');
4288 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4294 return TokError(
"invalid vector kind qualifier");
4305ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4308 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4310 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4315template <RegKind RK>
4319 const SMLoc S = getLoc();
4322 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4330 unsigned ElementWidth = KindRes->second;
4331 Operands.push_back(AArch64Operand::CreateVectorReg(
4332 RegNum, RK, ElementWidth, S,
4333 getLoc(), getContext()));
4336 if (RK == RegKind::SVEPredicateAsCounter) {
4343 if (parseOperand(
Operands,
false,
false))
4354 return Error(S,
"not expecting size suffix");
4357 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4362 auto Pred = getTok().getString().lower();
4363 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4364 return Error(getLoc(),
"expecting 'z' predication");
4366 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4367 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4370 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4371 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4380 if (!tryParseNeonVectorRegister(
Operands))
4383 if (tryParseZTOperand(
Operands).isSuccess())
4387 if (tryParseGPROperand<false>(
Operands).isSuccess())
4393bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4394 bool HasELFModifier =
false;
4398 HasELFModifier =
true;
4401 return TokError(
"expect relocation specifier in operand after ':'");
4403 std::string LowerCase = getTok().getIdentifier().lower();
4459 return TokError(
"expect relocation specifier in operand after ':'");
4463 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4467 if (getParser().parseExpression(ImmVal))
4480 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4483 size_t DotPosition =
Name.find(
'.');
4492 const std::optional<std::pair<int, int>> &KindRes =
4496 "Expected the register to be followed by element width suffix");
4497 ElementWidth = KindRes->second;
4504 auto LCurly = getTok();
4509 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4510 0, S, getLoc(), getContext()));
4515 if (getTok().getString().equals_insensitive(
"za")) {
4521 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4522 0xFF, S, getLoc(), getContext()));
4526 SMLoc TileLoc = getLoc();
4528 unsigned FirstReg, ElementWidth;
4529 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4530 if (!ParseRes.isSuccess()) {
4531 getLexer().UnLex(LCurly);
4537 unsigned PrevReg = FirstReg;
4540 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4543 SeenRegs.
insert(FirstReg);
4547 unsigned Reg, NextElementWidth;
4548 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4549 if (!ParseRes.isSuccess())
4553 if (ElementWidth != NextElementWidth)
4554 return Error(TileLoc,
"mismatched register size suffix");
4557 Warning(TileLoc,
"tile list not in ascending order");
4560 Warning(TileLoc,
"duplicate tile in list");
4563 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4572 unsigned RegMask = 0;
4573 for (
auto Reg : DRegs)
4577 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4582template <RegKind VectorKind>
4592 auto RegTok = getTok();
4593 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4594 if (ParseRes.isSuccess()) {
4601 RegTok.getString().equals_insensitive(
"zt0"))
4605 (ParseRes.isNoMatch() && NoMatchIsError &&
4606 !RegTok.getString().starts_with_insensitive(
"za")))
4607 return Error(Loc,
"vector register expected");
4612 int NumRegs = getNumRegsForRegKind(VectorKind);
4614 auto LCurly = getTok();
4619 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4623 if (ParseRes.isNoMatch())
4626 if (!ParseRes.isSuccess())
4629 int64_t PrevReg = FirstReg;
4634 SMLoc Loc = getLoc();
4638 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4639 if (!ParseRes.isSuccess())
4643 if (Kind != NextKind)
4644 return Error(Loc,
"mismatched register size suffix");
4647 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4649 if (Space == 0 || Space > 3)
4650 return Error(Loc,
"invalid number of vectors");
4655 bool HasCalculatedStride =
false;
4657 SMLoc Loc = getLoc();
4660 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4661 if (!ParseRes.isSuccess())
4665 if (Kind != NextKind)
4666 return Error(Loc,
"mismatched register size suffix");
4668 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4669 unsigned PrevRegVal =
4670 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4671 if (!HasCalculatedStride) {
4672 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4673 : (RegVal + NumRegs - PrevRegVal);
4674 HasCalculatedStride =
true;
4678 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4679 return Error(Loc,
"registers must have the same sequential stride");
4690 return Error(S,
"invalid number of vectors");
4692 unsigned NumElements = 0;
4693 unsigned ElementWidth = 0;
4694 if (!
Kind.empty()) {
4696 std::tie(NumElements, ElementWidth) = *VK;
4699 Operands.push_back(AArch64Operand::CreateVectorList(
4700 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4701 getLoc(), getContext()));
4708 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4709 if (!ParseRes.isSuccess())
4712 return tryParseVectorIndex(
Operands).isFailure();
4716 SMLoc StartLoc = getLoc();
4724 Operands.push_back(AArch64Operand::CreateReg(
4725 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4732 return Error(getLoc(),
"index must be absent or #0");
4735 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4736 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4737 return Error(getLoc(),
"index must be absent or #0");
4739 Operands.push_back(AArch64Operand::CreateReg(
4740 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4745 SMLoc StartLoc = getLoc();
4749 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4754 Operands.push_back(AArch64Operand::CreateReg(
4755 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4761 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4763 if (getParser().parseExpression(ImmVal))
4767 return TokError(
"immediate value expected for vector index");
4768 Operands.push_back(AArch64Operand::CreateImm(
4770 getLoc(), getContext()));
4772 if (parseOptionalMulOperand(
Operands))
4777 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4782template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4784 SMLoc StartLoc = getLoc();
4793 Operands.push_back(AArch64Operand::CreateReg(
4794 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4803 Res = tryParseOptionalShiftExtend(ExtOpnd);
4807 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4808 Operands.push_back(AArch64Operand::CreateReg(
4809 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4810 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4811 Ext->hasShiftExtendAmount()));
4825 if (!getTok().getString().equals_insensitive(
"mul") ||
4826 !(NextIsVL || NextIsHash))
4830 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4835 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4847 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4848 Operands.push_back(AArch64Operand::CreateImm(
4855 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4861 auto Tok = Parser.
getTok();
4866 .
Case(
"vgx2",
"vgx2")
4867 .
Case(
"vgx4",
"vgx4")
4879 auto Tok = getTok();
4889 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4898 bool invertCondCode) {
4902 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4916 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4921 getLexer().UnLex(SavedTok);
4925 switch (getLexer().getKind()) {
4929 if (parseSymbolicImmVal(Expr))
4930 return Error(S,
"invalid operand");
4933 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4934 return parseOptionalShiftExtend(getTok());
4938 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4943 return parseOperand(
Operands,
false,
false);
4946 if (!parseNeonVectorList(
Operands))
4950 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4955 return parseOperand(
Operands,
false,
false);
4960 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4962 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4967 return parseCondCode(
Operands, invertCondCode);
4981 Res = tryParseOptionalShiftExtend(
Operands);
4984 getLexer().UnLex(SavedTok);
4991 if (!parseOptionalMulOperand(
Operands))
4996 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
4998 return parseKeywordOperand(
Operands);
5004 if (getParser().parseExpression(IdVal))
5007 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
5019 bool isNegative =
false;
5035 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5036 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5037 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5038 return TokError(
"unexpected floating point literal");
5039 else if (IntVal != 0 || isNegative)
5040 return TokError(
"expected floating-point constant #0.0");
5043 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
5044 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
5049 if (parseSymbolicImmVal(ImmVal))
5053 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
5056 return parseOptionalShiftExtend(Tok);
5059 SMLoc Loc = getLoc();
5060 if (Mnemonic !=
"ldr")
5061 return TokError(
"unexpected token in operand");
5063 const MCExpr *SubExprVal;
5064 if (getParser().parseExpression(SubExprVal))
5068 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5069 return Error(Loc,
"Only valid when first operand is register");
5072 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5078 if (isa<MCConstantExpr>(SubExprVal)) {
5079 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
5080 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5085 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5086 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5087 Operands.push_back(AArch64Operand::CreateImm(
5091 ShiftAmt,
true, S, E, Ctx));
5097 return Error(Loc,
"Immediate too large for register");
5101 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5102 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
5108bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5109 const MCExpr *Expr =
nullptr;
5111 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5114 if (check(!
Value, L,
"expected constant expression"))
5116 Out =
Value->getValue();
5120bool AArch64AsmParser::parseComma() {
5128bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5132 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5137 unsigned RangeEnd =
Last;
5138 if (
Base == AArch64::X0) {
5139 if (
Last == AArch64::FP) {
5140 RangeEnd = AArch64::X28;
5141 if (Reg == AArch64::FP) {
5146 if (
Last == AArch64::LR) {
5147 RangeEnd = AArch64::X28;
5148 if (Reg == AArch64::FP) {
5151 }
else if (Reg == AArch64::LR) {
5158 if (check(Reg < First || Reg > RangeEnd, Start,
5159 Twine(
"expected register in range ") +
5169 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5170 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5172 if (AOp1.isVectorList() && AOp2.isVectorList())
5173 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5174 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5175 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5177 if (!AOp1.isReg() || !AOp2.isReg())
5180 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5181 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5184 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5185 "Testing equality of non-scalar registers not supported");
5188 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5190 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5192 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5194 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5205 .
Case(
"beq",
"b.eq")
5206 .
Case(
"bne",
"b.ne")
5207 .
Case(
"bhs",
"b.hs")
5208 .
Case(
"bcs",
"b.cs")
5209 .
Case(
"blo",
"b.lo")
5210 .
Case(
"bcc",
"b.cc")
5211 .
Case(
"bmi",
"b.mi")
5212 .
Case(
"bpl",
"b.pl")
5213 .
Case(
"bvs",
"b.vs")
5214 .
Case(
"bvc",
"b.vc")
5215 .
Case(
"bhi",
"b.hi")
5216 .
Case(
"bls",
"b.ls")
5217 .
Case(
"bge",
"b.ge")
5218 .
Case(
"blt",
"b.lt")
5219 .
Case(
"bgt",
"b.gt")
5220 .
Case(
"ble",
"b.le")
5221 .
Case(
"bal",
"b.al")
5222 .
Case(
"bnv",
"b.nv")
5227 getTok().getIdentifier().lower() ==
".req") {
5228 parseDirectiveReq(
Name, NameLoc);
5235 size_t Start = 0, Next =
Name.find(
'.');
5240 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5241 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5242 return parseSysAlias(Head, NameLoc,
Operands);
5245 if (Head ==
"tlbip")
5246 return parseSyspAlias(Head, NameLoc,
Operands);
5248 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5254 Next =
Name.find(
'.', Start + 1);
5255 Head =
Name.slice(Start + 1, Next);
5259 std::string Suggestion;
5262 std::string Msg =
"invalid condition code";
5263 if (!Suggestion.empty())
5264 Msg +=
", did you mean " + Suggestion +
"?";
5265 return Error(SuffixLoc, Msg);
5267 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5270 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5276 Next =
Name.find(
'.', Start + 1);
5277 Head =
Name.slice(Start, Next);
5280 Operands.push_back(AArch64Operand::CreateToken(
5281 Head, SuffixLoc, getContext(),
true));
5286 bool condCodeFourthOperand =
5287 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5288 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5289 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5297 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5298 bool condCodeThirdOperand =
5299 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5307 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5308 (
N == 3 && condCodeThirdOperand) ||
5309 (
N == 2 && condCodeSecondOperand),
5310 condCodeSecondOperand || condCodeThirdOperand)) {
5330 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5333 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5336 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5349 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5350 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5351 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5352 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5353 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5354 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5355 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5361bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5370 PrefixInfo
Prefix = NextPrefix;
5371 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5383 return Error(IDLoc,
"instruction is unpredictable when following a"
5384 " movprfx, suggest replacing movprfx with mov");
5388 return Error(Loc[0],
"instruction is unpredictable when following a"
5389 " movprfx writing to a different destination");
5396 return Error(Loc[0],
"instruction is unpredictable when following a"
5397 " movprfx and destination also used as non-destructive"
5401 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5402 if (
Prefix.isPredicated()) {
5416 return Error(IDLoc,
"instruction is unpredictable when following a"
5417 " predicated movprfx, suggest using unpredicated movprfx");
5421 return Error(IDLoc,
"instruction is unpredictable when following a"
5422 " predicated movprfx using a different general predicate");
5426 return Error(IDLoc,
"instruction is unpredictable when following a"
5427 " predicated movprfx with a different element size");
5433 if (IsWindowsArm64EC) {
5439 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5440 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5441 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5442 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5443 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5444 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5445 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5446 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5447 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5448 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5450 " is disallowed on ARM64EC.");
5460 case AArch64::LDPSWpre:
5461 case AArch64::LDPWpost:
5462 case AArch64::LDPWpre:
5463 case AArch64::LDPXpost:
5464 case AArch64::LDPXpre: {
5469 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5470 "is also a destination");
5472 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5473 "is also a destination");
5476 case AArch64::LDR_ZA:
5477 case AArch64::STR_ZA: {
5480 return Error(Loc[1],
5481 "unpredictable instruction, immediate and offset mismatch.");
5484 case AArch64::LDPDi:
5485 case AArch64::LDPQi:
5486 case AArch64::LDPSi:
5487 case AArch64::LDPSWi:
5488 case AArch64::LDPWi:
5489 case AArch64::LDPXi: {
5493 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5496 case AArch64::LDPDpost:
5497 case AArch64::LDPDpre:
5498 case AArch64::LDPQpost:
5499 case AArch64::LDPQpre:
5500 case AArch64::LDPSpost:
5501 case AArch64::LDPSpre:
5502 case AArch64::LDPSWpost: {
5506 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5509 case AArch64::STPDpost:
5510 case AArch64::STPDpre:
5511 case AArch64::STPQpost:
5512 case AArch64::STPQpre:
5513 case AArch64::STPSpost:
5514 case AArch64::STPSpre:
5515 case AArch64::STPWpost:
5516 case AArch64::STPWpre:
5517 case AArch64::STPXpost:
5518 case AArch64::STPXpre: {
5523 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5524 "is also a source");
5526 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5527 "is also a source");
5530 case AArch64::LDRBBpre:
5531 case AArch64::LDRBpre:
5532 case AArch64::LDRHHpre:
5533 case AArch64::LDRHpre:
5534 case AArch64::LDRSBWpre:
5535 case AArch64::LDRSBXpre:
5536 case AArch64::LDRSHWpre:
5537 case AArch64::LDRSHXpre:
5538 case AArch64::LDRSWpre:
5539 case AArch64::LDRWpre:
5540 case AArch64::LDRXpre:
5541 case AArch64::LDRBBpost:
5542 case AArch64::LDRBpost:
5543 case AArch64::LDRHHpost:
5544 case AArch64::LDRHpost:
5545 case AArch64::LDRSBWpost:
5546 case AArch64::LDRSBXpost:
5547 case AArch64::LDRSHWpost:
5548 case AArch64::LDRSHXpost:
5549 case AArch64::LDRSWpost:
5550 case AArch64::LDRWpost:
5551 case AArch64::LDRXpost: {
5555 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5556 "is also a source");
5559 case AArch64::STRBBpost:
5560 case AArch64::STRBpost:
5561 case AArch64::STRHHpost:
5562 case AArch64::STRHpost:
5563 case AArch64::STRWpost:
5564 case AArch64::STRXpost:
5565 case AArch64::STRBBpre:
5566 case AArch64::STRBpre:
5567 case AArch64::STRHHpre:
5568 case AArch64::STRHpre:
5569 case AArch64::STRWpre:
5570 case AArch64::STRXpre: {
5574 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5575 "is also a source");
5578 case AArch64::STXRB:
5579 case AArch64::STXRH:
5580 case AArch64::STXRW:
5581 case AArch64::STXRX:
5582 case AArch64::STLXRB:
5583 case AArch64::STLXRH:
5584 case AArch64::STLXRW:
5585 case AArch64::STLXRX: {
5591 return Error(Loc[0],
5592 "unpredictable STXR instruction, status is also a source");
5595 case AArch64::STXPW:
5596 case AArch64::STXPX:
5597 case AArch64::STLXPW:
5598 case AArch64::STLXPX: {
5605 return Error(Loc[0],
5606 "unpredictable STXP instruction, status is also a source");
5609 case AArch64::LDRABwriteback:
5610 case AArch64::LDRAAwriteback: {
5614 return Error(Loc[0],
5615 "unpredictable LDRA instruction, writeback base"
5616 " is also a destination");
5623 case AArch64::CPYFP:
5624 case AArch64::CPYFPWN:
5625 case AArch64::CPYFPRN:
5626 case AArch64::CPYFPN:
5627 case AArch64::CPYFPWT:
5628 case AArch64::CPYFPWTWN:
5629 case AArch64::CPYFPWTRN:
5630 case AArch64::CPYFPWTN:
5631 case AArch64::CPYFPRT:
5632 case AArch64::CPYFPRTWN:
5633 case AArch64::CPYFPRTRN:
5634 case AArch64::CPYFPRTN:
5635 case AArch64::CPYFPT:
5636 case AArch64::CPYFPTWN:
5637 case AArch64::CPYFPTRN:
5638 case AArch64::CPYFPTN:
5639 case AArch64::CPYFM:
5640 case AArch64::CPYFMWN:
5641 case AArch64::CPYFMRN:
5642 case AArch64::CPYFMN:
5643 case AArch64::CPYFMWT:
5644 case AArch64::CPYFMWTWN:
5645 case AArch64::CPYFMWTRN:
5646 case AArch64::CPYFMWTN:
5647 case AArch64::CPYFMRT:
5648 case AArch64::CPYFMRTWN:
5649 case AArch64::CPYFMRTRN:
5650 case AArch64::CPYFMRTN:
5651 case AArch64::CPYFMT:
5652 case AArch64::CPYFMTWN:
5653 case AArch64::CPYFMTRN:
5654 case AArch64::CPYFMTN:
5655 case AArch64::CPYFE:
5656 case AArch64::CPYFEWN:
5657 case AArch64::CPYFERN:
5658 case AArch64::CPYFEN:
5659 case AArch64::CPYFEWT:
5660 case AArch64::CPYFEWTWN:
5661 case AArch64::CPYFEWTRN:
5662 case AArch64::CPYFEWTN:
5663 case AArch64::CPYFERT:
5664 case AArch64::CPYFERTWN:
5665 case AArch64::CPYFERTRN:
5666 case AArch64::CPYFERTN:
5667 case AArch64::CPYFET:
5668 case AArch64::CPYFETWN:
5669 case AArch64::CPYFETRN:
5670 case AArch64::CPYFETN:
5672 case AArch64::CPYPWN:
5673 case AArch64::CPYPRN:
5674 case AArch64::CPYPN:
5675 case AArch64::CPYPWT:
5676 case AArch64::CPYPWTWN:
5677 case AArch64::CPYPWTRN:
5678 case AArch64::CPYPWTN:
5679 case AArch64::CPYPRT:
5680 case AArch64::CPYPRTWN:
5681 case AArch64::CPYPRTRN:
5682 case AArch64::CPYPRTN:
5683 case AArch64::CPYPT:
5684 case AArch64::CPYPTWN:
5685 case AArch64::CPYPTRN:
5686 case AArch64::CPYPTN:
5688 case AArch64::CPYMWN:
5689 case AArch64::CPYMRN:
5690 case AArch64::CPYMN:
5691 case AArch64::CPYMWT:
5692 case AArch64::CPYMWTWN:
5693 case AArch64::CPYMWTRN:
5694 case AArch64::CPYMWTN:
5695 case AArch64::CPYMRT:
5696 case AArch64::CPYMRTWN:
5697 case AArch64::CPYMRTRN:
5698 case AArch64::CPYMRTN:
5699 case AArch64::CPYMT:
5700 case AArch64::CPYMTWN:
5701 case AArch64::CPYMTRN:
5702 case AArch64::CPYMTN:
5704 case AArch64::CPYEWN:
5705 case AArch64::CPYERN:
5706 case AArch64::CPYEN:
5707 case AArch64::CPYEWT:
5708 case AArch64::CPYEWTWN:
5709 case AArch64::CPYEWTRN:
5710 case AArch64::CPYEWTN:
5711 case AArch64::CPYERT:
5712 case AArch64::CPYERTWN:
5713 case AArch64::CPYERTRN:
5714 case AArch64::CPYERTN:
5715 case AArch64::CPYET:
5716 case AArch64::CPYETWN:
5717 case AArch64::CPYETRN:
5718 case AArch64::CPYETN: {
5726 return Error(Loc[0],
5727 "invalid CPY instruction, Xd_wb and Xd do not match");
5729 return Error(Loc[0],
5730 "invalid CPY instruction, Xs_wb and Xs do not match");
5732 return Error(Loc[0],
5733 "invalid CPY instruction, Xn_wb and Xn do not match");
5735 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5736 " registers are the same");
5738 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5739 " registers are the same");
5741 return Error(Loc[0],
"invalid CPY instruction, source and size"
5742 " registers are the same");
5746 case AArch64::SETPT:
5747 case AArch64::SETPN:
5748 case AArch64::SETPTN:
5750 case AArch64::SETMT:
5751 case AArch64::SETMN:
5752 case AArch64::SETMTN:
5754 case AArch64::SETET:
5755 case AArch64::SETEN:
5756 case AArch64::SETETN:
5757 case AArch64::SETGP:
5758 case AArch64::SETGPT:
5759 case AArch64::SETGPN:
5760 case AArch64::SETGPTN:
5761 case AArch64::SETGM:
5762 case AArch64::SETGMT:
5763 case AArch64::SETGMN:
5764 case AArch64::SETGMTN:
5765 case AArch64::MOPSSETGE:
5766 case AArch64::MOPSSETGET:
5767 case AArch64::MOPSSETGEN:
5768 case AArch64::MOPSSETGETN: {
5775 return Error(Loc[0],
5776 "invalid SET instruction, Xd_wb and Xd do not match");
5778 return Error(Loc[0],
5779 "invalid SET instruction, Xn_wb and Xn do not match");
5781 return Error(Loc[0],
"invalid SET instruction, destination and size"
5782 " registers are the same");
5784 return Error(Loc[0],
"invalid SET instruction, destination and source"
5785 " registers are the same");
5787 return Error(Loc[0],
"invalid SET instruction, source and size"
5788 " registers are the same");
5797 case AArch64::ADDSWri:
5798 case AArch64::ADDSXri:
5799 case AArch64::ADDWri:
5800 case AArch64::ADDXri:
5801 case AArch64::SUBSWri:
5802 case AArch64::SUBSXri:
5803 case AArch64::SUBWri:
5804 case AArch64::SUBXri: {
5812 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5841 return Error(Loc.
back(),
"invalid immediate expression");
5854 unsigned VariantID = 0);
5856bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5860 case Match_InvalidTiedOperand: {
5862 if (
Op.isVectorList())
5863 return Error(Loc,
"operand must match destination register list");
5865 assert(
Op.isReg() &&
"Unexpected operand type");
5866 switch (
Op.getRegEqualityTy()) {
5867 case RegConstraintEqualityTy::EqualsSubReg:
5868 return Error(Loc,
"operand must be 64-bit form of destination register");
5869 case RegConstraintEqualityTy::EqualsSuperReg:
5870 return Error(Loc,
"operand must be 32-bit form of destination register");
5871 case RegConstraintEqualityTy::EqualsReg:
5872 return Error(Loc,
"operand must match destination register");
5876 case Match_MissingFeature:
5878 "instruction requires a CPU feature not currently enabled");
5879 case Match_InvalidOperand:
5880 return Error(Loc,
"invalid operand for instruction");
5881 case Match_InvalidSuffix:
5882 return Error(Loc,
"invalid type suffix for instruction");
5883 case Match_InvalidCondCode:
5884 return Error(Loc,
"expected AArch64 condition code");
5885 case Match_AddSubRegExtendSmall:
5887 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5888 case Match_AddSubRegExtendLarge:
5890 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5891 case Match_AddSubSecondSource:
5893 "expected compatible register, symbol or integer in range [0, 4095]");
5894 case Match_LogicalSecondSource:
5895 return Error(Loc,
"expected compatible register or logical immediate");
5896 case Match_InvalidMovImm32Shift:
5897 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5898 case Match_InvalidMovImm64Shift:
5899 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5900 case Match_AddSubRegShift32:
5902 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5903 case Match_AddSubRegShift64:
5905 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5906 case Match_InvalidFPImm:
5908 "expected compatible register or floating-point constant");
5909 case Match_InvalidMemoryIndexedSImm6:
5910 return Error(Loc,
"index must be an integer in range [-32, 31].");
5911 case Match_InvalidMemoryIndexedSImm5:
5912 return Error(Loc,
"index must be an integer in range [-16, 15].");
5913 case Match_InvalidMemoryIndexed1SImm4:
5914 return Error(Loc,
"index must be an integer in range [-8, 7].");
5915 case Match_InvalidMemoryIndexed2SImm4:
5916 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5917 case Match_InvalidMemoryIndexed3SImm4:
5918 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5919 case Match_InvalidMemoryIndexed4SImm4:
5920 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5921 case Match_InvalidMemoryIndexed16SImm4:
5922 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5923 case Match_InvalidMemoryIndexed32SImm4:
5924 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5925 case Match_InvalidMemoryIndexed1SImm6:
5926 return Error(Loc,
"index must be an integer in range [-32, 31].");
5927 case Match_InvalidMemoryIndexedSImm8:
5928 return Error(Loc,
"index must be an integer in range [-128, 127].");
5929 case Match_InvalidMemoryIndexedSImm9:
5930 return Error(Loc,
"index must be an integer in range [-256, 255].");
5931 case Match_InvalidMemoryIndexed16SImm9:
5932 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5933 case Match_InvalidMemoryIndexed8SImm10:
5934 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5935 case Match_InvalidMemoryIndexed4SImm7:
5936 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5937 case Match_InvalidMemoryIndexed8SImm7:
5938 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5939 case Match_InvalidMemoryIndexed16SImm7:
5940 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5941 case Match_InvalidMemoryIndexed8UImm5:
5942 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5943 case Match_InvalidMemoryIndexed8UImm3:
5944 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5945 case Match_InvalidMemoryIndexed4UImm5:
5946 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5947 case Match_InvalidMemoryIndexed2UImm5:
5948 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5949 case Match_InvalidMemoryIndexed8UImm6:
5950 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5951 case Match_InvalidMemoryIndexed16UImm6:
5952 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5953 case Match_InvalidMemoryIndexed4UImm6:
5954 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5955 case Match_InvalidMemoryIndexed2UImm6:
5956 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5957 case Match_InvalidMemoryIndexed1UImm6:
5958 return Error(Loc,
"index must be in range [0, 63].");
5959 case Match_InvalidMemoryWExtend8:
5961 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5962 case Match_InvalidMemoryWExtend16:
5964 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5965 case Match_InvalidMemoryWExtend32:
5967 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5968 case Match_InvalidMemoryWExtend64:
5970 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5971 case Match_InvalidMemoryWExtend128:
5973 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5974 case Match_InvalidMemoryXExtend8:
5976 "expected 'lsl' or 'sxtx' with optional shift of #0");
5977 case Match_InvalidMemoryXExtend16:
5979 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5980 case Match_InvalidMemoryXExtend32:
5982 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5983 case Match_InvalidMemoryXExtend64:
5985 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5986 case Match_InvalidMemoryXExtend128:
5988 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5989 case Match_InvalidMemoryIndexed1:
5990 return Error(Loc,
"index must be an integer in range [0, 4095].");
5991 case Match_InvalidMemoryIndexed2:
5992 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
5993 case Match_InvalidMemoryIndexed4:
5994 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
5995 case Match_InvalidMemoryIndexed8:
5996 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
5997 case Match_InvalidMemoryIndexed16:
5998 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
5999 case Match_InvalidImm0_0:
6000 return Error(Loc,
"immediate must be 0.");
6001 case Match_InvalidImm0_1:
6002 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6003 case Match_InvalidImm0_3:
6004 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6005 case Match_InvalidImm0_7:
6006 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6007 case Match_InvalidImm0_15:
6008 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6009 case Match_InvalidImm0_31:
6010 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6011 case Match_InvalidImm0_63:
6012 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6013 case Match_InvalidImm0_127:
6014 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6015 case Match_InvalidImm0_255:
6016 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6017 case Match_InvalidImm0_65535:
6018 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6019 case Match_InvalidImm1_8:
6020 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6021 case Match_InvalidImm1_16:
6022 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6023 case Match_InvalidImm1_32:
6024 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6025 case Match_InvalidImm1_64:
6026 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6027 case Match_InvalidImmM1_62:
6028 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6029 case Match_InvalidMemoryIndexedRange2UImm0:
6030 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6031 case Match_InvalidMemoryIndexedRange2UImm1:
6032 return Error(Loc,
"vector select offset must be an immediate range of the "
6033 "form <immf>:<imml>, where the first "
6034 "immediate is a multiple of 2 in the range [0, 2], and "
6035 "the second immediate is immf + 1.");
6036 case Match_InvalidMemoryIndexedRange2UImm2:
6037 case Match_InvalidMemoryIndexedRange2UImm3:
6040 "vector select offset must be an immediate range of the form "
6042 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6044 "depending on the instruction, and the second immediate is immf + 1.");
6045 case Match_InvalidMemoryIndexedRange4UImm0:
6046 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6047 case Match_InvalidMemoryIndexedRange4UImm1:
6048 case Match_InvalidMemoryIndexedRange4UImm2:
6051 "vector select offset must be an immediate range of the form "
6053 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6055 "depending on the instruction, and the second immediate is immf + 3.");
6056 case Match_InvalidSVEAddSubImm8:
6057 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6058 " with a shift amount of 0");
6059 case Match_InvalidSVEAddSubImm16:
6060 case Match_InvalidSVEAddSubImm32:
6061 case Match_InvalidSVEAddSubImm64:
6062 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6063 "multiple of 256 in range [256, 65280]");
6064 case Match_InvalidSVECpyImm8:
6065 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6066 " with a shift amount of 0");
6067 case Match_InvalidSVECpyImm16:
6068 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6069 "multiple of 256 in range [-32768, 65280]");
6070 case Match_InvalidSVECpyImm32:
6071 case Match_InvalidSVECpyImm64:
6072 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6073 "multiple of 256 in range [-32768, 32512]");
6074 case Match_InvalidIndexRange0_0:
6075 return Error(Loc,
"expected lane specifier '[0]'");
6076 case Match_InvalidIndexRange1_1:
6077 return Error(Loc,
"expected lane specifier '[1]'");
6078 case Match_InvalidIndexRange0_15:
6079 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6080 case Match_InvalidIndexRange0_7:
6081 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6082 case Match_InvalidIndexRange0_3:
6083 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6084 case Match_InvalidIndexRange0_1:
6085 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6086 case Match_InvalidSVEIndexRange0_63:
6087 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6088 case Match_InvalidSVEIndexRange0_31:
6089 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6090 case Match_InvalidSVEIndexRange0_15:
6091 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6092 case Match_InvalidSVEIndexRange0_7:
6093 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6094 case Match_InvalidSVEIndexRange0_3:
6095 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6096 case Match_InvalidLabel:
6097 return Error(Loc,
"expected label or encodable integer pc offset");
6099 return Error(Loc,
"expected readable system register");
6101 case Match_InvalidSVCR:
6102 return Error(Loc,
"expected writable system register or pstate");
6103 case Match_InvalidComplexRotationEven:
6104 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6105 case Match_InvalidComplexRotationOdd:
6106 return Error(Loc,
"complex rotation must be 90 or 270.");
6107 case Match_MnemonicFail: {
6109 ((AArch64Operand &)*
Operands[0]).getToken(),
6110 ComputeAvailableFeatures(STI->getFeatureBits()));
6111 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6113 case Match_InvalidGPR64shifted8:
6114 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6115 case Match_InvalidGPR64shifted16:
6116 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6117 case Match_InvalidGPR64shifted32:
6118 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6119 case Match_InvalidGPR64shifted64:
6120 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6121 case Match_InvalidGPR64shifted128:
6123 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6124 case Match_InvalidGPR64NoXZRshifted8:
6125 return Error(Loc,
"register must be x0..x30 without shift");
6126 case Match_InvalidGPR64NoXZRshifted16:
6127 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6128 case Match_InvalidGPR64NoXZRshifted32:
6129 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6130 case Match_InvalidGPR64NoXZRshifted64:
6131 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6132 case Match_InvalidGPR64NoXZRshifted128:
6133 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6134 case Match_InvalidZPR32UXTW8:
6135 case Match_InvalidZPR32SXTW8:
6136 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6137 case Match_InvalidZPR32UXTW16:
6138 case Match_InvalidZPR32SXTW16:
6139 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6140 case Match_InvalidZPR32UXTW32:
6141 case Match_InvalidZPR32SXTW32:
6142 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6143 case Match_InvalidZPR32UXTW64:
6144 case Match_InvalidZPR32SXTW64:
6145 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6146 case Match_InvalidZPR64UXTW8:
6147 case Match_InvalidZPR64SXTW8:
6148 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6149 case Match_InvalidZPR64UXTW16:
6150 case Match_InvalidZPR64SXTW16:
6151 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6152 case Match_InvalidZPR64UXTW32:
6153 case Match_InvalidZPR64SXTW32:
6154 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6155 case Match_InvalidZPR64UXTW64:
6156 case Match_InvalidZPR64SXTW64:
6157 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6158 case Match_InvalidZPR32LSL8:
6159 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6160 case Match_InvalidZPR32LSL16:
6161 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6162 case Match_InvalidZPR32LSL32:
6163 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6164 case Match_InvalidZPR32LSL64:
6165 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6166 case Match_InvalidZPR64LSL8:
6167 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6168 case Match_InvalidZPR64LSL16:
6169 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6170 case Match_InvalidZPR64LSL32:
6171 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6172 case Match_InvalidZPR64LSL64:
6173 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6174 case Match_InvalidZPR0:
6175 return Error(Loc,
"expected register without element width suffix");
6176 case Match_InvalidZPR8:
6177 case Match_InvalidZPR16:
6178 case Match_InvalidZPR32:
6179 case Match_InvalidZPR64:
6180 case Match_InvalidZPR128:
6181 return Error(Loc,
"invalid element width");
6182 case Match_InvalidZPR_3b8:
6183 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6184 case Match_InvalidZPR_3b16:
6185 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6186 case Match_InvalidZPR_3b32:
6187 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6188 case Match_InvalidZPR_4b8:
6190 "Invalid restricted vector register, expected z0.b..z15.b");
6191 case Match_InvalidZPR_4b16:
6192 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6193 case Match_InvalidZPR_4b32:
6194 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6195 case Match_InvalidZPR_4b64:
6196 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6197 case Match_InvalidZPRMul2_Lo8:
6198 return Error(Loc,
"Invalid restricted vector register, expected even "
6199 "register in z0.b..z14.b");
6200 case Match_InvalidZPRMul2_Hi8:
6201 return Error(Loc,
"Invalid restricted vector register, expected even "
6202 "register in z16.b..z30.b");
6203 case Match_InvalidZPRMul2_Lo16:
6204 return Error(Loc,
"Invalid restricted vector register, expected even "
6205 "register in z0.h..z14.h");
6206 case Match_InvalidZPRMul2_Hi16:
6207 return Error(Loc,
"Invalid restricted vector register, expected even "
6208 "register in z16.h..z30.h");
6209 case Match_InvalidZPRMul2_Lo32:
6210 return Error(Loc,
"Invalid restricted vector register, expected even "
6211 "register in z0.s..z14.s");
6212 case Match_InvalidZPRMul2_Hi32:
6213 return Error(Loc,
"Invalid restricted vector register, expected even "
6214 "register in z16.s..z30.s");
6215 case Match_InvalidZPRMul2_Lo64:
6216 return Error(Loc,
"Invalid restricted vector register, expected even "
6217 "register in z0.d..z14.d");
6218 case Match_InvalidZPRMul2_Hi64:
6219 return Error(Loc,
"Invalid restricted vector register, expected even "
6220 "register in z16.d..z30.d");
6221 case Match_InvalidZPR_K0:
6222 return Error(Loc,
"invalid restricted vector register, expected register "
6223 "in z20..z23 or z28..z31");
6224 case Match_InvalidSVEPattern:
6225 return Error(Loc,
"invalid predicate pattern");
6226 case Match_InvalidSVEPPRorPNRAnyReg:
6227 case Match_InvalidSVEPPRorPNRBReg:
6228 case Match_InvalidSVEPredicateAnyReg:
6229 case Match_InvalidSVEPredicateBReg:
6230 case Match_InvalidSVEPredicateHReg:
6231 case Match_InvalidSVEPredicateSReg:
6232 case Match_InvalidSVEPredicateDReg:
6233 return Error(Loc,
"invalid predicate register.");
6234 case Match_InvalidSVEPredicate3bAnyReg:
6235 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6236 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6237 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6238 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6239 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6240 return Error(Loc,
"Invalid predicate register, expected PN in range "
6241 "pn8..pn15 with element suffix.");
6242 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6243 return Error(Loc,
"invalid restricted predicate-as-counter register "
6244 "expected pn8..pn15");
6245 case Match_InvalidSVEPNPredicateBReg:
6246 case Match_InvalidSVEPNPredicateHReg:
6247 case Match_InvalidSVEPNPredicateSReg:
6248 case Match_InvalidSVEPNPredicateDReg:
6249 return Error(Loc,
"Invalid predicate register, expected PN in range "
6250 "pn0..pn15 with element suffix.");
6251 case Match_InvalidSVEVecLenSpecifier:
6252 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6253 case Match_InvalidSVEPredicateListMul2x8:
6254 case Match_InvalidSVEPredicateListMul2x16:
6255 case Match_InvalidSVEPredicateListMul2x32:
6256 case Match_InvalidSVEPredicateListMul2x64:
6257 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6258 "predicate registers, where the first vector is a multiple of 2 "
6259 "and with correct element type");
6260 case Match_InvalidSVEExactFPImmOperandHalfOne:
6261 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6262 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6263 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6264 case Match_InvalidSVEExactFPImmOperandZeroOne:
6265 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6266 case Match_InvalidMatrixTileVectorH8:
6267 case Match_InvalidMatrixTileVectorV8:
6268 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6269 case Match_InvalidMatrixTileVectorH16:
6270 case Match_InvalidMatrixTileVectorV16:
6272 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6273 case Match_InvalidMatrixTileVectorH32:
6274 case Match_InvalidMatrixTileVectorV32:
6276 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6277 case Match_InvalidMatrixTileVectorH64:
6278 case Match_InvalidMatrixTileVectorV64:
6280 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6281 case Match_InvalidMatrixTileVectorH128:
6282 case Match_InvalidMatrixTileVectorV128:
6284 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6285 case Match_InvalidMatrixTile16:
6286 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6287 case Match_InvalidMatrixTile32:
6288 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6289 case Match_InvalidMatrixTile64:
6290 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6291 case Match_InvalidMatrix:
6292 return Error(Loc,
"invalid matrix operand, expected za");
6293 case Match_InvalidMatrix8:
6294 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6295 case Match_InvalidMatrix16:
6296 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6297 case Match_InvalidMatrix32:
6298 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6299 case Match_InvalidMatrix64:
6300 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6301 case Match_InvalidMatrixIndexGPR32_12_15:
6302 return Error(Loc,
"operand must be a register in range [w12, w15]");
6303 case Match_InvalidMatrixIndexGPR32_8_11:
6304 return Error(Loc,
"operand must be a register in range [w8, w11]");
6305 case Match_InvalidSVEVectorList2x8Mul2:
6306 case Match_InvalidSVEVectorList2x16Mul2:
6307 case Match_InvalidSVEVectorList2x32Mul2:
6308 case Match_InvalidSVEVectorList2x64Mul2:
6309 case Match_InvalidSVEVectorList2x128Mul2:
6310 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6311 "SVE vectors, where the first vector is a multiple of 2 "
6312 "and with matching element types");
6313 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6314 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6315 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6316 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6317 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6318 "SVE vectors in the range z0-z14, where the first vector "
6319 "is a multiple of 2 "
6320 "and with matching element types");
6321 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6322 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6323 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6324 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6326 "Invalid vector list, expected list with 2 consecutive "
6327 "SVE vectors in the range z16-z30, where the first vector "
6328 "is a multiple of 2 "
6329 "and with matching element types");
6330 case Match_InvalidSVEVectorList4x8Mul4:
6331 case Match_InvalidSVEVectorList4x16Mul4:
6332 case Match_InvalidSVEVectorList4x32Mul4:
6333 case Match_InvalidSVEVectorList4x64Mul4:
6334 case Match_InvalidSVEVectorList4x128Mul4:
6335 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6336 "SVE vectors, where the first vector is a multiple of 4 "
6337 "and with matching element types");
6338 case Match_InvalidLookupTable:
6339 return Error(Loc,
"Invalid lookup table, expected zt0");
6340 case Match_InvalidSVEVectorListStrided2x8:
6341 case Match_InvalidSVEVectorListStrided2x16:
6342 case Match_InvalidSVEVectorListStrided2x32:
6343 case Match_InvalidSVEVectorListStrided2x64:
6346 "Invalid vector list, expected list with each SVE vector in the list "
6347 "8 registers apart, and the first register in the range [z0, z7] or "
6348 "[z16, z23] and with correct element type");
6349 case Match_InvalidSVEVectorListStrided4x8:
6350 case Match_InvalidSVEVectorListStrided4x16:
6351 case Match_InvalidSVEVectorListStrided4x32:
6352 case Match_InvalidSVEVectorListStrided4x64:
6355 "Invalid vector list, expected list with each SVE vector in the list "
6356 "4 registers apart, and the first register in the range [z0, z3] or "
6357 "[z16, z19] and with correct element type");
6358 case Match_AddSubLSLImm3ShiftLarge:
6360 "expected 'lsl' with optional integer in range [0, 7]");
6368bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6372 bool MatchingInlineAsm) {
6374 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6375 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6378 unsigned NumOperands =
Operands.size();
6380 if (NumOperands == 4 && Tok ==
"lsl") {
6381 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6382 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6383 if (Op2.isScalarReg() && Op3.isImm()) {
6384 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6389 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6391 NewOp3Val = (32 - Op3Val) & 0x1f;
6392 NewOp4Val = 31 - Op3Val;
6394 NewOp3Val = (64 - Op3Val) & 0x3f;
6395 NewOp4Val = 63 - Op3Val;
6402 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6403 Operands.push_back(AArch64Operand::CreateImm(
6404 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6405 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6406 Op3.getEndLoc(), getContext());
6409 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6411 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6412 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6413 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6415 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6416 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6417 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6419 if (LSBCE && WidthCE) {
6424 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6430 if (LSB >= RegWidth)
6431 return Error(LSBOp.getStartLoc(),
6432 "expected integer in range [0, 31]");
6433 if (Width < 1 || Width > RegWidth)
6434 return Error(WidthOp.getStartLoc(),
6435 "expected integer in range [1, 32]");
6439 ImmR = (32 - LSB) & 0x1f;
6441 ImmR = (64 - LSB) & 0x3f;
6445 if (ImmR != 0 && ImmS >= ImmR)
6446 return Error(WidthOp.getStartLoc(),
6447 "requested insert overflows register");
6452 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6453 Operands[2] = AArch64Operand::CreateReg(
6454 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6456 Operands[3] = AArch64Operand::CreateImm(
6457 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6459 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6460 WidthOp.getEndLoc(), getContext()));
6463 }
else if (NumOperands == 5) {
6466 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6467 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6468 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6469 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6471 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6472 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6473 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6475 if (Op3CE && Op4CE) {
6480 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6486 if (Op3Val >= RegWidth)
6487 return Error(Op3.getStartLoc(),
6488 "expected integer in range [0, 31]");
6489 if (Op4Val < 1 || Op4Val > RegWidth)
6490 return Error(Op4.getStartLoc(),
6491 "expected integer in range [1, 32]");
6495 NewOp3Val = (32 - Op3Val) & 0x1f;
6497 NewOp3Val = (64 - Op3Val) & 0x3f;
6501 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6502 return Error(Op4.getStartLoc(),
6503 "requested insert overflows register");
6509 Operands[3] = AArch64Operand::CreateImm(
6510 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6511 Operands[4] = AArch64Operand::CreateImm(
6512 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6514 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6516 else if (Tok ==
"sbfiz")
6517 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6519 else if (Tok ==
"ubfiz")
6520 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6529 }
else if (NumOperands == 5 &&
6530 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6531 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6532 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6533 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6535 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6536 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6537 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6539 if (Op3CE && Op4CE) {
6544 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6550 if (Op3Val >= RegWidth)
6551 return Error(Op3.getStartLoc(),
6552 "expected integer in range [0, 31]");
6553 if (Op4Val < 1 || Op4Val > RegWidth)
6554 return Error(Op4.getStartLoc(),
6555 "expected integer in range [1, 32]");
6557 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6559 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6560 return Error(Op4.getStartLoc(),
6561 "requested extract overflows register");
6565 Operands[4] = AArch64Operand::CreateImm(
6566 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6568 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6570 else if (Tok ==
"sbfx")
6571 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6573 else if (Tok ==
"ubfx")
6574 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6587 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6588 NumOperands == 4 && Tok ==
"movi") {
6589 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6590 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6591 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6592 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6593 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6594 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6595 if (Suffix.
lower() ==
".2d" &&
6596 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6597 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6598 " correctly on this CPU, converting to equivalent movi.16b");
6600 unsigned Idx = Op1.isToken() ? 1 : 2;
6602 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6610 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6613 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6614 if (
Op.isScalarReg()) {
6616 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6617 Op.getStartLoc(),
Op.getEndLoc(),
6622 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6623 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6624 if (
Op.isScalarReg() &&
6625 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6629 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6630 if (
Op.isScalarReg()) {
6632 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6634 Op.getEndLoc(), getContext());
6639 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6640 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6641 if (
Op.isScalarReg() &&
6642 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6646 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6647 if (
Op.isScalarReg()) {
6649 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6651 Op.getEndLoc(), getContext());
6660 unsigned MatchResult =
6662 MatchingInlineAsm, 1);
6666 if (MatchResult != Match_Success) {
6669 auto ShortFormNEONErrorInfo =
ErrorInfo;
6670 auto ShortFormNEONMatchResult = MatchResult;
6671 auto ShortFormNEONMissingFeatures = MissingFeatures;
6675 MatchingInlineAsm, 0);
6680 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6682 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6683 MatchResult = ShortFormNEONMatchResult;
6685 MissingFeatures = ShortFormNEONMissingFeatures;
6689 switch (MatchResult) {
6690 case Match_Success: {
6694 for (
unsigned i = 1; i < NumOperands; ++i)
6696 if (validateInstruction(Inst, IDLoc, OperandLocs))
6703 case Match_MissingFeature: {
6704 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6707 std::string Msg =
"instruction requires:";
6708 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6709 if (MissingFeatures[i]) {
6714 return Error(IDLoc, Msg);
6716 case Match_MnemonicFail:
6718 case Match_InvalidOperand: {
6719 SMLoc ErrorLoc = IDLoc;
6723 return Error(IDLoc,
"too few operands for instruction",
6724 SMRange(IDLoc, getTok().getLoc()));
6727 if (ErrorLoc ==
SMLoc())
6734 MatchResult = Match_InvalidSuffix;
6738 case Match_InvalidTiedOperand:
6739 case Match_InvalidMemoryIndexed1:
6740 case Match_InvalidMemoryIndexed2:
6741 case Match_InvalidMemoryIndexed4:
6742 case Match_InvalidMemoryIndexed8:
6743 case Match_InvalidMemoryIndexed16:
6744 case Match_InvalidCondCode:
6745 case Match_AddSubLSLImm3ShiftLarge:
6746 case Match_AddSubRegExtendSmall:
6747 case Match_AddSubRegExtendLarge:
6748 case Match_AddSubSecondSource:
6749 case Match_LogicalSecondSource:
6750 case Match_AddSubRegShift32:
6751 case Match_AddSubRegShift64:
6752 case Match_InvalidMovImm32Shift:
6753 case Match_InvalidMovImm64Shift:
6754 case Match_InvalidFPImm:
6755 case Match_InvalidMemoryWExtend8:
6756 case Match_InvalidMemoryWExtend16:
6757 case Match_InvalidMemoryWExtend32:
6758 case Match_InvalidMemoryWExtend64:
6759 case Match_InvalidMemoryWExtend128:
6760 case Match_InvalidMemoryXExtend8:
6761 case Match_InvalidMemoryXExtend16:
6762 case Match_InvalidMemoryXExtend32:
6763 case Match_InvalidMemoryXExtend64:
6764 case Match_InvalidMemoryXExtend128:
6765 case Match_InvalidMemoryIndexed1SImm4:
6766 case Match_InvalidMemoryIndexed2SImm4:
6767 case Match_InvalidMemoryIndexed3SImm4:
6768 case Match_InvalidMemoryIndexed4SImm4:
6769 case Match_InvalidMemoryIndexed1SImm6:
6770 case Match_InvalidMemoryIndexed16SImm4:
6771 case Match_InvalidMemoryIndexed32SImm4:
6772 case Match_InvalidMemoryIndexed4SImm7:
6773 case Match_InvalidMemoryIndexed8SImm7:
6774 case Match_InvalidMemoryIndexed16SImm7:
6775 case Match_InvalidMemoryIndexed8UImm5:
6776 case Match_InvalidMemoryIndexed8UImm3:
6777 case Match_InvalidMemoryIndexed4UImm5:
6778 case Match_InvalidMemoryIndexed2UImm5:
6779 case Match_InvalidMemoryIndexed1UImm6:
6780 case Match_InvalidMemoryIndexed2UImm6:
6781 case Match_InvalidMemoryIndexed4UImm6:
6782 case Match_InvalidMemoryIndexed8UImm6:
6783 case Match_InvalidMemoryIndexed16UImm6:
6784 case Match_InvalidMemoryIndexedSImm6:
6785 case Match_InvalidMemoryIndexedSImm5:
6786 case Match_InvalidMemoryIndexedSImm8:
6787 case Match_InvalidMemoryIndexedSImm9:
6788 case Match_InvalidMemoryIndexed16SImm9:
6789 case Match_InvalidMemoryIndexed8SImm10:
6790 case Match_InvalidImm0_0:
6791 case Match_InvalidImm0_1:
6792 case Match_InvalidImm0_3:
6793 case Match_InvalidImm0_7:
6794 case Match_InvalidImm0_15:
6795 case Match_InvalidImm0_31:
6796 case Match_InvalidImm0_63:
6797 case Match_InvalidImm0_127:
6798 case Match_InvalidImm0_255:
6799 case Match_InvalidImm0_65535:
6800 case Match_InvalidImm1_8:
6801 case Match_InvalidImm1_16:
6802 case Match_InvalidImm1_32:
6803 case Match_InvalidImm1_64:
6804 case Match_InvalidImmM1_62:
6805 case Match_InvalidMemoryIndexedRange2UImm0:
6806 case Match_InvalidMemoryIndexedRange2UImm1:
6807 case Match_InvalidMemoryIndexedRange2UImm2:
6808 case Match_InvalidMemoryIndexedRange2UImm3:
6809 case Match_InvalidMemoryIndexedRange4UImm0:
6810 case Match_InvalidMemoryIndexedRange4UImm1:
6811 case Match_InvalidMemoryIndexedRange4UImm2:
6812 case Match_InvalidSVEAddSubImm8:
6813 case Match_InvalidSVEAddSubImm16:
6814 case Match_InvalidSVEAddSubImm32:
6815 case Match_InvalidSVEAddSubImm64:
6816 case Match_InvalidSVECpyImm8:
6817 case Match_InvalidSVECpyImm16:
6818 case Match_InvalidSVECpyImm32:
6819 case Match_InvalidSVECpyImm64:
6820 case Match_InvalidIndexRange0_0:
6821 case Match_InvalidIndexRange1_1:
6822 case Match_InvalidIndexRange0_15:
6823 case Match_InvalidIndexRange0_7:
6824 case Match_InvalidIndexRange0_3:
6825 case Match_InvalidIndexRange0_1:
6826 case Match_InvalidSVEIndexRange0_63:
6827 case Match_InvalidSVEIndexRange0_31:
6828 case Match_InvalidSVEIndexRange0_15:
6829 case Match_InvalidSVEIndexRange0_7:
6830 case Match_InvalidSVEIndexRange0_3:
6831 case Match_InvalidLabel:
6832 case Match_InvalidComplexRotationEven:
6833 case Match_InvalidComplexRotationOdd:
6834 case Match_InvalidGPR64shifted8:
6835 case Match_InvalidGPR64shifted16:
6836 case Match_InvalidGPR64shifted32:
6837 case Match_InvalidGPR64shifted64:
6838 case Match_InvalidGPR64shifted128:
6839 case Match_InvalidGPR64NoXZRshifted8:
6840 case Match_InvalidGPR64NoXZRshifted16:
6841 case Match_InvalidGPR64NoXZRshifted32:
6842 case Match_InvalidGPR64NoXZRshifted64:
6843 case Match_InvalidGPR64NoXZRshifted128:
6844 case Match_InvalidZPR32UXTW8:
6845 case Match_InvalidZPR32UXTW16:
6846 case Match_InvalidZPR32UXTW32:
6847 case Match_InvalidZPR32UXTW64:
6848 case Match_InvalidZPR32SXTW8:
6849 case Match_InvalidZPR32SXTW16:
6850 case Match_InvalidZPR32SXTW32:
6851 case Match_InvalidZPR32SXTW64:
6852 case Match_InvalidZPR64UXTW8:
6853 case Match_InvalidZPR64SXTW8:
6854 case Match_InvalidZPR64UXTW16:
6855 case Match_InvalidZPR64SXTW16:
6856 case Match_InvalidZPR64UXTW32:
6857 case Match_InvalidZPR64SXTW32:
6858 case Match_InvalidZPR64UXTW64:
6859 case Match_InvalidZPR64SXTW64:
6860 case Match_InvalidZPR32LSL8:
6861 case Match_InvalidZPR32LSL16:
6862 case Match_InvalidZPR32LSL32:
6863 case Match_InvalidZPR32LSL64:
6864 case Match_InvalidZPR64LSL8:
6865 case Match_InvalidZPR64LSL16:
6866 case Match_InvalidZPR64LSL32:
6867 case Match_InvalidZPR64LSL64:
6868 case Match_InvalidZPR0:
6869 case Match_InvalidZPR8:
6870 case Match_InvalidZPR16:
6871 case Match_InvalidZPR32:
6872 case Match_InvalidZPR64:
6873 case Match_InvalidZPR128:
6874 case Match_InvalidZPR_3b8:
6875 case Match_InvalidZPR_3b16:
6876 case Match_InvalidZPR_3b32:
6877 case Match_InvalidZPR_4b8:
6878 case Match_InvalidZPR_4b16:
6879 case Match_InvalidZPR_4b32:
6880 case Match_InvalidZPR_4b64:
6881 case Match_InvalidSVEPPRorPNRAnyReg:
6882 case Match_InvalidSVEPPRorPNRBReg:
6883 case Match_InvalidSVEPredicateAnyReg:
6884 case Match_InvalidSVEPattern:
6885 case Match_InvalidSVEVecLenSpecifier:
6886 case Match_InvalidSVEPredicateBReg:
6887 case Match_InvalidSVEPredicateHReg:
6888 case Match_InvalidSVEPredicateSReg:
6889 case Match_InvalidSVEPredicateDReg:
6890 case Match_InvalidSVEPredicate3bAnyReg:
6891 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6892 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6893 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6894 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6895 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6896 case Match_InvalidSVEPNPredicateBReg:
6897 case Match_InvalidSVEPNPredicateHReg:
6898 case Match_InvalidSVEPNPredicateSReg:
6899 case Match_InvalidSVEPNPredicateDReg:
6900 case Match_InvalidSVEPredicateListMul2x8:
6901 case Match_InvalidSVEPredicateListMul2x16:
6902 case Match_InvalidSVEPredicateListMul2x32:
6903 case Match_InvalidSVEPredicateListMul2x64:
6904 case Match_InvalidSVEExactFPImmOperandHalfOne:
6905 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6906 case Match_InvalidSVEExactFPImmOperandZeroOne:
6907 case Match_InvalidMatrixTile16:
6908 case Match_InvalidMatrixTile32:
6909 case Match_InvalidMatrixTile64:
6910 case Match_InvalidMatrix:
6911 case Match_InvalidMatrix8:
6912 case Match_InvalidMatrix16:
6913 case Match_InvalidMatrix32:
6914 case Match_InvalidMatrix64:
6915 case Match_InvalidMatrixTileVectorH8:
6916 case Match_InvalidMatrixTileVectorH16:
6917 case Match_InvalidMatrixTileVectorH32:
6918 case Match_InvalidMatrixTileVectorH64:
6919 case Match_InvalidMatrixTileVectorH128:
6920 case Match_InvalidMatrixTileVectorV8:
6921 case Match_InvalidMatrixTileVectorV16:
6922 case Match_InvalidMatrixTileVectorV32:
6923 case Match_InvalidMatrixTileVectorV64:
6924 case Match_InvalidMatrixTileVectorV128:
6925 case Match_InvalidSVCR:
6926 case Match_InvalidMatrixIndexGPR32_12_15:
6927 case Match_InvalidMatrixIndexGPR32_8_11:
6928 case Match_InvalidLookupTable:
6929 case Match_InvalidZPRMul2_Lo8:
6930 case Match_InvalidZPRMul2_Hi8:
6931 case Match_InvalidZPRMul2_Lo16:
6932 case Match_InvalidZPRMul2_Hi16:
6933 case Match_InvalidZPRMul2_Lo32:
6934 case Match_InvalidZPRMul2_Hi32:
6935 case Match_InvalidZPRMul2_Lo64:
6936 case Match_InvalidZPRMul2_Hi64:
6937 case Match_InvalidZPR_K0:
6938 case Match_InvalidSVEVectorList2x8Mul2:
6939 case Match_InvalidSVEVectorList2x16Mul2:
6940 case Match_InvalidSVEVectorList2x32Mul2:
6941 case Match_InvalidSVEVectorList2x64Mul2:
6942 case Match_InvalidSVEVectorList2x128Mul2:
6943 case Match_InvalidSVEVectorList4x8Mul4:
6944 case Match_InvalidSVEVectorList4x16Mul4:
6945 case Match_InvalidSVEVectorList4x32Mul4:
6946 case Match_InvalidSVEVectorList4x64Mul4:
6947 case Match_InvalidSVEVectorList4x128Mul4:
6948 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6949 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6950 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6951 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6952 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6953 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6954 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6955 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6956 case Match_InvalidSVEVectorListStrided2x8:
6957 case Match_InvalidSVEVectorListStrided2x16:
6958 case Match_InvalidSVEVectorListStrided2x32:
6959 case Match_InvalidSVEVectorListStrided2x64:
6960 case Match_InvalidSVEVectorListStrided4x8:
6961 case Match_InvalidSVEVectorListStrided4x16:
6962 case Match_InvalidSVEVectorListStrided4x32:
6963 case Match_InvalidSVEVectorListStrided4x64:
6967 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6971 if (ErrorLoc ==
SMLoc())
6981bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6988 if (IDVal ==
".arch")
6989 parseDirectiveArch(Loc);
6990 else if (IDVal ==
".cpu")
6991 parseDirectiveCPU(Loc);
6992 else if (IDVal ==
".tlsdesccall")
6993 parseDirectiveTLSDescCall(Loc);
6994 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6995 parseDirectiveLtorg(Loc);
6996 else if (IDVal ==
".unreq")
6997 parseDirectiveUnreq(Loc);
6998 else if (IDVal ==
".inst")
6999 parseDirectiveInst(Loc);
7000 else if (IDVal ==
".cfi_negate_ra_state")
7001 parseDirectiveCFINegateRAState();
7002 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7003 parseDirectiveCFINegateRAStateWithPC();
7004 else if (IDVal ==
".cfi_b_key_frame")
7005 parseDirectiveCFIBKeyFrame();
7006 else if (IDVal ==
".cfi_mte_tagged_frame")
7007 parseDirectiveCFIMTETaggedFrame();
7008 else if (IDVal ==
".arch_extension")
7009 parseDirectiveArchExtension(Loc);
7010 else if (IDVal ==
".variant_pcs")
7011 parseDirectiveVariantPCS(Loc);
7014 parseDirectiveLOH(IDVal, Loc);
7017 }
else if (IsCOFF) {
7018 if (IDVal ==
".seh_stackalloc")
7019 parseDirectiveSEHAllocStack(Loc);
7020 else if (IDVal ==
".seh_endprologue")
7021 parseDirectiveSEHPrologEnd(Loc);
7022 else if (IDVal ==
".seh_save_r19r20_x")
7023 parseDirectiveSEHSaveR19R20X(Loc);
7024 else if (IDVal ==
".seh_save_fplr")
7025 parseDirectiveSEHSaveFPLR(Loc);
7026 else if (IDVal ==
".seh_save_fplr_x")
7027 parseDirectiveSEHSaveFPLRX(Loc);
7028 else if (IDVal ==
".seh_save_reg")
7029 parseDirectiveSEHSaveReg(Loc);
7030 else if (IDVal ==
".seh_save_reg_x")
7031 parseDirectiveSEHSaveRegX(Loc);
7032 else if (IDVal ==
".seh_save_regp")
7033 parseDirectiveSEHSaveRegP(Loc);
7034 else if (IDVal ==
".seh_save_regp_x")
7035 parseDirectiveSEHSaveRegPX(Loc);
7036 else if (IDVal ==
".seh_save_lrpair")
7037 parseDirectiveSEHSaveLRPair(Loc);
7038 else if (IDVal ==
".seh_save_freg")
7039 parseDirectiveSEHSaveFReg(Loc);
7040 else if (IDVal ==
".seh_save_freg_x")
7041 parseDirectiveSEHSaveFRegX(Loc);
7042 else if (IDVal ==
".seh_save_fregp")
7043 parseDirectiveSEHSaveFRegP(Loc);
7044 else if (IDVal ==
".seh_save_fregp_x")
7045 parseDirectiveSEHSaveFRegPX(Loc);
7046 else if (IDVal ==
".seh_set_fp")
7047 parseDirectiveSEHSetFP(Loc);
7048 else if (IDVal ==
".seh_add_fp")
7049 parseDirectiveSEHAddFP(Loc);
7050 else if (IDVal ==
".seh_nop")
7051 parseDirectiveSEHNop(Loc);
7052 else if (IDVal ==
".seh_save_next")
7053 parseDirectiveSEHSaveNext(Loc);
7054 else if (IDVal ==
".seh_startepilogue")
7055 parseDirectiveSEHEpilogStart(Loc);
7056 else if (IDVal ==
".seh_endepilogue")
7057 parseDirectiveSEHEpilogEnd(Loc);
7058 else if (IDVal ==
".seh_trap_frame")
7059 parseDirectiveSEHTrapFrame(Loc);
7060 else if (IDVal ==
".seh_pushframe")
7061 parseDirectiveSEHMachineFrame(Loc);
7062 else if (IDVal ==
".seh_context")
7063 parseDirectiveSEHContext(Loc);
7064 else if (IDVal ==
".seh_ec_context")
7065 parseDirectiveSEHECContext(Loc);
7066 else if (IDVal ==
".seh_clear_unwound_to_call")
7067 parseDirectiveSEHClearUnwoundToCall(Loc);
7068 else if (IDVal ==
".seh_pac_sign_lr")
7069 parseDirectiveSEHPACSignLR(Loc);
7070 else if (IDVal ==
".seh_save_any_reg")
7071 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7072 else if (IDVal ==
".seh_save_any_reg_p")
7073 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7074 else if (IDVal ==
".seh_save_any_reg_x")
7075 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7076 else if (IDVal ==
".seh_save_any_reg_px")
7077 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7090 if (!NoCrypto && Crypto) {
7093 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7094 ArchInfo == AArch64::ARMV8_3A) {
7098 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7099 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7100 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7101 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7102 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7103 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7109 }
else if (NoCrypto) {
7112 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7113 ArchInfo == AArch64::ARMV8_3A) {
7114 RequestedExtensions.
push_back(
"nosha2");
7117 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7118 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7119 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7120 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7121 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7122 ArchInfo == AArch64::ARMV9_4A) {
7124 RequestedExtensions.
push_back(
"nosha3");
7125 RequestedExtensions.
push_back(
"nosha2");
7137bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
7138 SMLoc CurLoc = getLoc();
7141 std::tie(Arch, ExtensionString) =
7142 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7146 return Error(CurLoc,
"unknown arch name");
7152 std::vector<StringRef> AArch64Features;
7157 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7159 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7162 if (!ExtensionString.
empty())
7163 ExtensionString.
split(RequestedExtensions,
'+');
7168 for (
auto Name : RequestedExtensions) {
7172 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7179 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7188 setAvailableFeatures(Features);
7194bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7195 SMLoc ExtLoc = getLoc();
7197 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7202 bool EnableFeature =
true;
7203 if (
Name.starts_with_insensitive(
"no")) {
7204 EnableFeature =
false;
7213 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7221 setAvailableFeatures(Features);
7227bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7228 SMLoc CurLoc = getLoc();
7231 std::tie(CPU, ExtensionString) =
7232 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7238 if (!ExtensionString.
empty())
7239 ExtensionString.
split(RequestedExtensions,
'+');
7243 Error(CurLoc,
"unknown CPU name");
7252 for (
auto Name : RequestedExtensions) {
7256 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7263 return Error(CurLoc,
"unsupported architectural extension: " +
Name);
7272 setAvailableFeatures(Features);
7278bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7280 return Error(Loc,
"expected expression following '.inst' directive");
7282 auto parseOp = [&]() ->
bool {
7284 const MCExpr *Expr =
nullptr;
7285 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7288 if (check(!
Value, L,
"expected constant expression"))
7290 getTargetStreamer().emitInst(
Value->getValue());
7294 return parseMany(parseOp);
7299bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7301 if (check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7313 getParser().getStreamer().emitInstruction(Inst, getSTI());
7319bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7323 return TokError(
"expected an identifier or a number in directive");
7326 int64_t
Id = getTok().getIntVal();
7328 return TokError(
"invalid numeric identifier in directive");
7337 return TokError(
"invalid identifier in directive");
7345 assert(NbArgs != -1 &&
"Invalid number of arguments");
7348 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7350 if (getParser().parseIdentifier(
Name))
7351 return TokError(
"expected identifier in directive");
7352 Args.push_back(getContext().getOrCreateSymbol(
Name));
7354 if (
Idx + 1 == NbArgs)
7362 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7368bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7371 getTargetStreamer().emitCurrentConstantPool();
7379 SMLoc SRegLoc = getLoc();
7380 RegKind RegisterKind = RegKind::Scalar;
7382 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7386 RegisterKind = RegKind::NeonVector;
7387 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7393 return Error(SRegLoc,
"vector register without type specifier expected");
7398 RegisterKind = RegKind::SVEDataVector;
7400 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7406 return Error(SRegLoc,
7407 "sve vector register without type specifier expected");
7412 RegisterKind = RegKind::SVEPredicateVector;
7413 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7419 return Error(SRegLoc,
7420 "sve predicate register without type specifier expected");
7424 return Error(SRegLoc,
"register name or alias expected");
7430 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7431 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7432 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7439bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7441 return TokError(
"unexpected input in .unreq directive.");
7442 RegisterReqs.
erase(getTok().getIdentifier().lower());
7447bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7450 getStreamer().emitCFINegateRAState();
7454bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7457 getStreamer().emitCFINegateRAStateWithPC();
7463bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7466 getStreamer().emitCFIBKeyFrame();
7472bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7475 getStreamer().emitCFIMTETaggedFrame();
7481bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7483 if (getParser().parseIdentifier(
Name))
7484 return TokError(
"expected symbol name");
7487 getTargetStreamer().emitDirectiveVariantPCS(
7488 getContext().getOrCreateSymbol(
Name));
7494bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7496 if (parseImmExpr(
Size))
7498 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7504bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7505 getTargetStreamer().emitARM64WinCFIPrologEnd();
7511bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7513 if (parseImmExpr(
Offset))
7515 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7521bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7523 if (parseImmExpr(
Offset))
7525 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7531bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7533 if (parseImmExpr(
Offset))
7535 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7541bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7544 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7545 parseComma() || parseImmExpr(
Offset))
7547 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7553bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7556 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7557 parseComma() || parseImmExpr(
Offset))
7559 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7565bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7568 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7569 parseComma() || parseImmExpr(
Offset))
7571 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7577bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7580 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7581 parseComma() || parseImmExpr(
Offset))
7583 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7589bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7593 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7594 parseComma() || parseImmExpr(
Offset))
7596 if (check(((Reg - 19) % 2 != 0), L,
7597 "expected register with even offset from x19"))
7599 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7605bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7608 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7609 parseComma() || parseImmExpr(
Offset))
7611 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7617bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7620 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7621 parseComma() || parseImmExpr(
Offset))
7623 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7629bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7632 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7633 parseComma() || parseImmExpr(
Offset))
7635 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7641bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7644 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7645 parseComma() || parseImmExpr(
Offset))
7647 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7653bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7654 getTargetStreamer().emitARM64WinCFISetFP();
7660bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7662 if (parseImmExpr(
Size))
7664 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7670bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7671 getTargetStreamer().emitARM64WinCFINop();
7677bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7678 getTargetStreamer().emitARM64WinCFISaveNext();
7684bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7685 getTargetStreamer().emitARM64WinCFIEpilogStart();
7691bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7692 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7698bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7699 getTargetStreamer().emitARM64WinCFITrapFrame();
7705bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7706 getTargetStreamer().emitARM64WinCFIMachineFrame();
7712bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7713 getTargetStreamer().emitARM64WinCFIContext();
7719bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7720 getTargetStreamer().emitARM64WinCFIECContext();
7726bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7727 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7733bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7734 getTargetStreamer().emitARM64WinCFIPACSignLR();
7743bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7748 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7749 parseComma() || parseImmExpr(
Offset))
7752 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7753 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7754 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7755 return Error(L,
"invalid save_any_reg offset");
7756 unsigned EncodedReg;
7757 if (Reg == AArch64::FP)
7759 else if (Reg == AArch64::LR)
7762 EncodedReg =
Reg - AArch64::X0;
7764 if (Reg == AArch64::LR)
7765 return Error(Start,
"lr cannot be paired with another register");
7767 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7769 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7772 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7774 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7776 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7777 unsigned EncodedReg =
Reg - AArch64::D0;
7778 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7779 return Error(L,
"invalid save_any_reg offset");
7781 if (Reg == AArch64::D31)
7782 return Error(Start,
"d31 cannot be paired with another register");
7784 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7786 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7789 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7791 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7793 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7794 unsigned EncodedReg =
Reg - AArch64::Q0;
7796 return Error(L,
"invalid save_any_reg offset");
7798 if (Reg == AArch64::Q31)
7799 return Error(Start,
"q31 cannot be paired with another register");
7801 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7803 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7806 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7808 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7811 return Error(Start,
"save_any_reg register must be x, q or d register");
7816bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7818 if (!parseAuthExpr(Res, EndLoc))
7820 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7827bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7838 "combination of @AUTH with other modifiers not supported");
7861 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7883 return TokError(
"expected key name");
7888 return TokError(
"invalid key '" + KeyStr +
"'");
7895 return TokError(
"expected integer discriminator");
7898 if (!isUInt<16>(Discriminator))
7899 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7900 " out of range [0, 0xFFFF]");
7903 bool UseAddressDiversity =
false;
7908 return TokError(
"expected 'addr'");
7909 UseAddressDiversity =
true;
7918 UseAddressDiversity, Ctx);
7923AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7931 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7932 ELFRefKind = AE->getKind();
7933 Expr = AE->getSubExpr();
7939 DarwinRefKind = SE->
getKind();
7946 if (!Relocatable || Res.
getSymB())
7973#define GET_REGISTER_MATCHER
7974#define GET_SUBTARGET_FEATURE_NAME
7975#define GET_MATCHER_IMPLEMENTATION
7976#define GET_MNEMONIC_SPELL_CHECKER
7977#include "AArch64GenAsmMatcher.inc"
7983 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7985 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7987 return Match_InvalidOperand;
7990 return Match_InvalidOperand;
7991 if (CE->getValue() == ExpectedVal)
7992 return Match_Success;
7993 return Match_InvalidOperand;
7998 return Match_InvalidOperand;
8004 if (
Op.isTokenEqual(
"za"))
8005 return Match_Success;
8006 return Match_InvalidOperand;
8012#define MATCH_HASH(N) \
8013 case MCK__HASH_##N: \
8014 return MatchesOpImmediate(N);
8040#define MATCH_HASH_MINUS(N) \
8041 case MCK__HASH__MINUS_##N: \
8042 return MatchesOpImmediate(-N);
8046#undef MATCH_HASH_MINUS
8055 return Error(S,
"expected register");
8058 ParseStatus Res = tryParseScalarRegister(FirstReg);
8060 return Error(S,
"expected first even register of a consecutive same-size "
8061 "even/odd register pair");
8064 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8066 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8068 bool isXReg = XRegClass.
contains(FirstReg),
8069 isWReg = WRegClass.
contains(FirstReg);
8070 if (!isXReg && !isWReg)
8071 return Error(S,
"expected first even register of a consecutive same-size "
8072 "even/odd register pair");
8077 if (FirstEncoding & 0x1)
8078 return Error(S,
"expected first even register of a consecutive same-size "
8079 "even/odd register pair");
8082 return Error(getLoc(),
"expected comma");
8088 Res = tryParseScalarRegister(SecondReg);
8090 return Error(E,
"expected second odd register of a consecutive same-size "
8091 "even/odd register pair");
8094 (isXReg && !XRegClass.
contains(SecondReg)) ||
8095 (isWReg && !WRegClass.
contains(SecondReg)))
8096 return Error(E,
"expected second odd register of a consecutive same-size "
8097 "even/odd register pair");
8102 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8105 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8108 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8109 getLoc(), getContext()));
8114template <
bool ParseShiftExtend,
bool ParseSuffix>
8116 const SMLoc S = getLoc();
8122 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8127 if (ParseSuffix &&
Kind.empty())
8134 unsigned ElementWidth = KindRes->second;
8138 Operands.push_back(AArch64Operand::CreateVectorReg(
8139 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
8152 Res = tryParseOptionalShiftExtend(ExtOpnd);
8156 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
8157 Operands.push_back(AArch64Operand::CreateVectorReg(
8158 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8159 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
8160 Ext->hasShiftExtendAmount()));
8185 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8187 return TokError(
"invalid operand for instruction");
8192 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8203 SS, getLoc(), getContext()));
8214 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8225 SS, getLoc(), getContext()));
8234 if (!tryParseScalarRegister(XReg).isSuccess())
8240 XReg, AArch64::x8sub_0,
8241 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8244 "expected an even-numbered x-register in the range [x0,x22]");
8247 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8261 if (getParser().parseExpression(ImmF))
8271 SMLoc E = getTok().getLoc();
8273 if (getParser().parseExpression(ImmL))
8276 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8277 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8280 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
8295 if (getParser().parseExpression(Ex))
8298 int64_t
Imm = dyn_cast<MCConstantExpr>(Ex)->getValue();
8305 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8312 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)
const SysReg * lookupSysRegByName(StringRef)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
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