71 SVEPredicateAsCounter,
77enum class MatrixKind {
Array, Tile, Row, Col };
79enum RegConstraintEqualityTy {
94 static PrefixInfo CreateFromInst(
const MCInst &Inst,
uint64_t TSFlags) {
97 case AArch64::MOVPRFX_ZZ:
101 case AArch64::MOVPRFX_ZPmZ_B:
102 case AArch64::MOVPRFX_ZPmZ_H:
103 case AArch64::MOVPRFX_ZPmZ_S:
104 case AArch64::MOVPRFX_ZPmZ_D:
109 "No destructive element size set for movprfx");
113 case AArch64::MOVPRFX_ZPzZ_B:
114 case AArch64::MOVPRFX_ZPzZ_H:
115 case AArch64::MOVPRFX_ZPzZ_S:
116 case AArch64::MOVPRFX_ZPzZ_D:
121 "No destructive element size set for movprfx");
132 PrefixInfo() =
default;
133 bool isActive()
const {
return Active; }
135 unsigned getElementSize()
const {
139 unsigned getDstReg()
const {
return Dst; }
140 unsigned getPgReg()
const {
148 unsigned ElementSize;
164 std::string &Suggestion);
166 unsigned matchRegisterNameAlias(
StringRef Name, RegKind Kind);
168 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
174 bool invertCondCode);
175 bool parseImmExpr(int64_t &Out);
177 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
185 bool parseDirectiveArch(
SMLoc L);
186 bool parseDirectiveArchExtension(
SMLoc L);
187 bool parseDirectiveCPU(
SMLoc L);
188 bool parseDirectiveInst(
SMLoc L);
190 bool parseDirectiveTLSDescCall(
SMLoc L);
193 bool parseDirectiveLtorg(
SMLoc L);
196 bool parseDirectiveUnreq(
SMLoc L);
197 bool parseDirectiveCFINegateRAState();
198 bool parseDirectiveCFIBKeyFrame();
199 bool parseDirectiveCFIMTETaggedFrame();
201 bool parseDirectiveVariantPCS(
SMLoc L);
203 bool parseDirectiveSEHAllocStack(
SMLoc L);
204 bool parseDirectiveSEHPrologEnd(
SMLoc L);
205 bool parseDirectiveSEHSaveR19R20X(
SMLoc L);
206 bool parseDirectiveSEHSaveFPLR(
SMLoc L);
207 bool parseDirectiveSEHSaveFPLRX(
SMLoc L);
208 bool parseDirectiveSEHSaveReg(
SMLoc L);
209 bool parseDirectiveSEHSaveRegX(
SMLoc L);
210 bool parseDirectiveSEHSaveRegP(
SMLoc L);
211 bool parseDirectiveSEHSaveRegPX(
SMLoc L);
212 bool parseDirectiveSEHSaveLRPair(
SMLoc L);
213 bool parseDirectiveSEHSaveFReg(
SMLoc L);
214 bool parseDirectiveSEHSaveFRegX(
SMLoc L);
215 bool parseDirectiveSEHSaveFRegP(
SMLoc L);
216 bool parseDirectiveSEHSaveFRegPX(
SMLoc L);
217 bool parseDirectiveSEHSetFP(
SMLoc L);
218 bool parseDirectiveSEHAddFP(
SMLoc L);
219 bool parseDirectiveSEHNop(
SMLoc L);
220 bool parseDirectiveSEHSaveNext(
SMLoc L);
221 bool parseDirectiveSEHEpilogStart(
SMLoc L);
222 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
223 bool parseDirectiveSEHTrapFrame(
SMLoc L);
224 bool parseDirectiveSEHMachineFrame(
SMLoc L);
225 bool parseDirectiveSEHContext(
SMLoc L);
226 bool parseDirectiveSEHECContext(
SMLoc L);
227 bool parseDirectiveSEHClearUnwoundToCall(
SMLoc L);
228 bool parseDirectiveSEHPACSignLR(
SMLoc L);
229 bool parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
bool Writeback);
231 bool validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
233 unsigned getNumRegsForRegKind(RegKind K);
237 bool MatchingInlineAsm)
override;
241#define GET_ASSEMBLER_HEADER
242#include "AArch64GenAsmMatcher.inc"
256 template <
bool IsSVEPrefetch = false>
263 template <
bool AddFPZeroAsLiteral>
271 template <
bool ParseShiftExtend,
272 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
275 template <
bool ParseShiftExtend,
bool ParseSuffix>
277 template <RegKind RK>
281 template <RegKind VectorKind>
283 bool ExpectMatch =
false);
291 enum AArch64MatchResultTy {
293#define GET_OPERAND_DIAGNOSTIC_TYPES
294#include "AArch64GenAsmMatcher.inc"
297 bool IsWindowsArm64EC;
328 SMLoc &EndLoc)
override;
331 unsigned Kind)
override;
335 static bool classifySymbolRef(
const MCExpr *Expr,
367 SMLoc StartLoc, EndLoc;
376 struct ShiftExtendOp {
379 bool HasExplicitAmount;
389 RegConstraintEqualityTy EqualityTy;
405 ShiftExtendOp ShiftExtend;
410 unsigned ElementWidth;
414 struct MatrixTileListOp {
415 unsigned RegMask = 0;
418 struct VectorListOp {
422 unsigned NumElements;
423 unsigned ElementWidth;
424 RegKind RegisterKind;
427 struct VectorIndexOp {
435 struct ShiftedImmOp {
437 unsigned ShiftAmount;
494 unsigned PStateField;
500 struct MatrixRegOp MatrixReg;
501 struct MatrixTileListOp MatrixTileList;
502 struct VectorListOp VectorList;
503 struct VectorIndexOp VectorIndex;
505 struct ShiftedImmOp ShiftedImm;
506 struct ImmRangeOp ImmRange;
508 struct FPImmOp FPImm;
510 struct SysRegOp SysReg;
511 struct SysCRImmOp SysCRImm;
513 struct PSBHintOp PSBHint;
514 struct BTIHintOp BTIHint;
515 struct ShiftExtendOp ShiftExtend;
528 StartLoc =
o.StartLoc;
538 ShiftedImm =
o.ShiftedImm;
541 ImmRange =
o.ImmRange;
555 case k_MatrixRegister:
556 MatrixReg =
o.MatrixReg;
558 case k_MatrixTileList:
559 MatrixTileList =
o.MatrixTileList;
562 VectorList =
o.VectorList;
565 VectorIndex =
o.VectorIndex;
571 SysCRImm =
o.SysCRImm;
583 ShiftExtend =
o.ShiftExtend;
592 SMLoc getStartLoc()
const override {
return StartLoc; }
594 SMLoc getEndLoc()
const override {
return EndLoc; }
597 assert(Kind == k_Token &&
"Invalid access!");
601 bool isTokenSuffix()
const {
602 assert(Kind == k_Token &&
"Invalid access!");
606 const MCExpr *getImm()
const {
607 assert(Kind == k_Immediate &&
"Invalid access!");
611 const MCExpr *getShiftedImmVal()
const {
612 assert(Kind == k_ShiftedImm &&
"Invalid access!");
613 return ShiftedImm.Val;
616 unsigned getShiftedImmShift()
const {
617 assert(Kind == k_ShiftedImm &&
"Invalid access!");
618 return ShiftedImm.ShiftAmount;
621 unsigned getFirstImmVal()
const {
622 assert(Kind == k_ImmRange &&
"Invalid access!");
623 return ImmRange.First;
626 unsigned getLastImmVal()
const {
627 assert(Kind == k_ImmRange &&
"Invalid access!");
628 return ImmRange.Last;
632 assert(Kind == k_CondCode &&
"Invalid access!");
637 assert (Kind == k_FPImm &&
"Invalid access!");
638 return APFloat(APFloat::IEEEdouble(),
APInt(64, FPImm.Val,
true));
641 bool getFPImmIsExact()
const {
642 assert (Kind == k_FPImm &&
"Invalid access!");
643 return FPImm.IsExact;
646 unsigned getBarrier()
const {
647 assert(Kind == k_Barrier &&
"Invalid access!");
652 assert(Kind == k_Barrier &&
"Invalid access!");
656 bool getBarriernXSModifier()
const {
657 assert(Kind == k_Barrier &&
"Invalid access!");
662 assert(Kind == k_Register &&
"Invalid access!");
666 unsigned getMatrixReg()
const {
667 assert(Kind == k_MatrixRegister &&
"Invalid access!");
668 return MatrixReg.RegNum;
671 unsigned getMatrixElementWidth()
const {
672 assert(Kind == k_MatrixRegister &&
"Invalid access!");
673 return MatrixReg.ElementWidth;
676 MatrixKind getMatrixKind()
const {
677 assert(Kind == k_MatrixRegister &&
"Invalid access!");
678 return MatrixReg.Kind;
681 unsigned getMatrixTileListRegMask()
const {
682 assert(isMatrixTileList() &&
"Invalid access!");
683 return MatrixTileList.RegMask;
686 RegConstraintEqualityTy getRegEqualityTy()
const {
687 assert(Kind == k_Register &&
"Invalid access!");
688 return Reg.EqualityTy;
691 unsigned getVectorListStart()
const {
692 assert(Kind == k_VectorList &&
"Invalid access!");
693 return VectorList.RegNum;
696 unsigned getVectorListCount()
const {
697 assert(Kind == k_VectorList &&
"Invalid access!");
698 return VectorList.Count;
701 unsigned getVectorListStride()
const {
702 assert(Kind == k_VectorList &&
"Invalid access!");
703 return VectorList.Stride;
706 int getVectorIndex()
const {
707 assert(Kind == k_VectorIndex &&
"Invalid access!");
708 return VectorIndex.Val;
712 assert(Kind == k_SysReg &&
"Invalid access!");
713 return StringRef(SysReg.Data, SysReg.Length);
716 unsigned getSysCR()
const {
717 assert(Kind == k_SysCR &&
"Invalid access!");
721 unsigned getPrefetch()
const {
722 assert(Kind == k_Prefetch &&
"Invalid access!");
726 unsigned getPSBHint()
const {
727 assert(Kind == k_PSBHint &&
"Invalid access!");
732 assert(Kind == k_PSBHint &&
"Invalid access!");
733 return StringRef(PSBHint.Data, PSBHint.Length);
736 unsigned getBTIHint()
const {
737 assert(Kind == k_BTIHint &&
"Invalid access!");
742 assert(Kind == k_BTIHint &&
"Invalid access!");
743 return StringRef(BTIHint.Data, BTIHint.Length);
747 assert(Kind == k_SVCR &&
"Invalid access!");
748 return StringRef(SVCR.Data, SVCR.Length);
752 assert(Kind == k_Prefetch &&
"Invalid access!");
757 if (Kind == k_ShiftExtend)
758 return ShiftExtend.Type;
759 if (Kind == k_Register)
760 return Reg.ShiftExtend.Type;
764 unsigned getShiftExtendAmount()
const {
765 if (Kind == k_ShiftExtend)
766 return ShiftExtend.Amount;
767 if (Kind == k_Register)
768 return Reg.ShiftExtend.Amount;
772 bool hasShiftExtendAmount()
const {
773 if (Kind == k_ShiftExtend)
774 return ShiftExtend.HasExplicitAmount;
775 if (Kind == k_Register)
776 return Reg.ShiftExtend.HasExplicitAmount;
780 bool isImm()
const override {
return Kind == k_Immediate; }
781 bool isMem()
const override {
return false; }
783 bool isUImm6()
const {
790 return (Val >= 0 && Val < 64);
793 template <
int W
idth>
bool isSImm()
const {
return isSImmScaled<Width, 1>(); }
796 return isImmScaled<Bits, Scale>(
true);
799 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
801 if (IsRange && isImmRange() &&
802 (getLastImmVal() != getFirstImmVal() +
Offset))
803 return DiagnosticPredicateTy::NoMatch;
805 return isImmScaled<Bits, Scale, IsRange>(
false);
808 template <
int Bits,
int Scale,
bool IsRange = false>
810 if ((!
isImm() && !isImmRange()) || (
isImm() && IsRange) ||
811 (isImmRange() && !IsRange))
812 return DiagnosticPredicateTy::NoMatch;
816 Val = getFirstImmVal();
820 return DiagnosticPredicateTy::NoMatch;
824 int64_t MinVal, MaxVal;
826 int64_t Shift =
Bits - 1;
827 MinVal = (int64_t(1) << Shift) * -Scale;
828 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
831 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
834 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
835 return DiagnosticPredicateTy::Match;
837 return DiagnosticPredicateTy::NearMatch;
842 return DiagnosticPredicateTy::NoMatch;
843 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
845 return DiagnosticPredicateTy::NoMatch;
847 if (Val >= 0 && Val < 32)
848 return DiagnosticPredicateTy::Match;
849 return DiagnosticPredicateTy::NearMatch;
854 return DiagnosticPredicateTy::NoMatch;
855 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
857 return DiagnosticPredicateTy::NoMatch;
859 if (Val >= 0 && Val <= 1)
860 return DiagnosticPredicateTy::Match;
861 return DiagnosticPredicateTy::NearMatch;
864 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
868 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
900 template <
int Scale>
bool isUImm12Offset()
const {
906 return isSymbolicUImm12Offset(getImm());
909 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
912 template <
int N,
int M>
913 bool isImmInRange()
const {
920 return (Val >=
N && Val <= M);
925 template <
typename T>
926 bool isLogicalImm()
const {
943 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
945 bool isImmRange()
const {
return Kind == k_ImmRange; }
950 template <
unsigned W
idth>
951 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
952 if (isShiftedImm() && Width == getShiftedImmShift())
953 if (
auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
954 return std::make_pair(
CE->getValue(), Width);
957 if (
auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
958 int64_t Val =
CE->getValue();
960 return std::make_pair(Val >> Width, Width);
962 return std::make_pair(Val, 0u);
968 bool isAddSubImm()
const {
969 if (!isShiftedImm() && !
isImm())
975 if (isShiftedImm()) {
976 unsigned Shift = ShiftedImm.ShiftAmount;
977 Expr = ShiftedImm.Val;
978 if (Shift != 0 && Shift != 12)
987 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
988 DarwinRefKind, Addend)) {
1005 if (
auto ShiftedVal = getShiftedVal<12>())
1006 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1013 bool isAddSubImmNeg()
const {
1014 if (!isShiftedImm() && !
isImm())
1018 if (
auto ShiftedVal = getShiftedVal<12>())
1019 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1029 template <
typename T>
1031 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1032 return DiagnosticPredicateTy::NoMatch;
1034 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1035 std::is_same<int8_t, T>::value;
1036 if (
auto ShiftedImm = getShiftedVal<8>())
1037 if (!(IsByte && ShiftedImm->second) &&
1038 AArch64_AM::isSVECpyImm<T>(
uint64_t(ShiftedImm->first)
1039 << ShiftedImm->second))
1040 return DiagnosticPredicateTy::Match;
1042 return DiagnosticPredicateTy::NearMatch;
1049 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1050 return DiagnosticPredicateTy::NoMatch;
1052 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1053 std::is_same<int8_t, T>::value;
1054 if (
auto ShiftedImm = getShiftedVal<8>())
1055 if (!(IsByte && ShiftedImm->second) &&
1056 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
1057 << ShiftedImm->second))
1058 return DiagnosticPredicateTy::Match;
1060 return DiagnosticPredicateTy::NearMatch;
1064 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1065 return DiagnosticPredicateTy::Match;
1066 return DiagnosticPredicateTy::NoMatch;
1069 bool isCondCode()
const {
return Kind == k_CondCode; }
1071 bool isSIMDImmType10()
const {
1081 bool isBranchTarget()
const {
1090 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1091 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1102 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1103 DarwinRefKind, Addend)) {
1112 bool isMovWSymbolG3()
const {
1116 bool isMovWSymbolG2()
const {
1117 return isMovWSymbol(
1124 bool isMovWSymbolG1()
const {
1125 return isMovWSymbol(
1133 bool isMovWSymbolG0()
const {
1134 return isMovWSymbol(
1142 template<
int RegW
idth,
int Shift>
1143 bool isMOVZMovAlias()
const {
1144 if (!
isImm())
return false;
1157 template<
int RegW
idth,
int Shift>
1158 bool isMOVNMovAlias()
const {
1159 if (!
isImm())
return false;
1162 if (!CE)
return false;
1168 bool isFPImm()
const {
1169 return Kind == k_FPImm &&
1173 bool isBarrier()
const {
1174 return Kind == k_Barrier && !getBarriernXSModifier();
1176 bool isBarriernXS()
const {
1177 return Kind == k_Barrier && getBarriernXSModifier();
1179 bool isSysReg()
const {
return Kind == k_SysReg; }
1181 bool isMRSSystemRegister()
const {
1182 if (!isSysReg())
return false;
1184 return SysReg.MRSReg != -1U;
1187 bool isMSRSystemRegister()
const {
1188 if (!isSysReg())
return false;
1189 return SysReg.MSRReg != -1U;
1192 bool isSystemPStateFieldWithImm0_1()
const {
1193 if (!isSysReg())
return false;
1194 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1197 bool isSystemPStateFieldWithImm0_15()
const {
1200 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1203 bool isSVCR()
const {
1206 return SVCR.PStateField != -1U;
1209 bool isReg()
const override {
1210 return Kind == k_Register;
1213 bool isVectorList()
const {
return Kind == k_VectorList; }
1215 bool isScalarReg()
const {
1216 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1219 bool isNeonVectorReg()
const {
1220 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1223 bool isNeonVectorRegLo()
const {
1224 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1225 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1227 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1231 bool isNeonVectorReg0to7()
const {
1232 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1233 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1237 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1238 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1240 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1243 case AArch64::PPRRegClassID:
1244 case AArch64::PPR_3bRegClassID:
1245 case AArch64::PPR_p8to15RegClassID:
1246 case AArch64::PNRRegClassID:
1247 case AArch64::PNR_p8to15RegClassID:
1248 case AArch64::PPRorPNRRegClassID:
1249 RK = RegKind::SVEPredicateAsCounter;
1255 return (Kind == k_Register &&
Reg.Kind == RK) &&
1256 AArch64MCRegisterClasses[
Class].contains(
getReg());
1259 template <
unsigned Class>
bool isSVEVectorReg()
const {
1262 case AArch64::ZPRRegClassID:
1263 case AArch64::ZPR_3bRegClassID:
1264 case AArch64::ZPR_4bRegClassID:
1265 RK = RegKind::SVEDataVector;
1267 case AArch64::PPRRegClassID:
1268 case AArch64::PPR_3bRegClassID:
1269 case AArch64::PPR_p8to15RegClassID:
1270 case AArch64::PNRRegClassID:
1271 case AArch64::PNR_p8to15RegClassID:
1272 case AArch64::PPRorPNRRegClassID:
1273 RK = RegKind::SVEPredicateVector;
1279 return (Kind == k_Register &&
Reg.Kind == RK) &&
1280 AArch64MCRegisterClasses[
Class].contains(
getReg());
1283 template <
unsigned Class>
bool isFPRasZPR()
const {
1284 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1285 AArch64MCRegisterClasses[
Class].contains(
getReg());
1288 template <
int ElementW
idth,
unsigned Class>
1290 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1291 return DiagnosticPredicateTy::NoMatch;
1293 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1294 return DiagnosticPredicateTy::Match;
1296 return DiagnosticPredicateTy::NearMatch;
1299 template <
int ElementW
idth,
unsigned Class>
1301 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1302 Reg.Kind != RegKind::SVEPredicateVector))
1303 return DiagnosticPredicateTy::NoMatch;
1305 if ((isSVEPredicateAsCounterReg<Class>() ||
1306 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1307 Reg.ElementWidth == ElementWidth)
1308 return DiagnosticPredicateTy::Match;
1310 return DiagnosticPredicateTy::NearMatch;
1313 template <
int ElementW
idth,
unsigned Class>
1315 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1316 return DiagnosticPredicateTy::NoMatch;
1318 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1319 return DiagnosticPredicateTy::Match;
1321 return DiagnosticPredicateTy::NearMatch;
1324 template <
int ElementW
idth,
unsigned Class>
1326 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1327 return DiagnosticPredicateTy::NoMatch;
1329 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1330 return DiagnosticPredicateTy::Match;
1332 return DiagnosticPredicateTy::NearMatch;
1335 template <
int ElementWidth,
unsigned Class,
1337 bool ShiftWidthAlwaysSame>
1339 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1340 if (!VectorMatch.isMatch())
1341 return DiagnosticPredicateTy::NoMatch;
1346 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1349 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1350 return DiagnosticPredicateTy::NoMatch;
1352 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1353 return DiagnosticPredicateTy::Match;
1355 return DiagnosticPredicateTy::NearMatch;
1358 bool isGPR32as64()
const {
1359 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1360 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1363 bool isGPR64as32()
const {
1364 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1365 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1368 bool isGPR64x8()
const {
1369 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1370 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1374 bool isWSeqPair()
const {
1375 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1376 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1380 bool isXSeqPair()
const {
1381 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1382 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1386 bool isSyspXzrPair()
const {
1387 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1390 template<
int64_t Angle,
int64_t Remainder>
1392 if (!
isImm())
return DiagnosticPredicateTy::NoMatch;
1395 if (!CE)
return DiagnosticPredicateTy::NoMatch;
1398 if (
Value % Angle == Remainder &&
Value <= 270)
1399 return DiagnosticPredicateTy::Match;
1400 return DiagnosticPredicateTy::NearMatch;
1403 template <
unsigned RegClassID>
bool isGPR64()
const {
1404 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1405 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1408 template <
unsigned RegClassID,
int ExtW
idth>
1410 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1411 return DiagnosticPredicateTy::NoMatch;
1413 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1414 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1415 return DiagnosticPredicateTy::Match;
1416 return DiagnosticPredicateTy::NearMatch;
1421 template <RegKind VectorKind,
unsigned NumRegs>
1422 bool isImplicitlyTypedVectorList()
const {
1423 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1424 VectorList.NumElements == 0 &&
1425 VectorList.RegisterKind == VectorKind;
1428 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1429 unsigned ElementWidth,
unsigned Stride = 1>
1430 bool isTypedVectorList()
const {
1431 if (Kind != k_VectorList)
1433 if (VectorList.Count != NumRegs)
1435 if (VectorList.RegisterKind != VectorKind)
1437 if (VectorList.ElementWidth != ElementWidth)
1439 if (VectorList.Stride != Stride)
1441 return VectorList.NumElements == NumElements;
1444 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1445 unsigned ElementWidth>
1448 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1450 return DiagnosticPredicateTy::NoMatch;
1451 if (((VectorList.RegNum - AArch64::Z0) % NumRegs) != 0)
1452 return DiagnosticPredicateTy::NearMatch;
1453 return DiagnosticPredicateTy::Match;
1456 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1457 unsigned ElementWidth>
1459 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1460 ElementWidth, Stride>();
1462 return DiagnosticPredicateTy::NoMatch;
1463 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1464 ((VectorList.RegNum >= AArch64::Z16) &&
1465 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1466 return DiagnosticPredicateTy::Match;
1467 return DiagnosticPredicateTy::NoMatch;
1470 template <
int Min,
int Max>
1472 if (Kind != k_VectorIndex)
1473 return DiagnosticPredicateTy::NoMatch;
1474 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1475 return DiagnosticPredicateTy::Match;
1476 return DiagnosticPredicateTy::NearMatch;
1479 bool isToken()
const override {
return Kind == k_Token; }
1481 bool isTokenEqual(
StringRef Str)
const {
1482 return Kind == k_Token && getToken() == Str;
1484 bool isSysCR()
const {
return Kind == k_SysCR; }
1485 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1486 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1487 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1488 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1489 bool isShifter()
const {
1490 if (!isShiftExtend())
1500 if (Kind != k_FPImm)
1501 return DiagnosticPredicateTy::NoMatch;
1503 if (getFPImmIsExact()) {
1505 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1509 APFloat RealVal(APFloat::IEEEdouble());
1511 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1512 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1515 if (
getFPImm().bitwiseIsEqual(RealVal))
1516 return DiagnosticPredicateTy::Match;
1519 return DiagnosticPredicateTy::NearMatch;
1522 template <
unsigned ImmA,
unsigned ImmB>
1525 if ((Res = isExactFPImm<ImmA>()))
1526 return DiagnosticPredicateTy::Match;
1527 if ((Res = isExactFPImm<ImmB>()))
1528 return DiagnosticPredicateTy::Match;
1532 bool isExtend()
const {
1533 if (!isShiftExtend())
1542 getShiftExtendAmount() <= 4;
1545 bool isExtend64()
const {
1555 bool isExtendLSL64()
const {
1561 getShiftExtendAmount() <= 4;
1564 bool isLSLImm3Shift()
const {
1565 if (!isShiftExtend())
1571 template<
int W
idth>
bool isMemXExtend()
const {
1576 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1577 getShiftExtendAmount() == 0);
1580 template<
int W
idth>
bool isMemWExtend()
const {
1585 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1586 getShiftExtendAmount() == 0);
1589 template <
unsigned w
idth>
1590 bool isArithmeticShifter()
const {
1600 template <
unsigned w
idth>
1601 bool isLogicalShifter()
const {
1609 getShiftExtendAmount() < width;
1612 bool isMovImm32Shifter()
const {
1620 uint64_t Val = getShiftExtendAmount();
1621 return (Val == 0 || Val == 16);
1624 bool isMovImm64Shifter()
const {
1632 uint64_t Val = getShiftExtendAmount();
1633 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1636 bool isLogicalVecShifter()
const {
1641 unsigned Shift = getShiftExtendAmount();
1643 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1646 bool isLogicalVecHalfWordShifter()
const {
1647 if (!isLogicalVecShifter())
1651 unsigned Shift = getShiftExtendAmount();
1653 (Shift == 0 || Shift == 8);
1656 bool isMoveVecShifter()
const {
1657 if (!isShiftExtend())
1661 unsigned Shift = getShiftExtendAmount();
1663 (Shift == 8 || Shift == 16);
1672 bool isSImm9OffsetFB()
const {
1673 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1676 bool isAdrpLabel()
const {
1683 int64_t Val =
CE->getValue();
1684 int64_t Min = - (4096 * (1LL << (21 - 1)));
1685 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1686 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1692 bool isAdrLabel()
const {
1699 int64_t Val =
CE->getValue();
1700 int64_t Min = - (1LL << (21 - 1));
1701 int64_t
Max = ((1LL << (21 - 1)) - 1);
1702 return Val >= Min && Val <=
Max;
1708 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1711 return DiagnosticPredicateTy::NoMatch;
1712 if (getMatrixKind() != Kind ||
1713 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1714 EltSize != getMatrixElementWidth())
1715 return DiagnosticPredicateTy::NearMatch;
1716 return DiagnosticPredicateTy::Match;
1719 bool isPAuthPCRelLabel16Operand()
const {
1731 return (Val <= 0) && (Val > -(1 << 18));
1738 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1744 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1745 assert(
N == 1 &&
"Invalid number of operands!");
1749 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1750 assert(
N == 1 &&
"Invalid number of operands!");
1754 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1755 assert(
N == 1 &&
"Invalid number of operands!");
1757 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1766 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1767 assert(
N == 1 &&
"Invalid number of operands!");
1769 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1778 template <
int W
idth>
1779 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1782 case 8:
Base = AArch64::B0;
break;
1783 case 16:
Base = AArch64::H0;
break;
1784 case 32:
Base = AArch64::S0;
break;
1785 case 64:
Base = AArch64::D0;
break;
1786 case 128:
Base = AArch64::Q0;
break;
1793 void addPPRorPNRRegOperands(
MCInst &Inst,
unsigned N)
const {
1794 assert(
N == 1 &&
"Invalid number of operands!");
1797 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1798 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1802 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1803 assert(
N == 1 &&
"Invalid number of operands!");
1808 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1809 assert(
N == 1 &&
"Invalid number of operands!");
1811 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1815 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1816 assert(
N == 1 &&
"Invalid number of operands!");
1818 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1822 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1823 assert(
N == 1 &&
"Invalid number of operands!");
1827 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1828 assert(
N == 1 &&
"Invalid number of operands!");
1832 enum VecListIndexType {
1833 VecListIdx_DReg = 0,
1834 VecListIdx_QReg = 1,
1835 VecListIdx_ZReg = 2,
1836 VecListIdx_PReg = 3,
1839 template <VecListIndexType RegTy,
unsigned NumRegs>
1840 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1841 assert(
N == 1 &&
"Invalid number of operands!");
1842 static const unsigned FirstRegs[][5] = {
1844 AArch64::D0, AArch64::D0_D1,
1845 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1847 AArch64::Q0, AArch64::Q0_Q1,
1848 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1850 AArch64::Z0, AArch64::Z0_Z1,
1851 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1853 AArch64::P0, AArch64::P0_P1 }
1856 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1857 " NumRegs must be <= 4 for ZRegs");
1859 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1860 " NumRegs must be <= 2 for PRegs");
1862 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1864 FirstRegs[(
unsigned)RegTy][0]));
1867 template <
unsigned NumRegs>
1868 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1869 assert(
N == 1 &&
"Invalid number of operands!");
1870 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1874 if (getVectorListStart() < AArch64::Z16) {
1875 assert((getVectorListStart() < AArch64::Z8) &&
1876 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1878 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1880 assert((getVectorListStart() < AArch64::Z24) &&
1881 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1883 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1887 if (getVectorListStart() < AArch64::Z16) {
1888 assert((getVectorListStart() < AArch64::Z4) &&
1889 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1891 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1893 assert((getVectorListStart() < AArch64::Z20) &&
1894 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1896 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1904 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1905 assert(
N == 1 &&
"Invalid number of operands!");
1906 unsigned RegMask = getMatrixTileListRegMask();
1907 assert(RegMask <= 0xFF &&
"Invalid mask!");
1911 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1912 assert(
N == 1 &&
"Invalid number of operands!");
1916 template <
unsigned ImmIs0,
unsigned ImmIs1>
1917 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1918 assert(
N == 1 &&
"Invalid number of operands!");
1919 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1923 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1924 assert(
N == 1 &&
"Invalid number of operands!");
1928 addExpr(Inst, getImm());
1931 template <
int Shift>
1932 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1933 assert(
N == 2 &&
"Invalid number of operands!");
1934 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1937 }
else if (isShiftedImm()) {
1938 addExpr(Inst, getShiftedImmVal());
1941 addExpr(Inst, getImm());
1946 template <
int Shift>
1947 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1948 assert(
N == 2 &&
"Invalid number of operands!");
1949 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1956 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1957 assert(
N == 1 &&
"Invalid number of operands!");
1961 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1962 assert(
N == 1 &&
"Invalid number of operands!");
1965 addExpr(Inst, getImm());
1970 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
1971 addImmOperands(Inst,
N);
1975 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
1976 assert(
N == 1 &&
"Invalid number of operands!");
1986 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
1987 assert(
N == 1 &&
"Invalid number of operands!");
1992 template <
int Scale>
1993 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
1994 assert(
N == 1 &&
"Invalid number of operands!");
1999 template <
int Scale>
2000 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
2001 assert(
N == 1 &&
"Invalid number of operands!");
2005 template <
typename T>
2006 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
2007 assert(
N == 1 &&
"Invalid number of operands!");
2009 std::make_unsigned_t<T> Val = MCE->
getValue();
2014 template <
typename T>
2015 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2016 assert(
N == 1 &&
"Invalid number of operands!");
2018 std::make_unsigned_t<T> Val = ~MCE->getValue();
2023 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
2024 assert(
N == 1 &&
"Invalid number of operands!");
2030 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2034 assert(
N == 1 &&
"Invalid number of operands!");
2037 addExpr(Inst, getImm());
2040 assert(MCE &&
"Invalid constant immediate operand!");
2044 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2048 assert(
N == 1 &&
"Invalid number of operands!");
2051 addExpr(Inst, getImm());
2057 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2061 assert(
N == 1 &&
"Invalid number of operands!");
2064 addExpr(Inst, getImm());
2067 assert(MCE &&
"Invalid constant immediate operand!");
2071 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2075 assert(
N == 1 &&
"Invalid number of operands!");
2078 addExpr(Inst, getImm());
2081 assert(MCE &&
"Invalid constant immediate operand!");
2085 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2086 assert(
N == 1 &&
"Invalid number of operands!");
2091 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2092 assert(
N == 1 &&
"Invalid number of operands!");
2096 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2097 assert(
N == 1 &&
"Invalid number of operands!");
2101 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2102 assert(
N == 1 &&
"Invalid number of operands!");
2107 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2108 assert(
N == 1 &&
"Invalid number of operands!");
2113 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2114 assert(
N == 1 &&
"Invalid number of operands!");
2119 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2120 assert(
N == 1 &&
"Invalid number of operands!");
2125 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2126 assert(
N == 1 &&
"Invalid number of operands!");
2131 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2132 assert(
N == 1 &&
"Invalid number of operands!");
2136 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2137 assert(
N == 1 &&
"Invalid number of operands!");
2141 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2142 assert(
N == 1 &&
"Invalid number of operands!");
2146 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2147 assert(
N == 1 &&
"Invalid number of operands!");
2151 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2152 assert(
N == 1 &&
"Invalid number of operands!");
2158 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2159 assert(
N == 1 &&
"Invalid number of operands!");
2160 unsigned Imm = getShiftExtendAmount();
2164 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2165 assert(
N == 1 &&
"Invalid number of operands!");
2173 if (
Reg != AArch64::XZR)
2179 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2187 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2188 assert(
N == 1 &&
"Invalid number of operands!");
2195 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2196 assert(
N == 2 &&
"Invalid number of operands!");
2207 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2208 assert(
N == 2 &&
"Invalid number of operands!");
2216 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2217 assert(
N == 1 &&
"Invalid number of operands!");
2224 addExpr(Inst, getImm());
2229 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2230 assert(
N == 1 &&
"Invalid number of operands!");
2237 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2238 assert(
N == 1 &&
"Invalid number of operands!");
2243 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2244 assert(
N == 1 &&
"Invalid number of operands!");
2251 static std::unique_ptr<AArch64Operand>
2253 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2254 Op->Tok.Data = Str.data();
2255 Op->Tok.Length = Str.size();
2256 Op->Tok.IsSuffix = IsSuffix;
2262 static std::unique_ptr<AArch64Operand>
2264 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2266 unsigned ShiftAmount = 0,
2267 unsigned HasExplicitAmount =
false) {
2268 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2269 Op->Reg.RegNum = RegNum;
2271 Op->Reg.ElementWidth = 0;
2272 Op->Reg.EqualityTy = EqTy;
2273 Op->Reg.ShiftExtend.Type = ExtTy;
2274 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2275 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2281 static std::unique_ptr<AArch64Operand>
2282 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2285 unsigned ShiftAmount = 0,
2286 unsigned HasExplicitAmount =
false) {
2287 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2288 Kind == RegKind::SVEPredicateVector ||
2289 Kind == RegKind::SVEPredicateAsCounter) &&
2290 "Invalid vector kind");
2291 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2293 Op->Reg.ElementWidth = ElementWidth;
2297 static std::unique_ptr<AArch64Operand>
2298 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2299 unsigned NumElements,
unsigned ElementWidth,
2301 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2302 Op->VectorList.RegNum = RegNum;
2303 Op->VectorList.Count = Count;
2304 Op->VectorList.Stride = Stride;
2305 Op->VectorList.NumElements = NumElements;
2306 Op->VectorList.ElementWidth = ElementWidth;
2307 Op->VectorList.RegisterKind = RegisterKind;
2313 static std::unique_ptr<AArch64Operand>
2315 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2316 Op->VectorIndex.Val =
Idx;
2322 static std::unique_ptr<AArch64Operand>
2324 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2325 Op->MatrixTileList.RegMask = RegMask;
2332 const unsigned ElementWidth) {
2333 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2335 {{0, AArch64::ZAB0},
2336 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2337 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2338 {{8, AArch64::ZAB0},
2339 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2340 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2341 {{16, AArch64::ZAH0},
2342 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2343 {{16, AArch64::ZAH1},
2344 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2345 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2346 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2347 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2348 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2351 if (ElementWidth == 64)
2354 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2355 assert(!Regs.empty() &&
"Invalid tile or element width!");
2356 for (
auto OutReg : Regs)
2361 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2363 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2370 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2371 unsigned ShiftAmount,
2374 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2375 Op->ShiftedImm .Val = Val;
2376 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2382 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2386 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2388 Op->ImmRange.Last =
Last;
2393 static std::unique_ptr<AArch64Operand>
2395 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2396 Op->CondCode.Code =
Code;
2402 static std::unique_ptr<AArch64Operand>
2404 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2406 Op->FPImm.IsExact = IsExact;
2412 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2416 bool HasnXSModifier) {
2417 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2418 Op->Barrier.Val = Val;
2419 Op->Barrier.Data = Str.data();
2420 Op->Barrier.Length = Str.size();
2421 Op->Barrier.HasnXSModifier = HasnXSModifier;
2427 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2432 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2433 Op->SysReg.Data = Str.data();
2434 Op->SysReg.Length = Str.size();
2435 Op->SysReg.MRSReg = MRSReg;
2436 Op->SysReg.MSRReg = MSRReg;
2437 Op->SysReg.PStateField = PStateField;
2443 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2445 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2446 Op->SysCRImm.Val = Val;
2452 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2456 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2457 Op->Prefetch.Val = Val;
2458 Op->Barrier.Data = Str.data();
2459 Op->Barrier.Length = Str.size();
2465 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2469 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2470 Op->PSBHint.Val = Val;
2471 Op->PSBHint.Data = Str.data();
2472 Op->PSBHint.Length = Str.size();
2478 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2482 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2483 Op->BTIHint.Val = Val | 32;
2484 Op->BTIHint.Data = Str.data();
2485 Op->BTIHint.Length = Str.size();
2491 static std::unique_ptr<AArch64Operand>
2492 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2494 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2495 Op->MatrixReg.RegNum = RegNum;
2496 Op->MatrixReg.ElementWidth = ElementWidth;
2497 Op->MatrixReg.Kind =
Kind;
2503 static std::unique_ptr<AArch64Operand>
2505 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2506 Op->SVCR.PStateField = PStateField;
2507 Op->SVCR.Data = Str.data();
2508 Op->SVCR.Length = Str.size();
2514 static std::unique_ptr<AArch64Operand>
2517 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2518 Op->ShiftExtend.Type = ShOp;
2519 Op->ShiftExtend.Amount = Val;
2520 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2532 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2533 if (!getFPImmIsExact())
2540 OS <<
"<barrier " <<
Name <<
">";
2542 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2548 case k_ShiftedImm: {
2549 unsigned Shift = getShiftedImmShift();
2550 OS <<
"<shiftedimm ";
2551 OS << *getShiftedImmVal();
2557 OS << getFirstImmVal();
2558 OS <<
":" << getLastImmVal() <<
">";
2564 case k_VectorList: {
2565 OS <<
"<vectorlist ";
2566 unsigned Reg = getVectorListStart();
2567 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2568 OS <<
Reg + i * getVectorListStride() <<
" ";
2573 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2576 OS <<
"<sysreg: " << getSysReg() <<
'>';
2579 OS <<
"'" << getToken() <<
"'";
2582 OS <<
"c" << getSysCR();
2587 OS <<
"<prfop " <<
Name <<
">";
2589 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2593 OS << getPSBHintName();
2596 OS << getBTIHintName();
2598 case k_MatrixRegister:
2599 OS <<
"<matrix " << getMatrixReg() <<
">";
2601 case k_MatrixTileList: {
2602 OS <<
"<matrixlist ";
2603 unsigned RegMask = getMatrixTileListRegMask();
2604 unsigned MaxBits = 8;
2605 for (
unsigned I = MaxBits;
I > 0; --
I)
2606 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2615 OS <<
"<register " <<
getReg() <<
">";
2616 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2621 << getShiftExtendAmount();
2622 if (!hasShiftExtendAmount())
2638 .
Case(
"v0", AArch64::Q0)
2639 .
Case(
"v1", AArch64::Q1)
2640 .
Case(
"v2", AArch64::Q2)
2641 .
Case(
"v3", AArch64::Q3)
2642 .
Case(
"v4", AArch64::Q4)
2643 .
Case(
"v5", AArch64::Q5)
2644 .
Case(
"v6", AArch64::Q6)
2645 .
Case(
"v7", AArch64::Q7)
2646 .
Case(
"v8", AArch64::Q8)
2647 .
Case(
"v9", AArch64::Q9)
2648 .
Case(
"v10", AArch64::Q10)
2649 .
Case(
"v11", AArch64::Q11)
2650 .
Case(
"v12", AArch64::Q12)
2651 .
Case(
"v13", AArch64::Q13)
2652 .
Case(
"v14", AArch64::Q14)
2653 .
Case(
"v15", AArch64::Q15)
2654 .
Case(
"v16", AArch64::Q16)
2655 .
Case(
"v17", AArch64::Q17)
2656 .
Case(
"v18", AArch64::Q18)
2657 .
Case(
"v19", AArch64::Q19)
2658 .
Case(
"v20", AArch64::Q20)
2659 .
Case(
"v21", AArch64::Q21)
2660 .
Case(
"v22", AArch64::Q22)
2661 .
Case(
"v23", AArch64::Q23)
2662 .
Case(
"v24", AArch64::Q24)
2663 .
Case(
"v25", AArch64::Q25)
2664 .
Case(
"v26", AArch64::Q26)
2665 .
Case(
"v27", AArch64::Q27)
2666 .
Case(
"v28", AArch64::Q28)
2667 .
Case(
"v29", AArch64::Q29)
2668 .
Case(
"v30", AArch64::Q30)
2669 .
Case(
"v31", AArch64::Q31)
2678 RegKind VectorKind) {
2679 std::pair<int, int> Res = {-1, -1};
2681 switch (VectorKind) {
2682 case RegKind::NeonVector:
2685 .Case(
".1d", {1, 64})
2686 .Case(
".1q", {1, 128})
2688 .Case(
".2h", {2, 16})
2689 .Case(
".2b", {2, 8})
2690 .Case(
".2s", {2, 32})
2691 .Case(
".2d", {2, 64})
2694 .Case(
".4b", {4, 8})
2695 .Case(
".4h", {4, 16})
2696 .Case(
".4s", {4, 32})
2697 .Case(
".8b", {8, 8})
2698 .Case(
".8h", {8, 16})
2699 .Case(
".16b", {16, 8})
2704 .Case(
".h", {0, 16})
2705 .Case(
".s", {0, 32})
2706 .Case(
".d", {0, 64})
2709 case RegKind::SVEPredicateAsCounter:
2710 case RegKind::SVEPredicateVector:
2711 case RegKind::SVEDataVector:
2712 case RegKind::Matrix:
2716 .Case(
".h", {0, 16})
2717 .Case(
".s", {0, 32})
2718 .Case(
".d", {0, 64})
2719 .Case(
".q", {0, 128})
2726 if (Res == std::make_pair(-1, -1))
2727 return std::nullopt;
2729 return std::optional<std::pair<int, int>>(Res);
2738 .
Case(
"z0", AArch64::Z0)
2739 .
Case(
"z1", AArch64::Z1)
2740 .
Case(
"z2", AArch64::Z2)
2741 .
Case(
"z3", AArch64::Z3)
2742 .
Case(
"z4", AArch64::Z4)
2743 .
Case(
"z5", AArch64::Z5)
2744 .
Case(
"z6", AArch64::Z6)
2745 .
Case(
"z7", AArch64::Z7)
2746 .
Case(
"z8", AArch64::Z8)
2747 .
Case(
"z9", AArch64::Z9)
2748 .
Case(
"z10", AArch64::Z10)
2749 .
Case(
"z11", AArch64::Z11)
2750 .
Case(
"z12", AArch64::Z12)
2751 .
Case(
"z13", AArch64::Z13)
2752 .
Case(
"z14", AArch64::Z14)
2753 .
Case(
"z15", AArch64::Z15)
2754 .
Case(
"z16", AArch64::Z16)
2755 .
Case(
"z17", AArch64::Z17)
2756 .
Case(
"z18", AArch64::Z18)
2757 .
Case(
"z19", AArch64::Z19)
2758 .
Case(
"z20", AArch64::Z20)
2759 .
Case(
"z21", AArch64::Z21)
2760 .
Case(
"z22", AArch64::Z22)
2761 .
Case(
"z23", AArch64::Z23)
2762 .
Case(
"z24", AArch64::Z24)
2763 .
Case(
"z25", AArch64::Z25)
2764 .
Case(
"z26", AArch64::Z26)
2765 .
Case(
"z27", AArch64::Z27)
2766 .
Case(
"z28", AArch64::Z28)
2767 .
Case(
"z29", AArch64::Z29)
2768 .
Case(
"z30", AArch64::Z30)
2769 .
Case(
"z31", AArch64::Z31)
2775 .
Case(
"p0", AArch64::P0)
2776 .
Case(
"p1", AArch64::P1)
2777 .
Case(
"p2", AArch64::P2)
2778 .
Case(
"p3", AArch64::P3)
2779 .
Case(
"p4", AArch64::P4)
2780 .
Case(
"p5", AArch64::P5)
2781 .
Case(
"p6", AArch64::P6)
2782 .
Case(
"p7", AArch64::P7)
2783 .
Case(
"p8", AArch64::P8)
2784 .
Case(
"p9", AArch64::P9)
2785 .
Case(
"p10", AArch64::P10)
2786 .
Case(
"p11", AArch64::P11)
2787 .
Case(
"p12", AArch64::P12)
2788 .
Case(
"p13", AArch64::P13)
2789 .
Case(
"p14", AArch64::P14)
2790 .
Case(
"p15", AArch64::P15)
2796 .
Case(
"pn0", AArch64::PN0)
2797 .
Case(
"pn1", AArch64::PN1)
2798 .
Case(
"pn2", AArch64::PN2)
2799 .
Case(
"pn3", AArch64::PN3)
2800 .
Case(
"pn4", AArch64::PN4)
2801 .
Case(
"pn5", AArch64::PN5)
2802 .
Case(
"pn6", AArch64::PN6)
2803 .
Case(
"pn7", AArch64::PN7)
2804 .
Case(
"pn8", AArch64::PN8)
2805 .
Case(
"pn9", AArch64::PN9)
2806 .
Case(
"pn10", AArch64::PN10)
2807 .
Case(
"pn11", AArch64::PN11)
2808 .
Case(
"pn12", AArch64::PN12)
2809 .
Case(
"pn13", AArch64::PN13)
2810 .
Case(
"pn14", AArch64::PN14)
2811 .
Case(
"pn15", AArch64::PN15)
2817 .
Case(
"za0.d", AArch64::ZAD0)
2818 .
Case(
"za1.d", AArch64::ZAD1)
2819 .
Case(
"za2.d", AArch64::ZAD2)
2820 .
Case(
"za3.d", AArch64::ZAD3)
2821 .
Case(
"za4.d", AArch64::ZAD4)
2822 .
Case(
"za5.d", AArch64::ZAD5)
2823 .
Case(
"za6.d", AArch64::ZAD6)
2824 .
Case(
"za7.d", AArch64::ZAD7)
2825 .
Case(
"za0.s", AArch64::ZAS0)
2826 .
Case(
"za1.s", AArch64::ZAS1)
2827 .
Case(
"za2.s", AArch64::ZAS2)
2828 .
Case(
"za3.s", AArch64::ZAS3)
2829 .
Case(
"za0.h", AArch64::ZAH0)
2830 .
Case(
"za1.h", AArch64::ZAH1)
2831 .
Case(
"za0.b", AArch64::ZAB0)
2837 .
Case(
"za", AArch64::ZA)
2838 .
Case(
"za0.q", AArch64::ZAQ0)
2839 .
Case(
"za1.q", AArch64::ZAQ1)
2840 .
Case(
"za2.q", AArch64::ZAQ2)
2841 .
Case(
"za3.q", AArch64::ZAQ3)
2842 .
Case(
"za4.q", AArch64::ZAQ4)
2843 .
Case(
"za5.q", AArch64::ZAQ5)
2844 .
Case(
"za6.q", AArch64::ZAQ6)
2845 .
Case(
"za7.q", AArch64::ZAQ7)
2846 .
Case(
"za8.q", AArch64::ZAQ8)
2847 .
Case(
"za9.q", AArch64::ZAQ9)
2848 .
Case(
"za10.q", AArch64::ZAQ10)
2849 .
Case(
"za11.q", AArch64::ZAQ11)
2850 .
Case(
"za12.q", AArch64::ZAQ12)
2851 .
Case(
"za13.q", AArch64::ZAQ13)
2852 .
Case(
"za14.q", AArch64::ZAQ14)
2853 .
Case(
"za15.q", AArch64::ZAQ15)
2854 .
Case(
"za0.d", AArch64::ZAD0)
2855 .
Case(
"za1.d", AArch64::ZAD1)
2856 .
Case(
"za2.d", AArch64::ZAD2)
2857 .
Case(
"za3.d", AArch64::ZAD3)
2858 .
Case(
"za4.d", AArch64::ZAD4)
2859 .
Case(
"za5.d", AArch64::ZAD5)
2860 .
Case(
"za6.d", AArch64::ZAD6)
2861 .
Case(
"za7.d", AArch64::ZAD7)
2862 .
Case(
"za0.s", AArch64::ZAS0)
2863 .
Case(
"za1.s", AArch64::ZAS1)
2864 .
Case(
"za2.s", AArch64::ZAS2)
2865 .
Case(
"za3.s", AArch64::ZAS3)
2866 .
Case(
"za0.h", AArch64::ZAH0)
2867 .
Case(
"za1.h", AArch64::ZAH1)
2868 .
Case(
"za0.b", AArch64::ZAB0)
2869 .
Case(
"za0h.q", AArch64::ZAQ0)
2870 .
Case(
"za1h.q", AArch64::ZAQ1)
2871 .
Case(
"za2h.q", AArch64::ZAQ2)
2872 .
Case(
"za3h.q", AArch64::ZAQ3)
2873 .
Case(
"za4h.q", AArch64::ZAQ4)
2874 .
Case(
"za5h.q", AArch64::ZAQ5)
2875 .
Case(
"za6h.q", AArch64::ZAQ6)
2876 .
Case(
"za7h.q", AArch64::ZAQ7)
2877 .
Case(
"za8h.q", AArch64::ZAQ8)
2878 .
Case(
"za9h.q", AArch64::ZAQ9)
2879 .
Case(
"za10h.q", AArch64::ZAQ10)
2880 .
Case(
"za11h.q", AArch64::ZAQ11)
2881 .
Case(
"za12h.q", AArch64::ZAQ12)
2882 .
Case(
"za13h.q", AArch64::ZAQ13)
2883 .
Case(
"za14h.q", AArch64::ZAQ14)
2884 .
Case(
"za15h.q", AArch64::ZAQ15)
2885 .
Case(
"za0h.d", AArch64::ZAD0)
2886 .
Case(
"za1h.d", AArch64::ZAD1)
2887 .
Case(
"za2h.d", AArch64::ZAD2)
2888 .
Case(
"za3h.d", AArch64::ZAD3)
2889 .
Case(
"za4h.d", AArch64::ZAD4)
2890 .
Case(
"za5h.d", AArch64::ZAD5)
2891 .
Case(
"za6h.d", AArch64::ZAD6)
2892 .
Case(
"za7h.d", AArch64::ZAD7)
2893 .
Case(
"za0h.s", AArch64::ZAS0)
2894 .
Case(
"za1h.s", AArch64::ZAS1)
2895 .
Case(
"za2h.s", AArch64::ZAS2)
2896 .
Case(
"za3h.s", AArch64::ZAS3)
2897 .
Case(
"za0h.h", AArch64::ZAH0)
2898 .
Case(
"za1h.h", AArch64::ZAH1)
2899 .
Case(
"za0h.b", AArch64::ZAB0)
2900 .
Case(
"za0v.q", AArch64::ZAQ0)
2901 .
Case(
"za1v.q", AArch64::ZAQ1)
2902 .
Case(
"za2v.q", AArch64::ZAQ2)
2903 .
Case(
"za3v.q", AArch64::ZAQ3)
2904 .
Case(
"za4v.q", AArch64::ZAQ4)
2905 .
Case(
"za5v.q", AArch64::ZAQ5)
2906 .
Case(
"za6v.q", AArch64::ZAQ6)
2907 .
Case(
"za7v.q", AArch64::ZAQ7)
2908 .
Case(
"za8v.q", AArch64::ZAQ8)
2909 .
Case(
"za9v.q", AArch64::ZAQ9)
2910 .
Case(
"za10v.q", AArch64::ZAQ10)
2911 .
Case(
"za11v.q", AArch64::ZAQ11)
2912 .
Case(
"za12v.q", AArch64::ZAQ12)
2913 .
Case(
"za13v.q", AArch64::ZAQ13)
2914 .
Case(
"za14v.q", AArch64::ZAQ14)
2915 .
Case(
"za15v.q", AArch64::ZAQ15)
2916 .
Case(
"za0v.d", AArch64::ZAD0)
2917 .
Case(
"za1v.d", AArch64::ZAD1)
2918 .
Case(
"za2v.d", AArch64::ZAD2)
2919 .
Case(
"za3v.d", AArch64::ZAD3)
2920 .
Case(
"za4v.d", AArch64::ZAD4)
2921 .
Case(
"za5v.d", AArch64::ZAD5)
2922 .
Case(
"za6v.d", AArch64::ZAD6)
2923 .
Case(
"za7v.d", AArch64::ZAD7)
2924 .
Case(
"za0v.s", AArch64::ZAS0)
2925 .
Case(
"za1v.s", AArch64::ZAS1)
2926 .
Case(
"za2v.s", AArch64::ZAS2)
2927 .
Case(
"za3v.s", AArch64::ZAS3)
2928 .
Case(
"za0v.h", AArch64::ZAH0)
2929 .
Case(
"za1v.h", AArch64::ZAH1)
2930 .
Case(
"za0v.b", AArch64::ZAB0)
2936 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2941 StartLoc = getLoc();
2948unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
2950 unsigned RegNum = 0;
2952 return Kind == RegKind::SVEDataVector ? RegNum : 0;
2955 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
2958 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
2961 return Kind == RegKind::NeonVector ? RegNum : 0;
2964 return Kind == RegKind::Matrix ? RegNum : 0;
2966 if (
Name.equals_insensitive(
"zt0"))
2967 return Kind == RegKind::LookupTable ? AArch64::ZT0 : 0;
2971 return (Kind == RegKind::Scalar) ? RegNum : 0;
2976 .
Case(
"fp", AArch64::FP)
2977 .
Case(
"lr", AArch64::LR)
2978 .
Case(
"x31", AArch64::XZR)
2979 .
Case(
"w31", AArch64::WZR)
2981 return Kind == RegKind::Scalar ? RegNum : 0;
2987 if (Entry == RegisterReqs.
end())
2991 if (Kind ==
Entry->getValue().first)
2992 RegNum =
Entry->getValue().second;
2997unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2999 case RegKind::Scalar:
3000 case RegKind::NeonVector:
3001 case RegKind::SVEDataVector:
3003 case RegKind::Matrix:
3004 case RegKind::SVEPredicateVector:
3005 case RegKind::SVEPredicateAsCounter:
3007 case RegKind::LookupTable:
3022 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3036 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3039 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3040 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3044 if (BadNum || CRNum > 15)
3045 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3049 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3058 unsigned MaxVal = 63;
3064 if (getParser().parseExpression(ImmVal))
3069 return TokError(
"immediate value expected for prefetch operand");
3072 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3075 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3076 Operands.push_back(AArch64Operand::CreatePrefetch(
3077 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3082 return TokError(
"prefetch hint expected");
3084 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3086 return TokError(
"prefetch hint expected");
3088 Operands.push_back(AArch64Operand::CreatePrefetch(
3089 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3095template <
bool IsSVEPrefetch>
3101 if (IsSVEPrefetch) {
3102 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3103 return std::optional<unsigned>(Res->Encoding);
3104 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3105 return std::optional<unsigned>(Res->Encoding);
3106 return std::optional<unsigned>();
3109 auto LookupByEncoding = [](
unsigned E) {
3110 if (IsSVEPrefetch) {
3111 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3112 return std::optional<StringRef>(Res->Name);
3113 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3114 return std::optional<StringRef>(Res->Name);
3115 return std::optional<StringRef>();
3117 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3124 if (getParser().parseExpression(ImmVal))
3129 return TokError(
"immediate value expected for prefetch operand");
3132 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3135 auto PRFM = LookupByEncoding(MCE->
getValue());
3136 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3142 return TokError(
"prefetch hint expected");
3144 auto PRFM = LookupByName(Tok.
getString());
3146 return TokError(
"prefetch hint expected");
3148 Operands.push_back(AArch64Operand::CreatePrefetch(
3149 *PRFM, Tok.
getString(), S, getContext()));
3159 return TokError(
"invalid operand for instruction");
3161 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3163 return TokError(
"invalid operand for instruction");
3165 Operands.push_back(AArch64Operand::CreatePSBHint(
3166 PSB->Encoding, Tok.
getString(), S, getContext()));
3172 SMLoc StartLoc = getLoc();
3178 auto RegTok = getTok();
3179 if (!tryParseScalarRegister(RegNum).isSuccess())
3182 if (RegNum != AArch64::XZR) {
3183 getLexer().UnLex(RegTok);
3190 if (!tryParseScalarRegister(RegNum).isSuccess())
3191 return TokError(
"expected register operand");
3193 if (RegNum != AArch64::XZR)
3194 return TokError(
"xzr must be followed by xzr");
3198 Operands.push_back(AArch64Operand::CreateReg(
3199 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3209 return TokError(
"invalid operand for instruction");
3211 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3213 return TokError(
"invalid operand for instruction");
3215 Operands.push_back(AArch64Operand::CreateBTIHint(
3216 BTI->Encoding, Tok.
getString(), S, getContext()));
3225 const MCExpr *Expr =
nullptr;
3231 if (parseSymbolicImmVal(Expr))
3237 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3247 return Error(S,
"gotpage label reference not allowed an addend");
3257 return Error(S,
"page or gotpage label reference expected");
3265 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3274 const MCExpr *Expr =
nullptr;
3283 if (parseSymbolicImmVal(Expr))
3289 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3296 return Error(S,
"unexpected adr label");
3301 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3306template <
bool AddFPZeroAsLiteral>
3319 return TokError(
"invalid floating point immediate");
3324 if (Tok.
getIntVal() > 255 || isNegative)
3325 return TokError(
"encoded floating point value out of range");
3329 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3332 APFloat RealVal(APFloat::IEEEdouble());
3334 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3336 return TokError(
"invalid floating point representation");
3339 RealVal.changeSign();
3341 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3342 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3343 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3345 Operands.push_back(AArch64Operand::CreateFPImm(
3346 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3371 if (parseSymbolicImmVal(Imm))
3375 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3382 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3384 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3386 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3392 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3393 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3401 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3403 int64_t ShiftAmount = getTok().getIntVal();
3405 if (ShiftAmount < 0)
3406 return Error(getLoc(),
"positive shift amount required");
3410 if (ShiftAmount == 0 && Imm !=
nullptr) {
3412 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3416 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3417 getLoc(), getContext()));
3424AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3461 Suggestion =
"nfrst";
3468 bool invertCondCode) {
3474 std::string Suggestion;
3477 std::string Msg =
"invalid condition code";
3478 if (!Suggestion.empty())
3479 Msg +=
", did you mean " + Suggestion +
"?";
3480 return TokError(Msg);
3484 if (invertCondCode) {
3486 return TokError(
"condition codes AL and NV are invalid for this instruction");
3491 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3500 return TokError(
"invalid operand for instruction");
3502 unsigned PStateImm = -1;
3503 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3506 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3507 PStateImm = SVCR->Encoding;
3510 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3521 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3523 unsigned ElementWidth = 0;
3524 auto DotPosition =
Name.find(
'.');
3526 const auto &KindRes =
3530 "Expected the register to be followed by element width suffix");
3531 ElementWidth = KindRes->second;
3533 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3534 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3539 if (parseOperand(
Operands,
false,
false))
3546 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3550 size_t DotPosition =
Name.find(
'.');
3558 .
Case(
"h", MatrixKind::Row)
3559 .
Case(
"v", MatrixKind::Col)
3566 "Expected the register to be followed by element width suffix");
3567 unsigned ElementWidth = KindRes->second;
3571 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3572 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3577 if (parseOperand(
Operands,
false,
false))
3619 return TokError(
"expected #imm after shift specifier");
3625 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3634 return Error(
E,
"expected integer shift amount");
3637 if (getParser().parseExpression(ImmVal))
3642 return Error(
E,
"expected constant '#imm' after shift specifier");
3645 Operands.push_back(AArch64Operand::CreateShiftExtend(
3646 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3654 {
"crc", {AArch64::FeatureCRC}},
3655 {
"sm4", {AArch64::FeatureSM4}},
3656 {
"sha3", {AArch64::FeatureSHA3}},
3657 {
"sha2", {AArch64::FeatureSHA2}},
3658 {
"aes", {AArch64::FeatureAES}},
3659 {
"crypto", {AArch64::FeatureCrypto}},
3660 {
"fp", {AArch64::FeatureFPARMv8}},
3661 {
"simd", {AArch64::FeatureNEON}},
3662 {
"ras", {AArch64::FeatureRAS}},
3663 {
"rasv2", {AArch64::FeatureRASv2}},
3664 {
"lse", {AArch64::FeatureLSE}},
3665 {
"predres", {AArch64::FeaturePredRes}},
3666 {
"predres2", {AArch64::FeatureSPECRES2}},
3667 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3668 {
"mte", {AArch64::FeatureMTE}},
3669 {
"memtag", {AArch64::FeatureMTE}},
3670 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3671 {
"pan", {AArch64::FeaturePAN}},
3672 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3673 {
"ccpp", {AArch64::FeatureCCPP}},
3674 {
"rcpc", {AArch64::FeatureRCPC}},
3675 {
"rng", {AArch64::FeatureRandGen}},
3676 {
"sve", {AArch64::FeatureSVE}},
3677 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3678 {
"sve2", {AArch64::FeatureSVE2}},
3679 {
"sve2-aes", {AArch64::FeatureSVE2AES}},
3680 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3681 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3682 {
"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3683 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3684 {
"ls64", {AArch64::FeatureLS64}},
3685 {
"xs", {AArch64::FeatureXS}},
3686 {
"pauth", {AArch64::FeaturePAuth}},
3687 {
"flagm", {AArch64::FeatureFlagM}},
3688 {
"rme", {AArch64::FeatureRME}},
3689 {
"sme", {AArch64::FeatureSME}},
3690 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3691 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3692 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3693 {
"sme2", {AArch64::FeatureSME2}},
3694 {
"sme2p1", {AArch64::FeatureSME2p1}},
3695 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3696 {
"hbc", {AArch64::FeatureHBC}},
3697 {
"mops", {AArch64::FeatureMOPS}},
3698 {
"mec", {AArch64::FeatureMEC}},
3699 {
"the", {AArch64::FeatureTHE}},
3700 {
"d128", {AArch64::FeatureD128}},
3701 {
"lse128", {AArch64::FeatureLSE128}},
3702 {
"ite", {AArch64::FeatureITE}},
3703 {
"cssc", {AArch64::FeatureCSSC}},
3704 {
"rcpc3", {AArch64::FeatureRCPC3}},
3705 {
"gcs", {AArch64::FeatureGCS}},
3706 {
"bf16", {AArch64::FeatureBF16}},
3707 {
"compnum", {AArch64::FeatureComplxNum}},
3708 {
"dotprod", {AArch64::FeatureDotProd}},
3709 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3710 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3711 {
"fp16", {AArch64::FeatureFullFP16}},
3712 {
"fp16fml", {AArch64::FeatureFP16FML}},
3713 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3714 {
"lor", {AArch64::FeatureLOR}},
3715 {
"profile", {AArch64::FeatureSPE}},
3719 {
"rdm", {AArch64::FeatureRDM}},
3720 {
"rdma", {AArch64::FeatureRDM}},
3721 {
"sb", {AArch64::FeatureSB}},
3722 {
"ssbs", {AArch64::FeatureSSBS}},
3723 {
"tme", {AArch64::FeatureTME}},
3724 {
"fp8", {AArch64::FeatureFP8}},
3725 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3726 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3727 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3728 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3729 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3730 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3731 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3732 {
"lut", {AArch64::FeatureLUT}},
3733 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3734 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3735 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3736 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3737 {
"cpa", {AArch64::FeatureCPA}},
3738 {
"tlbiw", {AArch64::FeatureTLBIW}},
3742 if (FBS[AArch64::HasV8_0aOps])
3744 if (FBS[AArch64::HasV8_1aOps])
3746 else if (FBS[AArch64::HasV8_2aOps])
3748 else if (FBS[AArch64::HasV8_3aOps])
3750 else if (FBS[AArch64::HasV8_4aOps])
3752 else if (FBS[AArch64::HasV8_5aOps])
3754 else if (FBS[AArch64::HasV8_6aOps])
3756 else if (FBS[AArch64::HasV8_7aOps])
3758 else if (FBS[AArch64::HasV8_8aOps])
3760 else if (FBS[AArch64::HasV8_9aOps])
3762 else if (FBS[AArch64::HasV9_0aOps])
3764 else if (FBS[AArch64::HasV9_1aOps])
3766 else if (FBS[AArch64::HasV9_2aOps])
3768 else if (FBS[AArch64::HasV9_3aOps])
3770 else if (FBS[AArch64::HasV9_4aOps])
3772 else if (FBS[AArch64::HasV9_5aOps])
3774 else if (FBS[AArch64::HasV8_0rOps])
3783 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3790 const uint16_t Cm = (Encoding & 0x78) >> 3;
3791 const uint16_t Cn = (Encoding & 0x780) >> 7;
3792 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3797 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3799 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3801 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3804 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3811 if (
Name.contains(
'.'))
3812 return TokError(
"invalid operand");
3815 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3821 if (Mnemonic ==
"ic") {
3824 return TokError(
"invalid operand for IC instruction");
3825 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3826 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3828 return TokError(Str);
3831 }
else if (Mnemonic ==
"dc") {
3834 return TokError(
"invalid operand for DC instruction");
3835 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3836 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3838 return TokError(Str);
3841 }
else if (Mnemonic ==
"at") {
3844 return TokError(
"invalid operand for AT instruction");
3845 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3846 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3848 return TokError(Str);
3851 }
else if (Mnemonic ==
"tlbi") {
3854 return TokError(
"invalid operand for TLBI instruction");
3855 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3856 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3858 return TokError(Str);
3861 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3863 if (
Op.lower() !=
"rctx")
3864 return TokError(
"invalid operand for prediction restriction instruction");
3866 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3867 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3868 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3870 if (Mnemonic ==
"cosp" && !hasSpecres2)
3871 return TokError(
"COSP requires: predres2");
3873 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3875 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3876 : Mnemonic ==
"dvp" ? 0b101
3877 : Mnemonic ==
"cosp" ? 0b110
3878 : Mnemonic ==
"cpp" ? 0b111
3881 "Invalid mnemonic for prediction restriction instruction");
3882 const auto SYS_3_7_3 = 0b01101110011;
3883 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3885 createSysAlias(Encoding,
Operands, S);
3890 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3891 bool HasRegister =
false;
3896 return TokError(
"expected register operand");
3900 if (ExpectRegister && !HasRegister)
3901 return TokError(
"specified " + Mnemonic +
" op requires a register");
3902 else if (!ExpectRegister && HasRegister)
3903 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3915 if (
Name.contains(
'.'))
3916 return TokError(
"invalid operand");
3920 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
3926 if (Mnemonic ==
"tlbip") {
3927 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
3928 if (HasnXSQualifier) {
3929 Op =
Op.drop_back(3);
3933 return TokError(
"invalid operand for TLBIP instruction");
3935 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
3942 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
3943 std::string Str(
"TLBIP " +
Name +
" requires: ");
3945 return TokError(Str);
3956 return TokError(
"expected register identifier");
3961 return TokError(
"specified " + Mnemonic +
3962 " op requires a pair of registers");
3975 return TokError(
"'csync' operand expected");
3979 SMLoc ExprLoc = getLoc();
3981 if (getParser().parseExpression(ImmVal))
3985 return Error(ExprLoc,
"immediate value expected for barrier operand");
3987 if (Mnemonic ==
"dsb" &&
Value > 15) {
3994 if (Value < 0 || Value > 15)
3995 return Error(ExprLoc,
"barrier operand out of range");
3996 auto DB = AArch64DB::lookupDBByEncoding(
Value);
3997 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
3998 ExprLoc, getContext(),
4004 return TokError(
"invalid operand for instruction");
4007 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4008 auto DB = AArch64DB::lookupDBByName(Operand);
4010 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4011 return TokError(
"'sy' or #imm operand expected");
4013 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4014 return TokError(
"'csync' operand expected");
4016 if (Mnemonic ==
"dsb") {
4021 return TokError(
"invalid barrier option name");
4024 Operands.push_back(AArch64Operand::CreateBarrier(
4025 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4026 getContext(),
false ));
4036 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4037 if (Mnemonic !=
"dsb")
4043 SMLoc ExprLoc = getLoc();
4044 if (getParser().parseExpression(ImmVal))
4048 return Error(ExprLoc,
"immediate value expected for barrier operand");
4053 return Error(ExprLoc,
"barrier operand out of range");
4054 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4055 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4056 ExprLoc, getContext(),
4062 return TokError(
"invalid operand for instruction");
4065 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4068 return TokError(
"invalid barrier option name");
4071 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4072 getContext(),
true ));
4084 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4089 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4090 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4091 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4095 unsigned PStateImm = -1;
4096 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4097 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4098 PStateImm = PState15->Encoding;
4100 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4101 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4102 PStateImm = PState1->Encoding;
4106 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4107 PStateImm, getContext()));
4122 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4130 unsigned ElementWidth = KindRes->second;
4132 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4133 S, getLoc(), getContext()));
4138 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4140 return tryParseVectorIndex(
Operands).isFailure();
4144 SMLoc SIdx = getLoc();
4147 if (getParser().parseExpression(ImmVal))
4151 return TokError(
"immediate value expected for vector index");
4158 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4171 RegKind MatchKind) {
4180 size_t Start = 0, Next =
Name.find(
'.');
4182 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4188 return TokError(
"invalid vector kind qualifier");
4199ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4202 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4204 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4209template <RegKind RK>
4213 const SMLoc S = getLoc();
4216 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4224 unsigned ElementWidth = KindRes->second;
4225 Operands.push_back(AArch64Operand::CreateVectorReg(
4226 RegNum, RK, ElementWidth, S,
4227 getLoc(), getContext()));
4230 if (RK == RegKind::SVEPredicateAsCounter) {
4237 if (parseOperand(
Operands,
false,
false))
4248 return Error(S,
"not expecting size suffix");
4251 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4256 auto Pred = getTok().getString().lower();
4257 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4258 return Error(getLoc(),
"expecting 'z' predication");
4260 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4261 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4264 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4265 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4274 if (!tryParseNeonVectorRegister(
Operands))
4277 if (tryParseZTOperand(
Operands).isSuccess())
4281 if (tryParseGPROperand<false>(
Operands).isSuccess())
4287bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4288 bool HasELFModifier =
false;
4292 HasELFModifier =
true;
4295 return TokError(
"expect relocation specifier in operand after ':'");
4297 std::string LowerCase = getTok().getIdentifier().lower();
4348 return TokError(
"expect relocation specifier in operand after ':'");
4352 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4356 if (getParser().parseExpression(ImmVal))
4369 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4372 size_t DotPosition =
Name.find(
'.');
4381 const std::optional<std::pair<int, int>> &KindRes =
4385 "Expected the register to be followed by element width suffix");
4386 ElementWidth = KindRes->second;
4393 auto LCurly = getTok();
4398 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4399 0, S, getLoc(), getContext()));
4404 if (getTok().getString().equals_insensitive(
"za")) {
4410 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4411 0xFF, S, getLoc(), getContext()));
4415 SMLoc TileLoc = getLoc();
4417 unsigned FirstReg, ElementWidth;
4418 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4419 if (!ParseRes.isSuccess()) {
4420 getLexer().UnLex(LCurly);
4426 unsigned PrevReg = FirstReg;
4429 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4432 SeenRegs.
insert(FirstReg);
4436 unsigned Reg, NextElementWidth;
4437 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4438 if (!ParseRes.isSuccess())
4442 if (ElementWidth != NextElementWidth)
4443 return Error(TileLoc,
"mismatched register size suffix");
4446 Warning(TileLoc,
"tile list not in ascending order");
4449 Warning(TileLoc,
"duplicate tile in list");
4452 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4461 unsigned RegMask = 0;
4462 for (
auto Reg : DRegs)
4466 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4471template <RegKind VectorKind>
4481 auto RegTok = getTok();
4482 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4483 if (ParseRes.isSuccess()) {
4490 RegTok.getString().equals_insensitive(
"zt0"))
4494 (ParseRes.isNoMatch() && NoMatchIsError &&
4495 !RegTok.getString().starts_with_insensitive(
"za")))
4496 return Error(Loc,
"vector register expected");
4501 int NumRegs = getNumRegsForRegKind(VectorKind);
4503 auto LCurly = getTok();
4508 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4512 if (ParseRes.isNoMatch())
4515 if (!ParseRes.isSuccess())
4518 int64_t PrevReg = FirstReg;
4523 SMLoc Loc = getLoc();
4527 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4528 if (!ParseRes.isSuccess())
4532 if (Kind != NextKind)
4533 return Error(Loc,
"mismatched register size suffix");
4536 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4538 if (Space == 0 || Space > 3)
4539 return Error(Loc,
"invalid number of vectors");
4544 bool HasCalculatedStride =
false;
4546 SMLoc Loc = getLoc();
4549 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4550 if (!ParseRes.isSuccess())
4554 if (Kind != NextKind)
4555 return Error(Loc,
"mismatched register size suffix");
4557 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4558 unsigned PrevRegVal =
4559 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4560 if (!HasCalculatedStride) {
4561 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4562 : (RegVal + NumRegs - PrevRegVal);
4563 HasCalculatedStride =
true;
4567 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4568 return Error(Loc,
"registers must have the same sequential stride");
4579 return Error(S,
"invalid number of vectors");
4581 unsigned NumElements = 0;
4582 unsigned ElementWidth = 0;
4583 if (!
Kind.empty()) {
4585 std::tie(NumElements, ElementWidth) = *VK;
4588 Operands.push_back(AArch64Operand::CreateVectorList(
4589 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4590 getLoc(), getContext()));
4597 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4598 if (!ParseRes.isSuccess())
4601 return tryParseVectorIndex(
Operands).isFailure();
4605 SMLoc StartLoc = getLoc();
4613 Operands.push_back(AArch64Operand::CreateReg(
4614 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4621 return Error(getLoc(),
"index must be absent or #0");
4624 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4625 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4626 return Error(getLoc(),
"index must be absent or #0");
4628 Operands.push_back(AArch64Operand::CreateReg(
4629 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4634 SMLoc StartLoc = getLoc();
4638 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4643 Operands.push_back(AArch64Operand::CreateReg(
4644 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4650 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4652 if (getParser().parseExpression(ImmVal))
4656 return TokError(
"immediate value expected for vector index");
4657 Operands.push_back(AArch64Operand::CreateImm(
4659 getLoc(), getContext()));
4661 if (parseOptionalMulOperand(
Operands))
4666 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4671template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4673 SMLoc StartLoc = getLoc();
4682 Operands.push_back(AArch64Operand::CreateReg(
4683 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4692 Res = tryParseOptionalShiftExtend(ExtOpnd);
4696 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4697 Operands.push_back(AArch64Operand::CreateReg(
4698 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4699 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4700 Ext->hasShiftExtendAmount()));
4714 if (!getTok().getString().equals_insensitive(
"mul") ||
4715 !(NextIsVL || NextIsHash))
4719 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4724 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4736 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4737 Operands.push_back(AArch64Operand::CreateImm(
4744 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4750 auto Tok = Parser.
getTok();
4755 .
Case(
"vgx2",
"vgx2")
4756 .
Case(
"vgx4",
"vgx4")
4768 auto Tok = getTok();
4778 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4787 bool invertCondCode) {
4791 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4805 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4810 getLexer().UnLex(SavedTok);
4814 switch (getLexer().getKind()) {
4818 if (parseSymbolicImmVal(Expr))
4819 return Error(S,
"invalid operand");
4822 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4823 return parseOptionalShiftExtend(getTok());
4827 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4832 return parseOperand(
Operands,
false,
false);
4835 if (!parseNeonVectorList(
Operands))
4839 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4844 return parseOperand(
Operands,
false,
false);
4849 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4851 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4856 return parseCondCode(
Operands, invertCondCode);
4870 Res = tryParseOptionalShiftExtend(
Operands);
4873 getLexer().UnLex(SavedTok);
4880 if (!parseOptionalMulOperand(
Operands))
4885 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
4887 return parseKeywordOperand(
Operands);
4893 if (getParser().parseExpression(IdVal))
4896 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
4908 bool isNegative =
false;
4924 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
4925 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
4926 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
4927 return TokError(
"unexpected floating point literal");
4928 else if (IntVal != 0 || isNegative)
4929 return TokError(
"expected floating-point constant #0.0");
4932 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
4933 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
4938 if (parseSymbolicImmVal(ImmVal))
4942 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
4945 return parseOptionalShiftExtend(Tok);
4948 SMLoc Loc = getLoc();
4949 if (Mnemonic !=
"ldr")
4950 return TokError(
"unexpected token in operand");
4952 const MCExpr *SubExprVal;
4953 if (getParser().parseExpression(SubExprVal))
4957 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
4958 return Error(Loc,
"Only valid when first operand is register");
4961 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4967 if (isa<MCConstantExpr>(SubExprVal)) {
4968 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4969 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4974 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4975 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
4976 Operands.push_back(AArch64Operand::CreateImm(
4980 ShiftAmt,
true, S, E, Ctx));
4986 return Error(Loc,
"Immediate too large for register");
4990 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4991 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
4997bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4998 const MCExpr *Expr =
nullptr;
5000 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5003 if (check(!
Value, L,
"expected constant expression"))
5005 Out =
Value->getValue();
5009bool AArch64AsmParser::parseComma() {
5017bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5021 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5026 unsigned RangeEnd =
Last;
5027 if (
Base == AArch64::X0) {
5028 if (
Last == AArch64::FP) {
5029 RangeEnd = AArch64::X28;
5030 if (Reg == AArch64::FP) {
5035 if (
Last == AArch64::LR) {
5036 RangeEnd = AArch64::X28;
5037 if (Reg == AArch64::FP) {
5040 }
else if (Reg == AArch64::LR) {
5047 if (check(Reg < First || Reg > RangeEnd, Start,
5048 Twine(
"expected register in range ") +
5058 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5059 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5061 if (AOp1.isVectorList() && AOp2.isVectorList())
5062 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5063 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5064 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5066 if (!AOp1.isReg() || !AOp2.isReg())
5069 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5070 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5073 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5074 "Testing equality of non-scalar registers not supported");
5077 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5079 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5081 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5083 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5095 .
Case(
"beq",
"b.eq")
5096 .
Case(
"bne",
"b.ne")
5097 .
Case(
"bhs",
"b.hs")
5098 .
Case(
"bcs",
"b.cs")
5099 .
Case(
"blo",
"b.lo")
5100 .
Case(
"bcc",
"b.cc")
5101 .
Case(
"bmi",
"b.mi")
5102 .
Case(
"bpl",
"b.pl")
5103 .
Case(
"bvs",
"b.vs")
5104 .
Case(
"bvc",
"b.vc")
5105 .
Case(
"bhi",
"b.hi")
5106 .
Case(
"bls",
"b.ls")
5107 .
Case(
"bge",
"b.ge")
5108 .
Case(
"blt",
"b.lt")
5109 .
Case(
"bgt",
"b.gt")
5110 .
Case(
"ble",
"b.le")
5111 .
Case(
"bal",
"b.al")
5112 .
Case(
"bnv",
"b.nv")
5117 getTok().getIdentifier().lower() ==
".req") {
5118 parseDirectiveReq(
Name, NameLoc);
5125 size_t Start = 0, Next =
Name.find(
'.');
5130 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5131 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5132 return parseSysAlias(Head, NameLoc,
Operands);
5135 if (Head ==
"tlbip")
5136 return parseSyspAlias(Head, NameLoc,
Operands);
5138 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5144 Next =
Name.find(
'.', Start + 1);
5145 Head =
Name.slice(Start + 1, Next);
5149 std::string Suggestion;
5152 std::string Msg =
"invalid condition code";
5153 if (!Suggestion.empty())
5154 Msg +=
", did you mean " + Suggestion +
"?";
5155 return Error(SuffixLoc, Msg);
5157 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5160 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5166 Next =
Name.find(
'.', Start + 1);
5167 Head =
Name.slice(Start, Next);
5170 Operands.push_back(AArch64Operand::CreateToken(
5171 Head, SuffixLoc, getContext(),
true));
5176 bool condCodeFourthOperand =
5177 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5178 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5179 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5187 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5188 bool condCodeThirdOperand =
5189 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5197 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5198 (
N == 3 && condCodeThirdOperand) ||
5199 (
N == 2 && condCodeSecondOperand),
5200 condCodeSecondOperand || condCodeThirdOperand)) {
5220 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5223 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5226 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5239 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5240 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5241 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5242 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5243 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5244 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5245 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5251bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5260 PrefixInfo
Prefix = NextPrefix;
5261 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5273 return Error(IDLoc,
"instruction is unpredictable when following a"
5274 " movprfx, suggest replacing movprfx with mov");
5278 return Error(Loc[0],
"instruction is unpredictable when following a"
5279 " movprfx writing to a different destination");
5286 return Error(Loc[0],
"instruction is unpredictable when following a"
5287 " movprfx and destination also used as non-destructive"
5291 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5292 if (
Prefix.isPredicated()) {
5306 return Error(IDLoc,
"instruction is unpredictable when following a"
5307 " predicated movprfx, suggest using unpredicated movprfx");
5311 return Error(IDLoc,
"instruction is unpredictable when following a"
5312 " predicated movprfx using a different general predicate");
5316 return Error(IDLoc,
"instruction is unpredictable when following a"
5317 " predicated movprfx with a different element size");
5323 if (IsWindowsArm64EC) {
5329 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5330 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5331 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5332 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5333 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5334 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5335 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5336 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5337 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5338 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5340 " is disallowed on ARM64EC.");
5350 case AArch64::LDPSWpre:
5351 case AArch64::LDPWpost:
5352 case AArch64::LDPWpre:
5353 case AArch64::LDPXpost:
5354 case AArch64::LDPXpre: {
5359 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5360 "is also a destination");
5362 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5363 "is also a destination");
5366 case AArch64::LDR_ZA:
5367 case AArch64::STR_ZA: {
5370 return Error(Loc[1],
5371 "unpredictable instruction, immediate and offset mismatch.");
5374 case AArch64::LDPDi:
5375 case AArch64::LDPQi:
5376 case AArch64::LDPSi:
5377 case AArch64::LDPSWi:
5378 case AArch64::LDPWi:
5379 case AArch64::LDPXi: {
5383 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5386 case AArch64::LDPDpost:
5387 case AArch64::LDPDpre:
5388 case AArch64::LDPQpost:
5389 case AArch64::LDPQpre:
5390 case AArch64::LDPSpost:
5391 case AArch64::LDPSpre:
5392 case AArch64::LDPSWpost: {
5396 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5399 case AArch64::STPDpost:
5400 case AArch64::STPDpre:
5401 case AArch64::STPQpost:
5402 case AArch64::STPQpre:
5403 case AArch64::STPSpost:
5404 case AArch64::STPSpre:
5405 case AArch64::STPWpost:
5406 case AArch64::STPWpre:
5407 case AArch64::STPXpost:
5408 case AArch64::STPXpre: {
5413 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5414 "is also a source");
5416 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5417 "is also a source");
5420 case AArch64::LDRBBpre:
5421 case AArch64::LDRBpre:
5422 case AArch64::LDRHHpre:
5423 case AArch64::LDRHpre:
5424 case AArch64::LDRSBWpre:
5425 case AArch64::LDRSBXpre:
5426 case AArch64::LDRSHWpre:
5427 case AArch64::LDRSHXpre:
5428 case AArch64::LDRSWpre:
5429 case AArch64::LDRWpre:
5430 case AArch64::LDRXpre:
5431 case AArch64::LDRBBpost:
5432 case AArch64::LDRBpost:
5433 case AArch64::LDRHHpost:
5434 case AArch64::LDRHpost:
5435 case AArch64::LDRSBWpost:
5436 case AArch64::LDRSBXpost:
5437 case AArch64::LDRSHWpost:
5438 case AArch64::LDRSHXpost:
5439 case AArch64::LDRSWpost:
5440 case AArch64::LDRWpost:
5441 case AArch64::LDRXpost: {
5445 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5446 "is also a source");
5449 case AArch64::STRBBpost:
5450 case AArch64::STRBpost:
5451 case AArch64::STRHHpost:
5452 case AArch64::STRHpost:
5453 case AArch64::STRWpost:
5454 case AArch64::STRXpost:
5455 case AArch64::STRBBpre:
5456 case AArch64::STRBpre:
5457 case AArch64::STRHHpre:
5458 case AArch64::STRHpre:
5459 case AArch64::STRWpre:
5460 case AArch64::STRXpre: {
5464 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5465 "is also a source");
5468 case AArch64::STXRB:
5469 case AArch64::STXRH:
5470 case AArch64::STXRW:
5471 case AArch64::STXRX:
5472 case AArch64::STLXRB:
5473 case AArch64::STLXRH:
5474 case AArch64::STLXRW:
5475 case AArch64::STLXRX: {
5481 return Error(Loc[0],
5482 "unpredictable STXR instruction, status is also a source");
5485 case AArch64::STXPW:
5486 case AArch64::STXPX:
5487 case AArch64::STLXPW:
5488 case AArch64::STLXPX: {
5495 return Error(Loc[0],
5496 "unpredictable STXP instruction, status is also a source");
5499 case AArch64::LDRABwriteback:
5500 case AArch64::LDRAAwriteback: {
5504 return Error(Loc[0],
5505 "unpredictable LDRA instruction, writeback base"
5506 " is also a destination");
5513 case AArch64::CPYFP:
5514 case AArch64::CPYFPWN:
5515 case AArch64::CPYFPRN:
5516 case AArch64::CPYFPN:
5517 case AArch64::CPYFPWT:
5518 case AArch64::CPYFPWTWN:
5519 case AArch64::CPYFPWTRN:
5520 case AArch64::CPYFPWTN:
5521 case AArch64::CPYFPRT:
5522 case AArch64::CPYFPRTWN:
5523 case AArch64::CPYFPRTRN:
5524 case AArch64::CPYFPRTN:
5525 case AArch64::CPYFPT:
5526 case AArch64::CPYFPTWN:
5527 case AArch64::CPYFPTRN:
5528 case AArch64::CPYFPTN:
5529 case AArch64::CPYFM:
5530 case AArch64::CPYFMWN:
5531 case AArch64::CPYFMRN:
5532 case AArch64::CPYFMN:
5533 case AArch64::CPYFMWT:
5534 case AArch64::CPYFMWTWN:
5535 case AArch64::CPYFMWTRN:
5536 case AArch64::CPYFMWTN:
5537 case AArch64::CPYFMRT:
5538 case AArch64::CPYFMRTWN:
5539 case AArch64::CPYFMRTRN:
5540 case AArch64::CPYFMRTN:
5541 case AArch64::CPYFMT:
5542 case AArch64::CPYFMTWN:
5543 case AArch64::CPYFMTRN:
5544 case AArch64::CPYFMTN:
5545 case AArch64::CPYFE:
5546 case AArch64::CPYFEWN:
5547 case AArch64::CPYFERN:
5548 case AArch64::CPYFEN:
5549 case AArch64::CPYFEWT:
5550 case AArch64::CPYFEWTWN:
5551 case AArch64::CPYFEWTRN:
5552 case AArch64::CPYFEWTN:
5553 case AArch64::CPYFERT:
5554 case AArch64::CPYFERTWN:
5555 case AArch64::CPYFERTRN:
5556 case AArch64::CPYFERTN:
5557 case AArch64::CPYFET:
5558 case AArch64::CPYFETWN:
5559 case AArch64::CPYFETRN:
5560 case AArch64::CPYFETN:
5562 case AArch64::CPYPWN:
5563 case AArch64::CPYPRN:
5564 case AArch64::CPYPN:
5565 case AArch64::CPYPWT:
5566 case AArch64::CPYPWTWN:
5567 case AArch64::CPYPWTRN:
5568 case AArch64::CPYPWTN:
5569 case AArch64::CPYPRT:
5570 case AArch64::CPYPRTWN:
5571 case AArch64::CPYPRTRN:
5572 case AArch64::CPYPRTN:
5573 case AArch64::CPYPT:
5574 case AArch64::CPYPTWN:
5575 case AArch64::CPYPTRN:
5576 case AArch64::CPYPTN:
5578 case AArch64::CPYMWN:
5579 case AArch64::CPYMRN:
5580 case AArch64::CPYMN:
5581 case AArch64::CPYMWT:
5582 case AArch64::CPYMWTWN:
5583 case AArch64::CPYMWTRN:
5584 case AArch64::CPYMWTN:
5585 case AArch64::CPYMRT:
5586 case AArch64::CPYMRTWN:
5587 case AArch64::CPYMRTRN:
5588 case AArch64::CPYMRTN:
5589 case AArch64::CPYMT:
5590 case AArch64::CPYMTWN:
5591 case AArch64::CPYMTRN:
5592 case AArch64::CPYMTN:
5594 case AArch64::CPYEWN:
5595 case AArch64::CPYERN:
5596 case AArch64::CPYEN:
5597 case AArch64::CPYEWT:
5598 case AArch64::CPYEWTWN:
5599 case AArch64::CPYEWTRN:
5600 case AArch64::CPYEWTN:
5601 case AArch64::CPYERT:
5602 case AArch64::CPYERTWN:
5603 case AArch64::CPYERTRN:
5604 case AArch64::CPYERTN:
5605 case AArch64::CPYET:
5606 case AArch64::CPYETWN:
5607 case AArch64::CPYETRN:
5608 case AArch64::CPYETN: {
5616 return Error(Loc[0],
5617 "invalid CPY instruction, Xd_wb and Xd do not match");
5619 return Error(Loc[0],
5620 "invalid CPY instruction, Xs_wb and Xs do not match");
5622 return Error(Loc[0],
5623 "invalid CPY instruction, Xn_wb and Xn do not match");
5625 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5626 " registers are the same");
5628 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5629 " registers are the same");
5631 return Error(Loc[0],
"invalid CPY instruction, source and size"
5632 " registers are the same");
5636 case AArch64::SETPT:
5637 case AArch64::SETPN:
5638 case AArch64::SETPTN:
5640 case AArch64::SETMT:
5641 case AArch64::SETMN:
5642 case AArch64::SETMTN:
5644 case AArch64::SETET:
5645 case AArch64::SETEN:
5646 case AArch64::SETETN:
5647 case AArch64::SETGP:
5648 case AArch64::SETGPT:
5649 case AArch64::SETGPN:
5650 case AArch64::SETGPTN:
5651 case AArch64::SETGM:
5652 case AArch64::SETGMT:
5653 case AArch64::SETGMN:
5654 case AArch64::SETGMTN:
5655 case AArch64::MOPSSETGE:
5656 case AArch64::MOPSSETGET:
5657 case AArch64::MOPSSETGEN:
5658 case AArch64::MOPSSETGETN: {
5665 return Error(Loc[0],
5666 "invalid SET instruction, Xd_wb and Xd do not match");
5668 return Error(Loc[0],
5669 "invalid SET instruction, Xn_wb and Xn do not match");
5671 return Error(Loc[0],
"invalid SET instruction, destination and size"
5672 " registers are the same");
5674 return Error(Loc[0],
"invalid SET instruction, destination and source"
5675 " registers are the same");
5677 return Error(Loc[0],
"invalid SET instruction, source and size"
5678 " registers are the same");
5687 case AArch64::ADDSWri:
5688 case AArch64::ADDSXri:
5689 case AArch64::ADDWri:
5690 case AArch64::ADDXri:
5691 case AArch64::SUBSWri:
5692 case AArch64::SUBSXri:
5693 case AArch64::SUBWri:
5694 case AArch64::SUBXri: {
5702 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5729 return Error(Loc.
back(),
"invalid immediate expression");
5742 unsigned VariantID = 0);
5744bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5748 case Match_InvalidTiedOperand: {
5750 if (
Op.isVectorList())
5751 return Error(Loc,
"operand must match destination register list");
5753 assert(
Op.isReg() &&
"Unexpected operand type");
5754 switch (
Op.getRegEqualityTy()) {
5755 case RegConstraintEqualityTy::EqualsSubReg:
5756 return Error(Loc,
"operand must be 64-bit form of destination register");
5757 case RegConstraintEqualityTy::EqualsSuperReg:
5758 return Error(Loc,
"operand must be 32-bit form of destination register");
5759 case RegConstraintEqualityTy::EqualsReg:
5760 return Error(Loc,
"operand must match destination register");
5764 case Match_MissingFeature:
5766 "instruction requires a CPU feature not currently enabled");
5767 case Match_InvalidOperand:
5768 return Error(Loc,
"invalid operand for instruction");
5769 case Match_InvalidSuffix:
5770 return Error(Loc,
"invalid type suffix for instruction");
5771 case Match_InvalidCondCode:
5772 return Error(Loc,
"expected AArch64 condition code");
5773 case Match_AddSubRegExtendSmall:
5775 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5776 case Match_AddSubRegExtendLarge:
5778 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5779 case Match_AddSubSecondSource:
5781 "expected compatible register, symbol or integer in range [0, 4095]");
5782 case Match_LogicalSecondSource:
5783 return Error(Loc,
"expected compatible register or logical immediate");
5784 case Match_InvalidMovImm32Shift:
5785 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5786 case Match_InvalidMovImm64Shift:
5787 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5788 case Match_AddSubRegShift32:
5790 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5791 case Match_AddSubRegShift64:
5793 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5794 case Match_InvalidFPImm:
5796 "expected compatible register or floating-point constant");
5797 case Match_InvalidMemoryIndexedSImm6:
5798 return Error(Loc,
"index must be an integer in range [-32, 31].");
5799 case Match_InvalidMemoryIndexedSImm5:
5800 return Error(Loc,
"index must be an integer in range [-16, 15].");
5801 case Match_InvalidMemoryIndexed1SImm4:
5802 return Error(Loc,
"index must be an integer in range [-8, 7].");
5803 case Match_InvalidMemoryIndexed2SImm4:
5804 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5805 case Match_InvalidMemoryIndexed3SImm4:
5806 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5807 case Match_InvalidMemoryIndexed4SImm4:
5808 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5809 case Match_InvalidMemoryIndexed16SImm4:
5810 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5811 case Match_InvalidMemoryIndexed32SImm4:
5812 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5813 case Match_InvalidMemoryIndexed1SImm6:
5814 return Error(Loc,
"index must be an integer in range [-32, 31].");
5815 case Match_InvalidMemoryIndexedSImm8:
5816 return Error(Loc,
"index must be an integer in range [-128, 127].");
5817 case Match_InvalidMemoryIndexedSImm9:
5818 return Error(Loc,
"index must be an integer in range [-256, 255].");
5819 case Match_InvalidMemoryIndexed16SImm9:
5820 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5821 case Match_InvalidMemoryIndexed8SImm10:
5822 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5823 case Match_InvalidMemoryIndexed4SImm7:
5824 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5825 case Match_InvalidMemoryIndexed8SImm7:
5826 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5827 case Match_InvalidMemoryIndexed16SImm7:
5828 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5829 case Match_InvalidMemoryIndexed8UImm5:
5830 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5831 case Match_InvalidMemoryIndexed8UImm3:
5832 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5833 case Match_InvalidMemoryIndexed4UImm5:
5834 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5835 case Match_InvalidMemoryIndexed2UImm5:
5836 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5837 case Match_InvalidMemoryIndexed8UImm6:
5838 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5839 case Match_InvalidMemoryIndexed16UImm6:
5840 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5841 case Match_InvalidMemoryIndexed4UImm6:
5842 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5843 case Match_InvalidMemoryIndexed2UImm6:
5844 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5845 case Match_InvalidMemoryIndexed1UImm6:
5846 return Error(Loc,
"index must be in range [0, 63].");
5847 case Match_InvalidMemoryWExtend8:
5849 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5850 case Match_InvalidMemoryWExtend16:
5852 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5853 case Match_InvalidMemoryWExtend32:
5855 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5856 case Match_InvalidMemoryWExtend64:
5858 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5859 case Match_InvalidMemoryWExtend128:
5861 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5862 case Match_InvalidMemoryXExtend8:
5864 "expected 'lsl' or 'sxtx' with optional shift of #0");
5865 case Match_InvalidMemoryXExtend16:
5867 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5868 case Match_InvalidMemoryXExtend32:
5870 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5871 case Match_InvalidMemoryXExtend64:
5873 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5874 case Match_InvalidMemoryXExtend128:
5876 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5877 case Match_InvalidMemoryIndexed1:
5878 return Error(Loc,
"index must be an integer in range [0, 4095].");
5879 case Match_InvalidMemoryIndexed2:
5880 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
5881 case Match_InvalidMemoryIndexed4:
5882 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
5883 case Match_InvalidMemoryIndexed8:
5884 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
5885 case Match_InvalidMemoryIndexed16:
5886 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
5887 case Match_InvalidImm0_0:
5888 return Error(Loc,
"immediate must be 0.");
5889 case Match_InvalidImm0_1:
5890 return Error(Loc,
"immediate must be an integer in range [0, 1].");
5891 case Match_InvalidImm0_3:
5892 return Error(Loc,
"immediate must be an integer in range [0, 3].");
5893 case Match_InvalidImm0_7:
5894 return Error(Loc,
"immediate must be an integer in range [0, 7].");
5895 case Match_InvalidImm0_15:
5896 return Error(Loc,
"immediate must be an integer in range [0, 15].");
5897 case Match_InvalidImm0_31:
5898 return Error(Loc,
"immediate must be an integer in range [0, 31].");
5899 case Match_InvalidImm0_63:
5900 return Error(Loc,
"immediate must be an integer in range [0, 63].");
5901 case Match_InvalidImm0_127:
5902 return Error(Loc,
"immediate must be an integer in range [0, 127].");
5903 case Match_InvalidImm0_255:
5904 return Error(Loc,
"immediate must be an integer in range [0, 255].");
5905 case Match_InvalidImm0_65535:
5906 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
5907 case Match_InvalidImm1_8:
5908 return Error(Loc,
"immediate must be an integer in range [1, 8].");
5909 case Match_InvalidImm1_16:
5910 return Error(Loc,
"immediate must be an integer in range [1, 16].");
5911 case Match_InvalidImm1_32:
5912 return Error(Loc,
"immediate must be an integer in range [1, 32].");
5913 case Match_InvalidImm1_64:
5914 return Error(Loc,
"immediate must be an integer in range [1, 64].");
5915 case Match_InvalidMemoryIndexedRange2UImm0:
5916 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
5917 case Match_InvalidMemoryIndexedRange2UImm1:
5918 return Error(Loc,
"vector select offset must be an immediate range of the "
5919 "form <immf>:<imml>, where the first "
5920 "immediate is a multiple of 2 in the range [0, 2], and "
5921 "the second immediate is immf + 1.");
5922 case Match_InvalidMemoryIndexedRange2UImm2:
5923 case Match_InvalidMemoryIndexedRange2UImm3:
5926 "vector select offset must be an immediate range of the form "
5928 "where the first immediate is a multiple of 2 in the range [0, 6] or "
5930 "depending on the instruction, and the second immediate is immf + 1.");
5931 case Match_InvalidMemoryIndexedRange4UImm0:
5932 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
5933 case Match_InvalidMemoryIndexedRange4UImm1:
5934 case Match_InvalidMemoryIndexedRange4UImm2:
5937 "vector select offset must be an immediate range of the form "
5939 "where the first immediate is a multiple of 4 in the range [0, 4] or "
5941 "depending on the instruction, and the second immediate is immf + 3.");
5942 case Match_InvalidSVEAddSubImm8:
5943 return Error(Loc,
"immediate must be an integer in range [0, 255]"
5944 " with a shift amount of 0");
5945 case Match_InvalidSVEAddSubImm16:
5946 case Match_InvalidSVEAddSubImm32:
5947 case Match_InvalidSVEAddSubImm64:
5948 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
5949 "multiple of 256 in range [256, 65280]");
5950 case Match_InvalidSVECpyImm8:
5951 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
5952 " with a shift amount of 0");
5953 case Match_InvalidSVECpyImm16:
5954 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5955 "multiple of 256 in range [-32768, 65280]");
5956 case Match_InvalidSVECpyImm32:
5957 case Match_InvalidSVECpyImm64:
5958 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5959 "multiple of 256 in range [-32768, 32512]");
5960 case Match_InvalidIndexRange0_0:
5961 return Error(Loc,
"expected lane specifier '[0]'");
5962 case Match_InvalidIndexRange1_1:
5963 return Error(Loc,
"expected lane specifier '[1]'");
5964 case Match_InvalidIndexRange0_15:
5965 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5966 case Match_InvalidIndexRange0_7:
5967 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5968 case Match_InvalidIndexRange0_3:
5969 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5970 case Match_InvalidIndexRange0_1:
5971 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
5972 case Match_InvalidSVEIndexRange0_63:
5973 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
5974 case Match_InvalidSVEIndexRange0_31:
5975 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
5976 case Match_InvalidSVEIndexRange0_15:
5977 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5978 case Match_InvalidSVEIndexRange0_7:
5979 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5980 case Match_InvalidSVEIndexRange0_3:
5981 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5982 case Match_InvalidLabel:
5983 return Error(Loc,
"expected label or encodable integer pc offset");
5985 return Error(Loc,
"expected readable system register");
5987 case Match_InvalidSVCR:
5988 return Error(Loc,
"expected writable system register or pstate");
5989 case Match_InvalidComplexRotationEven:
5990 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
5991 case Match_InvalidComplexRotationOdd:
5992 return Error(Loc,
"complex rotation must be 90 or 270.");
5993 case Match_MnemonicFail: {
5995 ((AArch64Operand &)*
Operands[0]).getToken(),
5996 ComputeAvailableFeatures(STI->getFeatureBits()));
5997 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
5999 case Match_InvalidGPR64shifted8:
6000 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6001 case Match_InvalidGPR64shifted16:
6002 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6003 case Match_InvalidGPR64shifted32:
6004 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6005 case Match_InvalidGPR64shifted64:
6006 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6007 case Match_InvalidGPR64shifted128:
6009 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6010 case Match_InvalidGPR64NoXZRshifted8:
6011 return Error(Loc,
"register must be x0..x30 without shift");
6012 case Match_InvalidGPR64NoXZRshifted16:
6013 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6014 case Match_InvalidGPR64NoXZRshifted32:
6015 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6016 case Match_InvalidGPR64NoXZRshifted64:
6017 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6018 case Match_InvalidGPR64NoXZRshifted128:
6019 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6020 case Match_InvalidZPR32UXTW8:
6021 case Match_InvalidZPR32SXTW8:
6022 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6023 case Match_InvalidZPR32UXTW16:
6024 case Match_InvalidZPR32SXTW16:
6025 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6026 case Match_InvalidZPR32UXTW32:
6027 case Match_InvalidZPR32SXTW32:
6028 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6029 case Match_InvalidZPR32UXTW64:
6030 case Match_InvalidZPR32SXTW64:
6031 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6032 case Match_InvalidZPR64UXTW8:
6033 case Match_InvalidZPR64SXTW8:
6034 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6035 case Match_InvalidZPR64UXTW16:
6036 case Match_InvalidZPR64SXTW16:
6037 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6038 case Match_InvalidZPR64UXTW32:
6039 case Match_InvalidZPR64SXTW32:
6040 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6041 case Match_InvalidZPR64UXTW64:
6042 case Match_InvalidZPR64SXTW64:
6043 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6044 case Match_InvalidZPR32LSL8:
6045 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6046 case Match_InvalidZPR32LSL16:
6047 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6048 case Match_InvalidZPR32LSL32:
6049 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6050 case Match_InvalidZPR32LSL64:
6051 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6052 case Match_InvalidZPR64LSL8:
6053 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6054 case Match_InvalidZPR64LSL16:
6055 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6056 case Match_InvalidZPR64LSL32:
6057 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6058 case Match_InvalidZPR64LSL64:
6059 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6060 case Match_InvalidZPR0:
6061 return Error(Loc,
"expected register without element width suffix");
6062 case Match_InvalidZPR8:
6063 case Match_InvalidZPR16:
6064 case Match_InvalidZPR32:
6065 case Match_InvalidZPR64:
6066 case Match_InvalidZPR128:
6067 return Error(Loc,
"invalid element width");
6068 case Match_InvalidZPR_3b8:
6069 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6070 case Match_InvalidZPR_3b16:
6071 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6072 case Match_InvalidZPR_3b32:
6073 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6074 case Match_InvalidZPR_4b8:
6076 "Invalid restricted vector register, expected z0.b..z15.b");
6077 case Match_InvalidZPR_4b16:
6078 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6079 case Match_InvalidZPR_4b32:
6080 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6081 case Match_InvalidZPR_4b64:
6082 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6083 case Match_InvalidSVEPattern:
6084 return Error(Loc,
"invalid predicate pattern");
6085 case Match_InvalidSVEPPRorPNRAnyReg:
6086 case Match_InvalidSVEPPRorPNRBReg:
6087 case Match_InvalidSVEPredicateAnyReg:
6088 case Match_InvalidSVEPredicateBReg:
6089 case Match_InvalidSVEPredicateHReg:
6090 case Match_InvalidSVEPredicateSReg:
6091 case Match_InvalidSVEPredicateDReg:
6092 return Error(Loc,
"invalid predicate register.");
6093 case Match_InvalidSVEPredicate3bAnyReg:
6094 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6095 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6096 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6097 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6098 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6099 return Error(Loc,
"Invalid predicate register, expected PN in range "
6100 "pn8..pn15 with element suffix.");
6101 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6102 return Error(Loc,
"invalid restricted predicate-as-counter register "
6103 "expected pn8..pn15");
6104 case Match_InvalidSVEPNPredicateBReg:
6105 case Match_InvalidSVEPNPredicateHReg:
6106 case Match_InvalidSVEPNPredicateSReg:
6107 case Match_InvalidSVEPNPredicateDReg:
6108 return Error(Loc,
"Invalid predicate register, expected PN in range "
6109 "pn0..pn15 with element suffix.");
6110 case Match_InvalidSVEVecLenSpecifier:
6111 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6112 case Match_InvalidSVEPredicateListMul2x8:
6113 case Match_InvalidSVEPredicateListMul2x16:
6114 case Match_InvalidSVEPredicateListMul2x32:
6115 case Match_InvalidSVEPredicateListMul2x64:
6116 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6117 "predicate registers, where the first vector is a multiple of 2 "
6118 "and with correct element type");
6119 case Match_InvalidSVEExactFPImmOperandHalfOne:
6120 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6121 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6122 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6123 case Match_InvalidSVEExactFPImmOperandZeroOne:
6124 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6125 case Match_InvalidMatrixTileVectorH8:
6126 case Match_InvalidMatrixTileVectorV8:
6127 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6128 case Match_InvalidMatrixTileVectorH16:
6129 case Match_InvalidMatrixTileVectorV16:
6131 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6132 case Match_InvalidMatrixTileVectorH32:
6133 case Match_InvalidMatrixTileVectorV32:
6135 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6136 case Match_InvalidMatrixTileVectorH64:
6137 case Match_InvalidMatrixTileVectorV64:
6139 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6140 case Match_InvalidMatrixTileVectorH128:
6141 case Match_InvalidMatrixTileVectorV128:
6143 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6144 case Match_InvalidMatrixTile32:
6145 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6146 case Match_InvalidMatrixTile64:
6147 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6148 case Match_InvalidMatrix:
6149 return Error(Loc,
"invalid matrix operand, expected za");
6150 case Match_InvalidMatrix8:
6151 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6152 case Match_InvalidMatrix16:
6153 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6154 case Match_InvalidMatrix32:
6155 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6156 case Match_InvalidMatrix64:
6157 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6158 case Match_InvalidMatrixIndexGPR32_12_15:
6159 return Error(Loc,
"operand must be a register in range [w12, w15]");
6160 case Match_InvalidMatrixIndexGPR32_8_11:
6161 return Error(Loc,
"operand must be a register in range [w8, w11]");
6162 case Match_InvalidSVEVectorListMul2x8:
6163 case Match_InvalidSVEVectorListMul2x16:
6164 case Match_InvalidSVEVectorListMul2x32:
6165 case Match_InvalidSVEVectorListMul2x64:
6166 case Match_InvalidSVEVectorListMul2x128:
6167 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6168 "SVE vectors, where the first vector is a multiple of 2 "
6169 "and with matching element types");
6170 case Match_InvalidSVEVectorListMul4x8:
6171 case Match_InvalidSVEVectorListMul4x16:
6172 case Match_InvalidSVEVectorListMul4x32:
6173 case Match_InvalidSVEVectorListMul4x64:
6174 case Match_InvalidSVEVectorListMul4x128:
6175 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6176 "SVE vectors, where the first vector is a multiple of 4 "
6177 "and with matching element types");
6178 case Match_InvalidLookupTable:
6179 return Error(Loc,
"Invalid lookup table, expected zt0");
6180 case Match_InvalidSVEVectorListStrided2x8:
6181 case Match_InvalidSVEVectorListStrided2x16:
6182 case Match_InvalidSVEVectorListStrided2x32:
6183 case Match_InvalidSVEVectorListStrided2x64:
6186 "Invalid vector list, expected list with each SVE vector in the list "
6187 "8 registers apart, and the first register in the range [z0, z7] or "
6188 "[z16, z23] and with correct element type");
6189 case Match_InvalidSVEVectorListStrided4x8:
6190 case Match_InvalidSVEVectorListStrided4x16:
6191 case Match_InvalidSVEVectorListStrided4x32:
6192 case Match_InvalidSVEVectorListStrided4x64:
6195 "Invalid vector list, expected list with each SVE vector in the list "
6196 "4 registers apart, and the first register in the range [z0, z3] or "
6197 "[z16, z19] and with correct element type");
6198 case Match_AddSubLSLImm3ShiftLarge:
6200 "expected 'lsl' with optional integer in range [0, 7]");
6208bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6212 bool MatchingInlineAsm) {
6214 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6215 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6218 unsigned NumOperands =
Operands.size();
6220 if (NumOperands == 4 && Tok ==
"lsl") {
6221 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6222 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6223 if (Op2.isScalarReg() && Op3.isImm()) {
6224 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6229 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6231 NewOp3Val = (32 - Op3Val) & 0x1f;
6232 NewOp4Val = 31 - Op3Val;
6234 NewOp3Val = (64 - Op3Val) & 0x3f;
6235 NewOp4Val = 63 - Op3Val;
6242 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6243 Operands.push_back(AArch64Operand::CreateImm(
6244 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6245 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6246 Op3.getEndLoc(), getContext());
6249 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6251 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6252 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6253 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6255 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6256 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6257 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6259 if (LSBCE && WidthCE) {
6264 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6270 if (LSB >= RegWidth)
6271 return Error(LSBOp.getStartLoc(),
6272 "expected integer in range [0, 31]");
6273 if (Width < 1 || Width > RegWidth)
6274 return Error(WidthOp.getStartLoc(),
6275 "expected integer in range [1, 32]");
6279 ImmR = (32 - LSB) & 0x1f;
6281 ImmR = (64 - LSB) & 0x3f;
6285 if (ImmR != 0 && ImmS >= ImmR)
6286 return Error(WidthOp.getStartLoc(),
6287 "requested insert overflows register");
6292 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6293 Operands[2] = AArch64Operand::CreateReg(
6294 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6296 Operands[3] = AArch64Operand::CreateImm(
6297 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6299 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6300 WidthOp.getEndLoc(), getContext()));
6303 }
else if (NumOperands == 5) {
6306 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6307 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6308 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6309 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6311 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6312 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6313 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6315 if (Op3CE && Op4CE) {
6320 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6326 if (Op3Val >= RegWidth)
6327 return Error(Op3.getStartLoc(),
6328 "expected integer in range [0, 31]");
6329 if (Op4Val < 1 || Op4Val > RegWidth)
6330 return Error(Op4.getStartLoc(),
6331 "expected integer in range [1, 32]");
6335 NewOp3Val = (32 - Op3Val) & 0x1f;
6337 NewOp3Val = (64 - Op3Val) & 0x3f;
6341 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6342 return Error(Op4.getStartLoc(),
6343 "requested insert overflows register");
6349 Operands[3] = AArch64Operand::CreateImm(
6350 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6351 Operands[4] = AArch64Operand::CreateImm(
6352 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6354 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6356 else if (Tok ==
"sbfiz")
6357 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6359 else if (Tok ==
"ubfiz")
6360 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6369 }
else if (NumOperands == 5 &&
6370 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6371 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6372 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6373 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6375 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6376 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6377 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6379 if (Op3CE && Op4CE) {
6384 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6390 if (Op3Val >= RegWidth)
6391 return Error(Op3.getStartLoc(),
6392 "expected integer in range [0, 31]");
6393 if (Op4Val < 1 || Op4Val > RegWidth)
6394 return Error(Op4.getStartLoc(),
6395 "expected integer in range [1, 32]");
6397 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6399 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6400 return Error(Op4.getStartLoc(),
6401 "requested extract overflows register");
6405 Operands[4] = AArch64Operand::CreateImm(
6406 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6408 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6410 else if (Tok ==
"sbfx")
6411 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6413 else if (Tok ==
"ubfx")
6414 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6427 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6428 NumOperands == 4 && Tok ==
"movi") {
6429 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6430 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6431 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6432 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6433 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6434 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6435 if (Suffix.
lower() ==
".2d" &&
6436 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6437 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6438 " correctly on this CPU, converting to equivalent movi.16b");
6440 unsigned Idx = Op1.isToken() ? 1 : 2;
6442 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6450 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6453 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6454 if (
Op.isScalarReg()) {
6456 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6457 Op.getStartLoc(),
Op.getEndLoc(),
6462 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6463 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6464 if (
Op.isScalarReg() &&
6465 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6469 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6470 if (
Op.isScalarReg()) {
6472 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6474 Op.getEndLoc(), getContext());
6479 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6480 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6481 if (
Op.isScalarReg() &&
6482 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6486 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6487 if (
Op.isScalarReg()) {
6489 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6491 Op.getEndLoc(), getContext());
6500 unsigned MatchResult =
6502 MatchingInlineAsm, 1);
6506 if (MatchResult != Match_Success) {
6509 auto ShortFormNEONErrorInfo =
ErrorInfo;
6510 auto ShortFormNEONMatchResult = MatchResult;
6511 auto ShortFormNEONMissingFeatures = MissingFeatures;
6515 MatchingInlineAsm, 0);
6520 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6522 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6523 MatchResult = ShortFormNEONMatchResult;
6525 MissingFeatures = ShortFormNEONMissingFeatures;
6529 switch (MatchResult) {
6530 case Match_Success: {
6534 for (
unsigned i = 1; i < NumOperands; ++i)
6536 if (validateInstruction(Inst, IDLoc, OperandLocs))
6543 case Match_MissingFeature: {
6544 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6547 std::string Msg =
"instruction requires:";
6548 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6549 if (MissingFeatures[i]) {
6554 return Error(IDLoc, Msg);
6556 case Match_MnemonicFail:
6558 case Match_InvalidOperand: {
6559 SMLoc ErrorLoc = IDLoc;
6563 return Error(IDLoc,
"too few operands for instruction",
6564 SMRange(IDLoc, getTok().getLoc()));
6567 if (ErrorLoc ==
SMLoc())
6574 MatchResult = Match_InvalidSuffix;
6578 case Match_InvalidTiedOperand:
6579 case Match_InvalidMemoryIndexed1:
6580 case Match_InvalidMemoryIndexed2:
6581 case Match_InvalidMemoryIndexed4:
6582 case Match_InvalidMemoryIndexed8:
6583 case Match_InvalidMemoryIndexed16:
6584 case Match_InvalidCondCode:
6585 case Match_AddSubLSLImm3ShiftLarge:
6586 case Match_AddSubRegExtendSmall:
6587 case Match_AddSubRegExtendLarge:
6588 case Match_AddSubSecondSource:
6589 case Match_LogicalSecondSource:
6590 case Match_AddSubRegShift32:
6591 case Match_AddSubRegShift64:
6592 case Match_InvalidMovImm32Shift:
6593 case Match_InvalidMovImm64Shift:
6594 case Match_InvalidFPImm:
6595 case Match_InvalidMemoryWExtend8:
6596 case Match_InvalidMemoryWExtend16:
6597 case Match_InvalidMemoryWExtend32:
6598 case Match_InvalidMemoryWExtend64:
6599 case Match_InvalidMemoryWExtend128:
6600 case Match_InvalidMemoryXExtend8:
6601 case Match_InvalidMemoryXExtend16:
6602 case Match_InvalidMemoryXExtend32:
6603 case Match_InvalidMemoryXExtend64:
6604 case Match_InvalidMemoryXExtend128:
6605 case Match_InvalidMemoryIndexed1SImm4:
6606 case Match_InvalidMemoryIndexed2SImm4:
6607 case Match_InvalidMemoryIndexed3SImm4:
6608 case Match_InvalidMemoryIndexed4SImm4:
6609 case Match_InvalidMemoryIndexed1SImm6:
6610 case Match_InvalidMemoryIndexed16SImm4:
6611 case Match_InvalidMemoryIndexed32SImm4:
6612 case Match_InvalidMemoryIndexed4SImm7:
6613 case Match_InvalidMemoryIndexed8SImm7:
6614 case Match_InvalidMemoryIndexed16SImm7:
6615 case Match_InvalidMemoryIndexed8UImm5:
6616 case Match_InvalidMemoryIndexed8UImm3:
6617 case Match_InvalidMemoryIndexed4UImm5:
6618 case Match_InvalidMemoryIndexed2UImm5:
6619 case Match_InvalidMemoryIndexed1UImm6:
6620 case Match_InvalidMemoryIndexed2UImm6:
6621 case Match_InvalidMemoryIndexed4UImm6:
6622 case Match_InvalidMemoryIndexed8UImm6:
6623 case Match_InvalidMemoryIndexed16UImm6:
6624 case Match_InvalidMemoryIndexedSImm6:
6625 case Match_InvalidMemoryIndexedSImm5:
6626 case Match_InvalidMemoryIndexedSImm8:
6627 case Match_InvalidMemoryIndexedSImm9:
6628 case Match_InvalidMemoryIndexed16SImm9:
6629 case Match_InvalidMemoryIndexed8SImm10:
6630 case Match_InvalidImm0_0:
6631 case Match_InvalidImm0_1:
6632 case Match_InvalidImm0_3:
6633 case Match_InvalidImm0_7:
6634 case Match_InvalidImm0_15:
6635 case Match_InvalidImm0_31:
6636 case Match_InvalidImm0_63:
6637 case Match_InvalidImm0_127:
6638 case Match_InvalidImm0_255:
6639 case Match_InvalidImm0_65535:
6640 case Match_InvalidImm1_8:
6641 case Match_InvalidImm1_16:
6642 case Match_InvalidImm1_32:
6643 case Match_InvalidImm1_64:
6644 case Match_InvalidMemoryIndexedRange2UImm0:
6645 case Match_InvalidMemoryIndexedRange2UImm1:
6646 case Match_InvalidMemoryIndexedRange2UImm2:
6647 case Match_InvalidMemoryIndexedRange2UImm3:
6648 case Match_InvalidMemoryIndexedRange4UImm0:
6649 case Match_InvalidMemoryIndexedRange4UImm1:
6650 case Match_InvalidMemoryIndexedRange4UImm2:
6651 case Match_InvalidSVEAddSubImm8:
6652 case Match_InvalidSVEAddSubImm16:
6653 case Match_InvalidSVEAddSubImm32:
6654 case Match_InvalidSVEAddSubImm64:
6655 case Match_InvalidSVECpyImm8:
6656 case Match_InvalidSVECpyImm16:
6657 case Match_InvalidSVECpyImm32:
6658 case Match_InvalidSVECpyImm64:
6659 case Match_InvalidIndexRange0_0:
6660 case Match_InvalidIndexRange1_1:
6661 case Match_InvalidIndexRange0_15:
6662 case Match_InvalidIndexRange0_7:
6663 case Match_InvalidIndexRange0_3:
6664 case Match_InvalidIndexRange0_1:
6665 case Match_InvalidSVEIndexRange0_63:
6666 case Match_InvalidSVEIndexRange0_31:
6667 case Match_InvalidSVEIndexRange0_15:
6668 case Match_InvalidSVEIndexRange0_7:
6669 case Match_InvalidSVEIndexRange0_3:
6670 case Match_InvalidLabel:
6671 case Match_InvalidComplexRotationEven:
6672 case Match_InvalidComplexRotationOdd:
6673 case Match_InvalidGPR64shifted8:
6674 case Match_InvalidGPR64shifted16:
6675 case Match_InvalidGPR64shifted32:
6676 case Match_InvalidGPR64shifted64:
6677 case Match_InvalidGPR64shifted128:
6678 case Match_InvalidGPR64NoXZRshifted8:
6679 case Match_InvalidGPR64NoXZRshifted16:
6680 case Match_InvalidGPR64NoXZRshifted32:
6681 case Match_InvalidGPR64NoXZRshifted64:
6682 case Match_InvalidGPR64NoXZRshifted128:
6683 case Match_InvalidZPR32UXTW8:
6684 case Match_InvalidZPR32UXTW16:
6685 case Match_InvalidZPR32UXTW32:
6686 case Match_InvalidZPR32UXTW64:
6687 case Match_InvalidZPR32SXTW8:
6688 case Match_InvalidZPR32SXTW16:
6689 case Match_InvalidZPR32SXTW32:
6690 case Match_InvalidZPR32SXTW64:
6691 case Match_InvalidZPR64UXTW8:
6692 case Match_InvalidZPR64SXTW8:
6693 case Match_InvalidZPR64UXTW16:
6694 case Match_InvalidZPR64SXTW16:
6695 case Match_InvalidZPR64UXTW32:
6696 case Match_InvalidZPR64SXTW32:
6697 case Match_InvalidZPR64UXTW64:
6698 case Match_InvalidZPR64SXTW64:
6699 case Match_InvalidZPR32LSL8:
6700 case Match_InvalidZPR32LSL16:
6701 case Match_InvalidZPR32LSL32:
6702 case Match_InvalidZPR32LSL64:
6703 case Match_InvalidZPR64LSL8:
6704 case Match_InvalidZPR64LSL16:
6705 case Match_InvalidZPR64LSL32:
6706 case Match_InvalidZPR64LSL64:
6707 case Match_InvalidZPR0:
6708 case Match_InvalidZPR8:
6709 case Match_InvalidZPR16:
6710 case Match_InvalidZPR32:
6711 case Match_InvalidZPR64:
6712 case Match_InvalidZPR128:
6713 case Match_InvalidZPR_3b8:
6714 case Match_InvalidZPR_3b16:
6715 case Match_InvalidZPR_3b32:
6716 case Match_InvalidZPR_4b8:
6717 case Match_InvalidZPR_4b16:
6718 case Match_InvalidZPR_4b32:
6719 case Match_InvalidZPR_4b64:
6720 case Match_InvalidSVEPPRorPNRAnyReg:
6721 case Match_InvalidSVEPPRorPNRBReg:
6722 case Match_InvalidSVEPredicateAnyReg:
6723 case Match_InvalidSVEPattern:
6724 case Match_InvalidSVEVecLenSpecifier:
6725 case Match_InvalidSVEPredicateBReg:
6726 case Match_InvalidSVEPredicateHReg:
6727 case Match_InvalidSVEPredicateSReg:
6728 case Match_InvalidSVEPredicateDReg:
6729 case Match_InvalidSVEPredicate3bAnyReg:
6730 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6731 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6732 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6733 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6734 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6735 case Match_InvalidSVEPNPredicateBReg:
6736 case Match_InvalidSVEPNPredicateHReg:
6737 case Match_InvalidSVEPNPredicateSReg:
6738 case Match_InvalidSVEPNPredicateDReg:
6739 case Match_InvalidSVEPredicateListMul2x8:
6740 case Match_InvalidSVEPredicateListMul2x16:
6741 case Match_InvalidSVEPredicateListMul2x32:
6742 case Match_InvalidSVEPredicateListMul2x64:
6743 case Match_InvalidSVEExactFPImmOperandHalfOne:
6744 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6745 case Match_InvalidSVEExactFPImmOperandZeroOne:
6746 case Match_InvalidMatrixTile32:
6747 case Match_InvalidMatrixTile64:
6748 case Match_InvalidMatrix:
6749 case Match_InvalidMatrix8:
6750 case Match_InvalidMatrix16:
6751 case Match_InvalidMatrix32:
6752 case Match_InvalidMatrix64:
6753 case Match_InvalidMatrixTileVectorH8:
6754 case Match_InvalidMatrixTileVectorH16:
6755 case Match_InvalidMatrixTileVectorH32:
6756 case Match_InvalidMatrixTileVectorH64:
6757 case Match_InvalidMatrixTileVectorH128:
6758 case Match_InvalidMatrixTileVectorV8:
6759 case Match_InvalidMatrixTileVectorV16:
6760 case Match_InvalidMatrixTileVectorV32:
6761 case Match_InvalidMatrixTileVectorV64:
6762 case Match_InvalidMatrixTileVectorV128:
6763 case Match_InvalidSVCR:
6764 case Match_InvalidMatrixIndexGPR32_12_15:
6765 case Match_InvalidMatrixIndexGPR32_8_11:
6766 case Match_InvalidLookupTable:
6767 case Match_InvalidSVEVectorListMul2x8:
6768 case Match_InvalidSVEVectorListMul2x16:
6769 case Match_InvalidSVEVectorListMul2x32:
6770 case Match_InvalidSVEVectorListMul2x64:
6771 case Match_InvalidSVEVectorListMul2x128:
6772 case Match_InvalidSVEVectorListMul4x8:
6773 case Match_InvalidSVEVectorListMul4x16:
6774 case Match_InvalidSVEVectorListMul4x32:
6775 case Match_InvalidSVEVectorListMul4x64:
6776 case Match_InvalidSVEVectorListMul4x128:
6777 case Match_InvalidSVEVectorListStrided2x8:
6778 case Match_InvalidSVEVectorListStrided2x16:
6779 case Match_InvalidSVEVectorListStrided2x32:
6780 case Match_InvalidSVEVectorListStrided2x64:
6781 case Match_InvalidSVEVectorListStrided4x8:
6782 case Match_InvalidSVEVectorListStrided4x16:
6783 case Match_InvalidSVEVectorListStrided4x32:
6784 case Match_InvalidSVEVectorListStrided4x64:
6788 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6792 if (ErrorLoc ==
SMLoc())
6802bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6809 if (IDVal ==
".arch")
6810 parseDirectiveArch(Loc);
6811 else if (IDVal ==
".cpu")
6812 parseDirectiveCPU(Loc);
6813 else if (IDVal ==
".tlsdesccall")
6814 parseDirectiveTLSDescCall(Loc);
6815 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6816 parseDirectiveLtorg(Loc);
6817 else if (IDVal ==
".unreq")
6818 parseDirectiveUnreq(Loc);
6819 else if (IDVal ==
".inst")
6820 parseDirectiveInst(Loc);
6821 else if (IDVal ==
".cfi_negate_ra_state")
6822 parseDirectiveCFINegateRAState();
6823 else if (IDVal ==
".cfi_b_key_frame")
6824 parseDirectiveCFIBKeyFrame();
6825 else if (IDVal ==
".cfi_mte_tagged_frame")
6826 parseDirectiveCFIMTETaggedFrame();
6827 else if (IDVal ==
".arch_extension")
6828 parseDirectiveArchExtension(Loc);
6829 else if (IDVal ==
".variant_pcs")
6830 parseDirectiveVariantPCS(Loc);
6833 parseDirectiveLOH(IDVal, Loc);
6836 }
else if (IsCOFF) {
6837 if (IDVal ==
".seh_stackalloc")
6838 parseDirectiveSEHAllocStack(Loc);
6839 else if (IDVal ==
".seh_endprologue")
6840 parseDirectiveSEHPrologEnd(Loc);
6841 else if (IDVal ==
".seh_save_r19r20_x")
6842 parseDirectiveSEHSaveR19R20X(Loc);
6843 else if (IDVal ==
".seh_save_fplr")
6844 parseDirectiveSEHSaveFPLR(Loc);
6845 else if (IDVal ==
".seh_save_fplr_x")
6846 parseDirectiveSEHSaveFPLRX(Loc);
6847 else if (IDVal ==
".seh_save_reg")
6848 parseDirectiveSEHSaveReg(Loc);
6849 else if (IDVal ==
".seh_save_reg_x")
6850 parseDirectiveSEHSaveRegX(Loc);
6851 else if (IDVal ==
".seh_save_regp")
6852 parseDirectiveSEHSaveRegP(Loc);
6853 else if (IDVal ==
".seh_save_regp_x")
6854 parseDirectiveSEHSaveRegPX(Loc);
6855 else if (IDVal ==
".seh_save_lrpair")
6856 parseDirectiveSEHSaveLRPair(Loc);
6857 else if (IDVal ==
".seh_save_freg")
6858 parseDirectiveSEHSaveFReg(Loc);
6859 else if (IDVal ==
".seh_save_freg_x")
6860 parseDirectiveSEHSaveFRegX(Loc);
6861 else if (IDVal ==
".seh_save_fregp")
6862 parseDirectiveSEHSaveFRegP(Loc);
6863 else if (IDVal ==
".seh_save_fregp_x")
6864 parseDirectiveSEHSaveFRegPX(Loc);
6865 else if (IDVal ==
".seh_set_fp")
6866 parseDirectiveSEHSetFP(Loc);
6867 else if (IDVal ==
".seh_add_fp")
6868 parseDirectiveSEHAddFP(Loc);
6869 else if (IDVal ==
".seh_nop")
6870 parseDirectiveSEHNop(Loc);
6871 else if (IDVal ==
".seh_save_next")
6872 parseDirectiveSEHSaveNext(Loc);
6873 else if (IDVal ==
".seh_startepilogue")
6874 parseDirectiveSEHEpilogStart(Loc);
6875 else if (IDVal ==
".seh_endepilogue")
6876 parseDirectiveSEHEpilogEnd(Loc);
6877 else if (IDVal ==
".seh_trap_frame")
6878 parseDirectiveSEHTrapFrame(Loc);
6879 else if (IDVal ==
".seh_pushframe")
6880 parseDirectiveSEHMachineFrame(Loc);
6881 else if (IDVal ==
".seh_context")
6882 parseDirectiveSEHContext(Loc);
6883 else if (IDVal ==
".seh_ec_context")
6884 parseDirectiveSEHECContext(Loc);
6885 else if (IDVal ==
".seh_clear_unwound_to_call")
6886 parseDirectiveSEHClearUnwoundToCall(Loc);
6887 else if (IDVal ==
".seh_pac_sign_lr")
6888 parseDirectiveSEHPACSignLR(Loc);
6889 else if (IDVal ==
".seh_save_any_reg")
6890 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
6891 else if (IDVal ==
".seh_save_any_reg_p")
6892 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
6893 else if (IDVal ==
".seh_save_any_reg_x")
6894 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
6895 else if (IDVal ==
".seh_save_any_reg_px")
6896 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
6909 if (!NoCrypto && Crypto) {
6912 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
6913 ArchInfo == AArch64::ARMV8_3A) {
6917 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
6918 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
6919 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
6920 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
6921 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
6922 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
6928 }
else if (NoCrypto) {
6931 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
6932 ArchInfo == AArch64::ARMV8_3A) {
6933 RequestedExtensions.
push_back(
"nosha2");
6936 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
6937 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
6938 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
6939 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
6940 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
6941 ArchInfo == AArch64::ARMV9_4A) {
6943 RequestedExtensions.
push_back(
"nosha3");
6944 RequestedExtensions.
push_back(
"nosha2");
6952bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
6953 SMLoc ArchLoc = getLoc();
6956 std::tie(Arch, ExtensionString) =
6957 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6961 return Error(ArchLoc,
"unknown arch name");
6967 std::vector<StringRef> AArch64Features;
6972 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6974 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
6977 if (!ExtensionString.
empty())
6978 ExtensionString.
split(RequestedExtensions,
'+');
6983 setAvailableFeatures(ComputeAvailableFeatures(Features));
6984 for (
auto Name : RequestedExtensions) {
6985 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
6998 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7007bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7008 SMLoc ExtLoc = getLoc();
7010 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7015 bool EnableFeature =
true;
7016 if (
Name.starts_with_insensitive(
"no")) {
7017 EnableFeature =
false;
7028 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7034 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7038 return Error(ExtLoc,
"unknown architectural extension: " +
Name);
7047bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7048 SMLoc CurLoc = getLoc();
7051 std::tie(CPU, ExtensionString) =
7052 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7058 if (!ExtensionString.
empty())
7059 ExtensionString.
split(RequestedExtensions,
'+');
7063 Error(CurLoc,
"unknown CPU name");
7072 for (
auto Name : RequestedExtensions) {
7076 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7078 bool FoundExtension =
false;
7091 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7092 FoundExtension =
true;
7097 if (!FoundExtension)
7098 Error(CurLoc,
"unsupported architectural extension");
7107bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7109 return Error(Loc,
"expected expression following '.inst' directive");
7111 auto parseOp = [&]() ->
bool {
7113 const MCExpr *Expr =
nullptr;
7114 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7117 if (check(!
Value, L,
"expected constant expression"))
7119 getTargetStreamer().emitInst(
Value->getValue());
7123 return parseMany(parseOp);
7128bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7130 if (check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7142 getParser().getStreamer().emitInstruction(Inst, getSTI());
7148bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7152 return TokError(
"expected an identifier or a number in directive");
7155 int64_t
Id = getTok().getIntVal();
7157 return TokError(
"invalid numeric identifier in directive");
7166 return TokError(
"invalid identifier in directive");
7174 assert(NbArgs != -1 &&
"Invalid number of arguments");
7177 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7179 if (getParser().parseIdentifier(
Name))
7180 return TokError(
"expected identifier in directive");
7181 Args.push_back(getContext().getOrCreateSymbol(
Name));
7183 if (
Idx + 1 == NbArgs)
7191 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7197bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7200 getTargetStreamer().emitCurrentConstantPool();
7208 SMLoc SRegLoc = getLoc();
7209 RegKind RegisterKind = RegKind::Scalar;
7211 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7215 RegisterKind = RegKind::NeonVector;
7216 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7222 return Error(SRegLoc,
"vector register without type specifier expected");
7227 RegisterKind = RegKind::SVEDataVector;
7229 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7235 return Error(SRegLoc,
7236 "sve vector register without type specifier expected");
7241 RegisterKind = RegKind::SVEPredicateVector;
7242 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7248 return Error(SRegLoc,
7249 "sve predicate register without type specifier expected");
7253 return Error(SRegLoc,
"register name or alias expected");
7259 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7260 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7261 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7268bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7270 return TokError(
"unexpected input in .unreq directive.");
7271 RegisterReqs.
erase(getTok().getIdentifier().lower());
7276bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7279 getStreamer().emitCFINegateRAState();
7285bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7288 getStreamer().emitCFIBKeyFrame();
7294bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7297 getStreamer().emitCFIMTETaggedFrame();
7303bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7305 if (getParser().parseIdentifier(
Name))
7306 return TokError(
"expected symbol name");
7309 getTargetStreamer().emitDirectiveVariantPCS(
7310 getContext().getOrCreateSymbol(
Name));
7316bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7318 if (parseImmExpr(
Size))
7320 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7326bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7327 getTargetStreamer().emitARM64WinCFIPrologEnd();
7333bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7335 if (parseImmExpr(
Offset))
7337 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7343bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7345 if (parseImmExpr(
Offset))
7347 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7353bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7355 if (parseImmExpr(
Offset))
7357 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7363bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7366 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7367 parseComma() || parseImmExpr(
Offset))
7369 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7375bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7378 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7379 parseComma() || parseImmExpr(
Offset))
7381 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7387bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7390 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7391 parseComma() || parseImmExpr(
Offset))
7393 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7399bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7402 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7403 parseComma() || parseImmExpr(
Offset))
7405 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7411bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7415 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7416 parseComma() || parseImmExpr(
Offset))
7418 if (check(((Reg - 19) % 2 != 0), L,
7419 "expected register with even offset from x19"))
7421 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7427bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7430 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7431 parseComma() || parseImmExpr(
Offset))
7433 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7439bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7442 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7443 parseComma() || parseImmExpr(
Offset))
7445 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7451bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7454 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7455 parseComma() || parseImmExpr(
Offset))
7457 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7463bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7466 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7467 parseComma() || parseImmExpr(
Offset))
7469 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7475bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7476 getTargetStreamer().emitARM64WinCFISetFP();
7482bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7484 if (parseImmExpr(
Size))
7486 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7492bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7493 getTargetStreamer().emitARM64WinCFINop();
7499bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7500 getTargetStreamer().emitARM64WinCFISaveNext();
7506bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7507 getTargetStreamer().emitARM64WinCFIEpilogStart();
7513bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7514 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7520bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7521 getTargetStreamer().emitARM64WinCFITrapFrame();
7527bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7528 getTargetStreamer().emitARM64WinCFIMachineFrame();
7534bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7535 getTargetStreamer().emitARM64WinCFIContext();
7541bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7542 getTargetStreamer().emitARM64WinCFIECContext();
7548bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7549 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7555bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7556 getTargetStreamer().emitARM64WinCFIPACSignLR();
7565bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7570 if (check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7571 parseComma() || parseImmExpr(
Offset))
7574 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7575 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7576 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7577 return Error(L,
"invalid save_any_reg offset");
7578 unsigned EncodedReg;
7579 if (Reg == AArch64::FP)
7581 else if (Reg == AArch64::LR)
7584 EncodedReg =
Reg - AArch64::X0;
7586 if (Reg == AArch64::LR)
7587 return Error(Start,
"lr cannot be paired with another register");
7589 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7591 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7594 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7596 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7598 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7599 unsigned EncodedReg =
Reg - AArch64::D0;
7600 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7601 return Error(L,
"invalid save_any_reg offset");
7603 if (Reg == AArch64::D31)
7604 return Error(Start,
"d31 cannot be paired with another register");
7606 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7608 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7611 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7613 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7615 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7616 unsigned EncodedReg =
Reg - AArch64::Q0;
7618 return Error(L,
"invalid save_any_reg offset");
7620 if (Reg == AArch64::Q31)
7621 return Error(Start,
"q31 cannot be paired with another register");
7623 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7625 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7628 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7630 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7633 return Error(Start,
"save_any_reg register must be x, q or d register");
7638bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7640 if (!parseAuthExpr(Res, EndLoc))
7642 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7649bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7660 "combination of @AUTH with other modifiers not supported");
7683 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7705 return TokError(
"expected key name");
7710 return TokError(
"invalid key '" + KeyStr +
"'");
7717 return TokError(
"expected integer discriminator");
7720 if (!isUInt<16>(Discriminator))
7721 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7722 " out of range [0, 0xFFFF]");
7725 bool UseAddressDiversity =
false;
7730 return TokError(
"expected 'addr'");
7731 UseAddressDiversity =
true;
7740 UseAddressDiversity, Ctx);
7745AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7753 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7754 ELFRefKind = AE->getKind();
7755 Expr = AE->getSubExpr();
7761 DarwinRefKind = SE->
getKind();
7768 if (!Relocatable || Res.
getSymB())
7795#define GET_REGISTER_MATCHER
7796#define GET_SUBTARGET_FEATURE_NAME
7797#define GET_MATCHER_IMPLEMENTATION
7798#define GET_MNEMONIC_SPELL_CHECKER
7799#include "AArch64GenAsmMatcher.inc"
7805 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7807 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7809 return Match_InvalidOperand;
7812 return Match_InvalidOperand;
7813 if (CE->getValue() == ExpectedVal)
7814 return Match_Success;
7815 return Match_InvalidOperand;
7820 return Match_InvalidOperand;
7826 if (
Op.isTokenEqual(
"za"))
7827 return Match_Success;
7828 return Match_InvalidOperand;
7834#define MATCH_HASH(N) \
7835 case MCK__HASH_##N: \
7836 return MatchesOpImmediate(N);
7862#define MATCH_HASH_MINUS(N) \
7863 case MCK__HASH__MINUS_##N: \
7864 return MatchesOpImmediate(-N);
7868#undef MATCH_HASH_MINUS
7877 return Error(S,
"expected register");
7880 ParseStatus Res = tryParseScalarRegister(FirstReg);
7882 return Error(S,
"expected first even register of a consecutive same-size "
7883 "even/odd register pair");
7886 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
7888 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
7890 bool isXReg = XRegClass.
contains(FirstReg),
7891 isWReg = WRegClass.
contains(FirstReg);
7892 if (!isXReg && !isWReg)
7893 return Error(S,
"expected first even register of a consecutive same-size "
7894 "even/odd register pair");
7899 if (FirstEncoding & 0x1)
7900 return Error(S,
"expected first even register of a consecutive same-size "
7901 "even/odd register pair");
7904 return Error(getLoc(),
"expected comma");
7910 Res = tryParseScalarRegister(SecondReg);
7912 return Error(E,
"expected second odd register of a consecutive same-size "
7913 "even/odd register pair");
7916 (isXReg && !XRegClass.
contains(SecondReg)) ||
7917 (isWReg && !WRegClass.
contains(SecondReg)))
7918 return Error(E,
"expected second odd register of a consecutive same-size "
7919 "even/odd register pair");
7924 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
7927 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
7930 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
7931 getLoc(), getContext()));
7936template <
bool ParseShiftExtend,
bool ParseSuffix>
7938 const SMLoc S = getLoc();
7944 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7949 if (ParseSuffix &&
Kind.empty())
7956 unsigned ElementWidth = KindRes->second;
7960 Operands.push_back(AArch64Operand::CreateVectorReg(
7961 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
7974 Res = tryParseOptionalShiftExtend(ExtOpnd);
7978 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
7979 Operands.push_back(AArch64Operand::CreateVectorReg(
7980 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
7981 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
7982 Ext->hasShiftExtendAmount()));
8007 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8009 return TokError(
"invalid operand for instruction");
8014 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8025 SS, getLoc(), getContext()));
8036 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8047 SS, getLoc(), getContext()));
8056 if (!tryParseScalarRegister(XReg).isSuccess())
8062 XReg, AArch64::x8sub_0,
8063 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8066 "expected an even-numbered x-register in the range [x0,x22]");
8069 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8083 if (getParser().parseExpression(ImmF))
8093 SMLoc E = getTok().getLoc();
8095 if (getParser().parseExpression(ImmL))
8098 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8099 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8102 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S, E, getContext()));
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(unsigned ZReg, unsigned Reg)
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (#elements, element-width) if Suffix is a valid vector kind.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static unsigned matchMatrixRegName(StringRef Name)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static const struct Extension ExtensionMap[]
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live value
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static MSP430CC::CondCodes getCondCode(unsigned Cond)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx)
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Target independent representation for an assembler token.
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
void UnLex(AsmToken const &Token)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const 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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual 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 RegNo) const
Returns the encoding for RegNo.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc)
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
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)
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.
static unsigned getXRegFromWReg(unsigned Reg)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
MCLOHType
Linker Optimization Hint Type.
static unsigned getWRegFromXReg(unsigned Reg)
Target & getTheARM64Target()
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const FeatureBitset Features
A record for a potential prefetch made during the initial scan of the loop.
AArch64::ExtensionBitset DefaultExts
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
FeatureBitset FeaturesRequired