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 {
147 bool Predicated =
false;
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 {
"sve2", {AArch64::FeatureSVE2}},
3678 {
"sve2-aes", {AArch64::FeatureSVE2AES}},
3679 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3680 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3681 {
"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3682 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3683 {
"b16b16", {AArch64::FeatureB16B16}},
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 {
"hbc", {AArch64::FeatureHBC}},
3696 {
"mops", {AArch64::FeatureMOPS}},
3697 {
"mec", {AArch64::FeatureMEC}},
3698 {
"the", {AArch64::FeatureTHE}},
3699 {
"d128", {AArch64::FeatureD128}},
3700 {
"lse128", {AArch64::FeatureLSE128}},
3701 {
"ite", {AArch64::FeatureITE}},
3702 {
"cssc", {AArch64::FeatureCSSC}},
3703 {
"rcpc3", {AArch64::FeatureRCPC3}},
3704 {
"gcs", {AArch64::FeatureGCS}},
3705 {
"bf16", {AArch64::FeatureBF16}},
3706 {
"compnum", {AArch64::FeatureComplxNum}},
3707 {
"dotprod", {AArch64::FeatureDotProd}},
3708 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3709 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3710 {
"fp16", {AArch64::FeatureFullFP16}},
3711 {
"fp16fml", {AArch64::FeatureFP16FML}},
3712 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3713 {
"lor", {AArch64::FeatureLOR}},
3714 {
"profile", {AArch64::FeatureSPE}},
3718 {
"rdm", {AArch64::FeatureRDM}},
3719 {
"rdma", {AArch64::FeatureRDM}},
3720 {
"sb", {AArch64::FeatureSB}},
3721 {
"ssbs", {AArch64::FeatureSSBS}},
3722 {
"tme", {AArch64::FeatureTME}},
3723 {
"fp8", {AArch64::FeatureFP8}},
3724 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3725 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3726 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3727 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3728 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3729 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3730 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3731 {
"lut", {AArch64::FeatureLUT}},
3732 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3733 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3734 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3735 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3736 {
"cpa", {AArch64::FeatureCPA}},
3737 {
"tlbiw", {AArch64::FeatureTLBIW}},
3741 if (FBS[AArch64::HasV8_0aOps])
3743 if (FBS[AArch64::HasV8_1aOps])
3745 else if (FBS[AArch64::HasV8_2aOps])
3747 else if (FBS[AArch64::HasV8_3aOps])
3749 else if (FBS[AArch64::HasV8_4aOps])
3751 else if (FBS[AArch64::HasV8_5aOps])
3753 else if (FBS[AArch64::HasV8_6aOps])
3755 else if (FBS[AArch64::HasV8_7aOps])
3757 else if (FBS[AArch64::HasV8_8aOps])
3759 else if (FBS[AArch64::HasV8_9aOps])
3761 else if (FBS[AArch64::HasV9_0aOps])
3763 else if (FBS[AArch64::HasV9_1aOps])
3765 else if (FBS[AArch64::HasV9_2aOps])
3767 else if (FBS[AArch64::HasV9_3aOps])
3769 else if (FBS[AArch64::HasV9_4aOps])
3771 else if (FBS[AArch64::HasV9_5aOps])
3773 else if (FBS[AArch64::HasV8_0rOps])
3782 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3789 const uint16_t Cm = (Encoding & 0x78) >> 3;
3790 const uint16_t Cn = (Encoding & 0x780) >> 7;
3791 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3796 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3798 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3800 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3803 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3810 if (
Name.contains(
'.'))
3811 return TokError(
"invalid operand");
3814 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3820 if (Mnemonic ==
"ic") {
3823 return TokError(
"invalid operand for IC instruction");
3824 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3825 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3827 return TokError(Str);
3830 }
else if (Mnemonic ==
"dc") {
3833 return TokError(
"invalid operand for DC instruction");
3834 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3835 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3837 return TokError(Str);
3840 }
else if (Mnemonic ==
"at") {
3843 return TokError(
"invalid operand for AT instruction");
3844 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3845 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3847 return TokError(Str);
3850 }
else if (Mnemonic ==
"tlbi") {
3853 return TokError(
"invalid operand for TLBI instruction");
3854 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3855 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3857 return TokError(Str);
3860 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3862 if (
Op.lower() !=
"rctx")
3863 return TokError(
"invalid operand for prediction restriction instruction");
3865 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3866 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3867 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3869 if (Mnemonic ==
"cosp" && !hasSpecres2)
3870 return TokError(
"COSP requires: predres2");
3872 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3874 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3875 : Mnemonic ==
"dvp" ? 0b101
3876 : Mnemonic ==
"cosp" ? 0b110
3877 : Mnemonic ==
"cpp" ? 0b111
3880 "Invalid mnemonic for prediction restriction instruction");
3881 const auto SYS_3_7_3 = 0b01101110011;
3882 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3884 createSysAlias(Encoding,
Operands, S);
3889 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3890 bool HasRegister =
false;
3895 return TokError(
"expected register operand");
3899 if (ExpectRegister && !HasRegister)
3900 return TokError(
"specified " + Mnemonic +
" op requires a register");
3901 else if (!ExpectRegister && HasRegister)
3902 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3914 if (
Name.contains(
'.'))
3915 return TokError(
"invalid operand");
3919 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
3925 if (Mnemonic ==
"tlbip") {
3926 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
3927 if (HasnXSQualifier) {
3928 Op =
Op.drop_back(3);
3932 return TokError(
"invalid operand for TLBIP instruction");
3934 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
3941 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
3942 std::string Str(
"TLBIP " +
Name +
" requires: ");
3944 return TokError(Str);
3955 return TokError(
"expected register identifier");
3960 return TokError(
"specified " + Mnemonic +
3961 " op requires a pair of registers");
3974 return TokError(
"'csync' operand expected");
3978 SMLoc ExprLoc = getLoc();
3980 if (getParser().parseExpression(ImmVal))
3984 return Error(ExprLoc,
"immediate value expected for barrier operand");
3986 if (Mnemonic ==
"dsb" &&
Value > 15) {
3993 if (Value < 0 || Value > 15)
3994 return Error(ExprLoc,
"barrier operand out of range");
3995 auto DB = AArch64DB::lookupDBByEncoding(
Value);
3996 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
3997 ExprLoc, getContext(),
4003 return TokError(
"invalid operand for instruction");
4006 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4007 auto DB = AArch64DB::lookupDBByName(Operand);
4009 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4010 return TokError(
"'sy' or #imm operand expected");
4012 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4013 return TokError(
"'csync' operand expected");
4015 if (Mnemonic ==
"dsb") {
4020 return TokError(
"invalid barrier option name");
4023 Operands.push_back(AArch64Operand::CreateBarrier(
4024 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4025 getContext(),
false ));
4035 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4036 if (Mnemonic !=
"dsb")
4042 SMLoc ExprLoc = getLoc();
4043 if (getParser().parseExpression(ImmVal))
4047 return Error(ExprLoc,
"immediate value expected for barrier operand");
4052 return Error(ExprLoc,
"barrier operand out of range");
4053 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4054 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4055 ExprLoc, getContext(),
4061 return TokError(
"invalid operand for instruction");
4064 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4067 return TokError(
"invalid barrier option name");
4070 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4071 getContext(),
true ));
4083 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4088 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4089 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4090 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4094 unsigned PStateImm = -1;
4095 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4096 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4097 PStateImm = PState15->Encoding;
4099 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4100 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4101 PStateImm = PState1->Encoding;
4105 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4106 PStateImm, getContext()));
4121 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4129 unsigned ElementWidth = KindRes->second;
4131 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4132 S, getLoc(), getContext()));
4137 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4139 return tryParseVectorIndex(
Operands).isFailure();
4143 SMLoc SIdx = getLoc();
4146 if (getParser().parseExpression(ImmVal))
4150 return TokError(
"immediate value expected for vector index");
4157 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4170 RegKind MatchKind) {
4179 size_t Start = 0, Next =
Name.find(
'.');
4181 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4187 return TokError(
"invalid vector kind qualifier");
4198ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4201 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4203 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4208template <RegKind RK>
4212 const SMLoc S = getLoc();
4215 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4223 unsigned ElementWidth = KindRes->second;
4224 Operands.push_back(AArch64Operand::CreateVectorReg(
4225 RegNum, RK, ElementWidth, S,
4226 getLoc(), getContext()));
4229 if (RK == RegKind::SVEPredicateAsCounter) {
4236 if (parseOperand(
Operands,
false,
false))
4247 return Error(S,
"not expecting size suffix");
4250 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4255 auto Pred = getTok().getString().lower();
4256 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4257 return Error(getLoc(),
"expecting 'z' predication");
4259 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4260 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4263 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4264 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4273 if (!tryParseNeonVectorRegister(
Operands))
4276 if (tryParseZTOperand(
Operands).isSuccess())
4280 if (tryParseGPROperand<false>(
Operands).isSuccess())
4286bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4287 bool HasELFModifier =
false;
4291 HasELFModifier =
true;
4294 return TokError(
"expect relocation specifier in operand after ':'");
4296 std::string LowerCase = getTok().getIdentifier().lower();
4347 return TokError(
"expect relocation specifier in operand after ':'");
4351 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4355 if (getParser().parseExpression(ImmVal))
4368 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4371 size_t DotPosition =
Name.find(
'.');
4380 const std::optional<std::pair<int, int>> &KindRes =
4384 "Expected the register to be followed by element width suffix");
4385 ElementWidth = KindRes->second;
4392 auto LCurly = getTok();
4397 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4398 0, S, getLoc(), getContext()));
4403 if (getTok().getString().equals_insensitive(
"za")) {
4409 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4410 0xFF, S, getLoc(), getContext()));
4414 SMLoc TileLoc = getLoc();
4416 unsigned FirstReg, ElementWidth;
4417 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4418 if (!ParseRes.isSuccess()) {
4419 getLexer().UnLex(LCurly);
4425 unsigned PrevReg = FirstReg;
4428 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4431 SeenRegs.
insert(FirstReg);
4435 unsigned Reg, NextElementWidth;
4436 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4437 if (!ParseRes.isSuccess())
4441 if (ElementWidth != NextElementWidth)
4442 return Error(TileLoc,
"mismatched register size suffix");
4445 Warning(TileLoc,
"tile list not in ascending order");
4448 Warning(TileLoc,
"duplicate tile in list");
4451 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4460 unsigned RegMask = 0;
4461 for (
auto Reg : DRegs)
4465 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4470template <RegKind VectorKind>
4480 auto RegTok = getTok();
4481 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4482 if (ParseRes.isSuccess()) {
4489 RegTok.getString().equals_insensitive(
"zt0"))
4493 (ParseRes.isNoMatch() && NoMatchIsError &&
4494 !RegTok.getString().starts_with_insensitive(
"za")))
4495 return Error(Loc,
"vector register expected");
4500 int NumRegs = getNumRegsForRegKind(VectorKind);
4502 auto LCurly = getTok();
4507 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4511 if (ParseRes.isNoMatch())
4514 if (!ParseRes.isSuccess())
4517 int64_t PrevReg = FirstReg;
4522 SMLoc Loc = getLoc();
4526 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4527 if (!ParseRes.isSuccess())
4531 if (Kind != NextKind)
4532 return Error(Loc,
"mismatched register size suffix");
4535 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4537 if (Space == 0 || Space > 3)
4538 return Error(Loc,
"invalid number of vectors");
4543 bool HasCalculatedStride =
false;
4545 SMLoc Loc = getLoc();
4548 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4549 if (!ParseRes.isSuccess())
4553 if (Kind != NextKind)
4554 return Error(Loc,
"mismatched register size suffix");
4556 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4557 unsigned PrevRegVal =
4558 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4559 if (!HasCalculatedStride) {
4560 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4561 : (RegVal + NumRegs - PrevRegVal);
4562 HasCalculatedStride =
true;
4566 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4567 return Error(Loc,
"registers must have the same sequential stride");
4578 return Error(S,
"invalid number of vectors");
4580 unsigned NumElements = 0;
4581 unsigned ElementWidth = 0;
4582 if (!
Kind.empty()) {
4584 std::tie(NumElements, ElementWidth) = *VK;
4587 Operands.push_back(AArch64Operand::CreateVectorList(
4588 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4589 getLoc(), getContext()));
4596 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4597 if (!ParseRes.isSuccess())
4600 return tryParseVectorIndex(
Operands).isFailure();
4604 SMLoc StartLoc = getLoc();
4612 Operands.push_back(AArch64Operand::CreateReg(
4613 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4620 return Error(getLoc(),
"index must be absent or #0");
4623 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4624 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4625 return Error(getLoc(),
"index must be absent or #0");
4627 Operands.push_back(AArch64Operand::CreateReg(
4628 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4633 SMLoc StartLoc = getLoc();
4637 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4642 Operands.push_back(AArch64Operand::CreateReg(
4643 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4649 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4651 if (getParser().parseExpression(ImmVal))
4655 return TokError(
"immediate value expected for vector index");
4656 Operands.push_back(AArch64Operand::CreateImm(
4658 getLoc(), getContext()));
4660 if (parseOptionalMulOperand(
Operands))
4665 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4670template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4672 SMLoc StartLoc = getLoc();
4681 Operands.push_back(AArch64Operand::CreateReg(
4682 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4691 Res = tryParseOptionalShiftExtend(ExtOpnd);
4695 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4696 Operands.push_back(AArch64Operand::CreateReg(
4697 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4698 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4699 Ext->hasShiftExtendAmount()));
4713 if (!getTok().getString().equals_insensitive(
"mul") ||
4714 !(NextIsVL || NextIsHash))
4718 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4723 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4735 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4736 Operands.push_back(AArch64Operand::CreateImm(
4743 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4749 auto Tok = Parser.
getTok();
4754 .
Case(
"vgx2",
"vgx2")
4755 .
Case(
"vgx4",
"vgx4")
4767 auto Tok = getTok();
4777 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4786 bool invertCondCode) {
4790 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4804 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4809 getLexer().UnLex(SavedTok);
4813 switch (getLexer().getKind()) {
4817 if (parseSymbolicImmVal(Expr))
4818 return Error(S,
"invalid operand");
4821 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4822 return parseOptionalShiftExtend(getTok());
4826 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4831 return parseOperand(
Operands,
false,
false);
4834 if (!parseNeonVectorList(
Operands))
4838 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4843 return parseOperand(
Operands,
false,
false);
4848 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4850 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4855 return parseCondCode(
Operands, invertCondCode);
4869 Res = tryParseOptionalShiftExtend(
Operands);
4872 getLexer().UnLex(SavedTok);
4879 if (!parseOptionalMulOperand(
Operands))
4884 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
4886 return parseKeywordOperand(
Operands);
4892 if (getParser().parseExpression(IdVal))
4895 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
4907 bool isNegative =
false;
4923 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
4924 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
4925 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
4926 return TokError(
"unexpected floating point literal");
4927 else if (IntVal != 0 || isNegative)
4928 return TokError(
"expected floating-point constant #0.0");
4931 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
4932 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
4937 if (parseSymbolicImmVal(ImmVal))
4941 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
4944 return parseOptionalShiftExtend(Tok);
4947 SMLoc Loc = getLoc();
4948 if (Mnemonic !=
"ldr")
4949 return TokError(
"unexpected token in operand");
4951 const MCExpr *SubExprVal;
4952 if (getParser().parseExpression(SubExprVal))
4956 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
4957 return Error(Loc,
"Only valid when first operand is register");
4960 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4966 if (isa<MCConstantExpr>(SubExprVal)) {
4967 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4968 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4973 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4974 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
4975 Operands.push_back(AArch64Operand::CreateImm(
4979 ShiftAmt,
true, S, E, Ctx));
4985 return Error(Loc,
"Immediate too large for register");
4989 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4990 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
4996bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4997 const MCExpr *Expr =
nullptr;
4999 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
5002 if (
check(!
Value, L,
"expected constant expression"))
5004 Out =
Value->getValue();
5008bool AArch64AsmParser::parseComma() {
5016bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5020 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5025 unsigned RangeEnd =
Last;
5026 if (
Base == AArch64::X0) {
5027 if (
Last == AArch64::FP) {
5028 RangeEnd = AArch64::X28;
5029 if (Reg == AArch64::FP) {
5034 if (
Last == AArch64::LR) {
5035 RangeEnd = AArch64::X28;
5036 if (Reg == AArch64::FP) {
5039 }
else if (Reg == AArch64::LR) {
5046 if (
check(Reg < First || Reg > RangeEnd, Start,
5047 Twine(
"expected register in range ") +
5057 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5058 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5060 if (AOp1.isVectorList() && AOp2.isVectorList())
5061 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5062 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5063 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5065 if (!AOp1.isReg() || !AOp2.isReg())
5068 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5069 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5072 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5073 "Testing equality of non-scalar registers not supported");
5076 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5078 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5080 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5082 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5094 .
Case(
"beq",
"b.eq")
5095 .
Case(
"bne",
"b.ne")
5096 .
Case(
"bhs",
"b.hs")
5097 .
Case(
"bcs",
"b.cs")
5098 .
Case(
"blo",
"b.lo")
5099 .
Case(
"bcc",
"b.cc")
5100 .
Case(
"bmi",
"b.mi")
5101 .
Case(
"bpl",
"b.pl")
5102 .
Case(
"bvs",
"b.vs")
5103 .
Case(
"bvc",
"b.vc")
5104 .
Case(
"bhi",
"b.hi")
5105 .
Case(
"bls",
"b.ls")
5106 .
Case(
"bge",
"b.ge")
5107 .
Case(
"blt",
"b.lt")
5108 .
Case(
"bgt",
"b.gt")
5109 .
Case(
"ble",
"b.le")
5110 .
Case(
"bal",
"b.al")
5111 .
Case(
"bnv",
"b.nv")
5116 getTok().getIdentifier().lower() ==
".req") {
5117 parseDirectiveReq(
Name, NameLoc);
5124 size_t Start = 0, Next =
Name.find(
'.');
5129 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5130 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5131 return parseSysAlias(Head, NameLoc,
Operands);
5134 if (Head ==
"tlbip")
5135 return parseSyspAlias(Head, NameLoc,
Operands);
5137 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5143 Next =
Name.find(
'.', Start + 1);
5144 Head =
Name.slice(Start + 1, Next);
5148 std::string Suggestion;
5151 std::string Msg =
"invalid condition code";
5152 if (!Suggestion.empty())
5153 Msg +=
", did you mean " + Suggestion +
"?";
5154 return Error(SuffixLoc, Msg);
5156 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5159 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5165 Next =
Name.find(
'.', Start + 1);
5166 Head =
Name.slice(Start, Next);
5169 Operands.push_back(AArch64Operand::CreateToken(
5170 Head, SuffixLoc, getContext(),
true));
5175 bool condCodeFourthOperand =
5176 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5177 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5178 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5186 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5187 bool condCodeThirdOperand =
5188 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5196 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5197 (
N == 3 && condCodeThirdOperand) ||
5198 (
N == 2 && condCodeSecondOperand),
5199 condCodeSecondOperand || condCodeThirdOperand)) {
5219 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5222 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5225 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5238 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5239 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5240 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5241 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5242 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5243 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5244 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5250bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5259 PrefixInfo
Prefix = NextPrefix;
5260 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5272 return Error(IDLoc,
"instruction is unpredictable when following a"
5273 " movprfx, suggest replacing movprfx with mov");
5277 return Error(Loc[0],
"instruction is unpredictable when following a"
5278 " movprfx writing to a different destination");
5285 return Error(Loc[0],
"instruction is unpredictable when following a"
5286 " movprfx and destination also used as non-destructive"
5290 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5291 if (
Prefix.isPredicated()) {
5305 return Error(IDLoc,
"instruction is unpredictable when following a"
5306 " predicated movprfx, suggest using unpredicated movprfx");
5310 return Error(IDLoc,
"instruction is unpredictable when following a"
5311 " predicated movprfx using a different general predicate");
5315 return Error(IDLoc,
"instruction is unpredictable when following a"
5316 " predicated movprfx with a different element size");
5322 if (IsWindowsArm64EC) {
5328 if ((Reg == AArch64::W13 || Reg == AArch64::X13) ||
5329 (Reg == AArch64::W14 || Reg == AArch64::X14) ||
5330 (Reg == AArch64::W23 || Reg == AArch64::X23) ||
5331 (Reg == AArch64::W24 || Reg == AArch64::X24) ||
5332 (Reg == AArch64::W28 || Reg == AArch64::X28) ||
5333 (Reg >= AArch64::Q16 && Reg <= AArch64::Q31) ||
5334 (Reg >= AArch64::D16 && Reg <= AArch64::D31) ||
5335 (Reg >= AArch64::S16 && Reg <= AArch64::S31) ||
5336 (Reg >= AArch64::H16 && Reg <= AArch64::H31) ||
5337 (Reg >= AArch64::B16 && Reg <= AArch64::B31)) {
5339 " is disallowed on ARM64EC.");
5349 case AArch64::LDPSWpre:
5350 case AArch64::LDPWpost:
5351 case AArch64::LDPWpre:
5352 case AArch64::LDPXpost:
5353 case AArch64::LDPXpre: {
5358 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5359 "is also a destination");
5361 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5362 "is also a destination");
5365 case AArch64::LDR_ZA:
5366 case AArch64::STR_ZA: {
5369 return Error(Loc[1],
5370 "unpredictable instruction, immediate and offset mismatch.");
5373 case AArch64::LDPDi:
5374 case AArch64::LDPQi:
5375 case AArch64::LDPSi:
5376 case AArch64::LDPSWi:
5377 case AArch64::LDPWi:
5378 case AArch64::LDPXi: {
5382 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5385 case AArch64::LDPDpost:
5386 case AArch64::LDPDpre:
5387 case AArch64::LDPQpost:
5388 case AArch64::LDPQpre:
5389 case AArch64::LDPSpost:
5390 case AArch64::LDPSpre:
5391 case AArch64::LDPSWpost: {
5395 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5398 case AArch64::STPDpost:
5399 case AArch64::STPDpre:
5400 case AArch64::STPQpost:
5401 case AArch64::STPQpre:
5402 case AArch64::STPSpost:
5403 case AArch64::STPSpre:
5404 case AArch64::STPWpost:
5405 case AArch64::STPWpre:
5406 case AArch64::STPXpost:
5407 case AArch64::STPXpre: {
5412 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5413 "is also a source");
5415 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5416 "is also a source");
5419 case AArch64::LDRBBpre:
5420 case AArch64::LDRBpre:
5421 case AArch64::LDRHHpre:
5422 case AArch64::LDRHpre:
5423 case AArch64::LDRSBWpre:
5424 case AArch64::LDRSBXpre:
5425 case AArch64::LDRSHWpre:
5426 case AArch64::LDRSHXpre:
5427 case AArch64::LDRSWpre:
5428 case AArch64::LDRWpre:
5429 case AArch64::LDRXpre:
5430 case AArch64::LDRBBpost:
5431 case AArch64::LDRBpost:
5432 case AArch64::LDRHHpost:
5433 case AArch64::LDRHpost:
5434 case AArch64::LDRSBWpost:
5435 case AArch64::LDRSBXpost:
5436 case AArch64::LDRSHWpost:
5437 case AArch64::LDRSHXpost:
5438 case AArch64::LDRSWpost:
5439 case AArch64::LDRWpost:
5440 case AArch64::LDRXpost: {
5444 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5445 "is also a source");
5448 case AArch64::STRBBpost:
5449 case AArch64::STRBpost:
5450 case AArch64::STRHHpost:
5451 case AArch64::STRHpost:
5452 case AArch64::STRWpost:
5453 case AArch64::STRXpost:
5454 case AArch64::STRBBpre:
5455 case AArch64::STRBpre:
5456 case AArch64::STRHHpre:
5457 case AArch64::STRHpre:
5458 case AArch64::STRWpre:
5459 case AArch64::STRXpre: {
5463 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5464 "is also a source");
5467 case AArch64::STXRB:
5468 case AArch64::STXRH:
5469 case AArch64::STXRW:
5470 case AArch64::STXRX:
5471 case AArch64::STLXRB:
5472 case AArch64::STLXRH:
5473 case AArch64::STLXRW:
5474 case AArch64::STLXRX: {
5480 return Error(Loc[0],
5481 "unpredictable STXR instruction, status is also a source");
5484 case AArch64::STXPW:
5485 case AArch64::STXPX:
5486 case AArch64::STLXPW:
5487 case AArch64::STLXPX: {
5494 return Error(Loc[0],
5495 "unpredictable STXP instruction, status is also a source");
5498 case AArch64::LDRABwriteback:
5499 case AArch64::LDRAAwriteback: {
5503 return Error(Loc[0],
5504 "unpredictable LDRA instruction, writeback base"
5505 " is also a destination");
5512 case AArch64::CPYFP:
5513 case AArch64::CPYFPWN:
5514 case AArch64::CPYFPRN:
5515 case AArch64::CPYFPN:
5516 case AArch64::CPYFPWT:
5517 case AArch64::CPYFPWTWN:
5518 case AArch64::CPYFPWTRN:
5519 case AArch64::CPYFPWTN:
5520 case AArch64::CPYFPRT:
5521 case AArch64::CPYFPRTWN:
5522 case AArch64::CPYFPRTRN:
5523 case AArch64::CPYFPRTN:
5524 case AArch64::CPYFPT:
5525 case AArch64::CPYFPTWN:
5526 case AArch64::CPYFPTRN:
5527 case AArch64::CPYFPTN:
5528 case AArch64::CPYFM:
5529 case AArch64::CPYFMWN:
5530 case AArch64::CPYFMRN:
5531 case AArch64::CPYFMN:
5532 case AArch64::CPYFMWT:
5533 case AArch64::CPYFMWTWN:
5534 case AArch64::CPYFMWTRN:
5535 case AArch64::CPYFMWTN:
5536 case AArch64::CPYFMRT:
5537 case AArch64::CPYFMRTWN:
5538 case AArch64::CPYFMRTRN:
5539 case AArch64::CPYFMRTN:
5540 case AArch64::CPYFMT:
5541 case AArch64::CPYFMTWN:
5542 case AArch64::CPYFMTRN:
5543 case AArch64::CPYFMTN:
5544 case AArch64::CPYFE:
5545 case AArch64::CPYFEWN:
5546 case AArch64::CPYFERN:
5547 case AArch64::CPYFEN:
5548 case AArch64::CPYFEWT:
5549 case AArch64::CPYFEWTWN:
5550 case AArch64::CPYFEWTRN:
5551 case AArch64::CPYFEWTN:
5552 case AArch64::CPYFERT:
5553 case AArch64::CPYFERTWN:
5554 case AArch64::CPYFERTRN:
5555 case AArch64::CPYFERTN:
5556 case AArch64::CPYFET:
5557 case AArch64::CPYFETWN:
5558 case AArch64::CPYFETRN:
5559 case AArch64::CPYFETN:
5561 case AArch64::CPYPWN:
5562 case AArch64::CPYPRN:
5563 case AArch64::CPYPN:
5564 case AArch64::CPYPWT:
5565 case AArch64::CPYPWTWN:
5566 case AArch64::CPYPWTRN:
5567 case AArch64::CPYPWTN:
5568 case AArch64::CPYPRT:
5569 case AArch64::CPYPRTWN:
5570 case AArch64::CPYPRTRN:
5571 case AArch64::CPYPRTN:
5572 case AArch64::CPYPT:
5573 case AArch64::CPYPTWN:
5574 case AArch64::CPYPTRN:
5575 case AArch64::CPYPTN:
5577 case AArch64::CPYMWN:
5578 case AArch64::CPYMRN:
5579 case AArch64::CPYMN:
5580 case AArch64::CPYMWT:
5581 case AArch64::CPYMWTWN:
5582 case AArch64::CPYMWTRN:
5583 case AArch64::CPYMWTN:
5584 case AArch64::CPYMRT:
5585 case AArch64::CPYMRTWN:
5586 case AArch64::CPYMRTRN:
5587 case AArch64::CPYMRTN:
5588 case AArch64::CPYMT:
5589 case AArch64::CPYMTWN:
5590 case AArch64::CPYMTRN:
5591 case AArch64::CPYMTN:
5593 case AArch64::CPYEWN:
5594 case AArch64::CPYERN:
5595 case AArch64::CPYEN:
5596 case AArch64::CPYEWT:
5597 case AArch64::CPYEWTWN:
5598 case AArch64::CPYEWTRN:
5599 case AArch64::CPYEWTN:
5600 case AArch64::CPYERT:
5601 case AArch64::CPYERTWN:
5602 case AArch64::CPYERTRN:
5603 case AArch64::CPYERTN:
5604 case AArch64::CPYET:
5605 case AArch64::CPYETWN:
5606 case AArch64::CPYETRN:
5607 case AArch64::CPYETN: {
5615 return Error(Loc[0],
5616 "invalid CPY instruction, Xd_wb and Xd do not match");
5618 return Error(Loc[0],
5619 "invalid CPY instruction, Xs_wb and Xs do not match");
5621 return Error(Loc[0],
5622 "invalid CPY instruction, Xn_wb and Xn do not match");
5624 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5625 " registers are the same");
5627 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5628 " registers are the same");
5630 return Error(Loc[0],
"invalid CPY instruction, source and size"
5631 " registers are the same");
5635 case AArch64::SETPT:
5636 case AArch64::SETPN:
5637 case AArch64::SETPTN:
5639 case AArch64::SETMT:
5640 case AArch64::SETMN:
5641 case AArch64::SETMTN:
5643 case AArch64::SETET:
5644 case AArch64::SETEN:
5645 case AArch64::SETETN:
5646 case AArch64::SETGP:
5647 case AArch64::SETGPT:
5648 case AArch64::SETGPN:
5649 case AArch64::SETGPTN:
5650 case AArch64::SETGM:
5651 case AArch64::SETGMT:
5652 case AArch64::SETGMN:
5653 case AArch64::SETGMTN:
5654 case AArch64::MOPSSETGE:
5655 case AArch64::MOPSSETGET:
5656 case AArch64::MOPSSETGEN:
5657 case AArch64::MOPSSETGETN: {
5664 return Error(Loc[0],
5665 "invalid SET instruction, Xd_wb and Xd do not match");
5667 return Error(Loc[0],
5668 "invalid SET instruction, Xn_wb and Xn do not match");
5670 return Error(Loc[0],
"invalid SET instruction, destination and size"
5671 " registers are the same");
5673 return Error(Loc[0],
"invalid SET instruction, destination and source"
5674 " registers are the same");
5676 return Error(Loc[0],
"invalid SET instruction, source and size"
5677 " registers are the same");
5686 case AArch64::ADDSWri:
5687 case AArch64::ADDSXri:
5688 case AArch64::ADDWri:
5689 case AArch64::ADDXri:
5690 case AArch64::SUBSWri:
5691 case AArch64::SUBSXri:
5692 case AArch64::SUBWri:
5693 case AArch64::SUBXri: {
5701 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5728 return Error(Loc.
back(),
"invalid immediate expression");
5741 unsigned VariantID = 0);
5743bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5747 case Match_InvalidTiedOperand: {
5749 if (
Op.isVectorList())
5750 return Error(Loc,
"operand must match destination register list");
5752 assert(
Op.isReg() &&
"Unexpected operand type");
5753 switch (
Op.getRegEqualityTy()) {
5754 case RegConstraintEqualityTy::EqualsSubReg:
5755 return Error(Loc,
"operand must be 64-bit form of destination register");
5756 case RegConstraintEqualityTy::EqualsSuperReg:
5757 return Error(Loc,
"operand must be 32-bit form of destination register");
5758 case RegConstraintEqualityTy::EqualsReg:
5759 return Error(Loc,
"operand must match destination register");
5763 case Match_MissingFeature:
5765 "instruction requires a CPU feature not currently enabled");
5766 case Match_InvalidOperand:
5767 return Error(Loc,
"invalid operand for instruction");
5768 case Match_InvalidSuffix:
5769 return Error(Loc,
"invalid type suffix for instruction");
5770 case Match_InvalidCondCode:
5771 return Error(Loc,
"expected AArch64 condition code");
5772 case Match_AddSubRegExtendSmall:
5774 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5775 case Match_AddSubRegExtendLarge:
5777 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5778 case Match_AddSubSecondSource:
5780 "expected compatible register, symbol or integer in range [0, 4095]");
5781 case Match_LogicalSecondSource:
5782 return Error(Loc,
"expected compatible register or logical immediate");
5783 case Match_InvalidMovImm32Shift:
5784 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5785 case Match_InvalidMovImm64Shift:
5786 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5787 case Match_AddSubRegShift32:
5789 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5790 case Match_AddSubRegShift64:
5792 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5793 case Match_InvalidFPImm:
5795 "expected compatible register or floating-point constant");
5796 case Match_InvalidMemoryIndexedSImm6:
5797 return Error(Loc,
"index must be an integer in range [-32, 31].");
5798 case Match_InvalidMemoryIndexedSImm5:
5799 return Error(Loc,
"index must be an integer in range [-16, 15].");
5800 case Match_InvalidMemoryIndexed1SImm4:
5801 return Error(Loc,
"index must be an integer in range [-8, 7].");
5802 case Match_InvalidMemoryIndexed2SImm4:
5803 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5804 case Match_InvalidMemoryIndexed3SImm4:
5805 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5806 case Match_InvalidMemoryIndexed4SImm4:
5807 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5808 case Match_InvalidMemoryIndexed16SImm4:
5809 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5810 case Match_InvalidMemoryIndexed32SImm4:
5811 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5812 case Match_InvalidMemoryIndexed1SImm6:
5813 return Error(Loc,
"index must be an integer in range [-32, 31].");
5814 case Match_InvalidMemoryIndexedSImm8:
5815 return Error(Loc,
"index must be an integer in range [-128, 127].");
5816 case Match_InvalidMemoryIndexedSImm9:
5817 return Error(Loc,
"index must be an integer in range [-256, 255].");
5818 case Match_InvalidMemoryIndexed16SImm9:
5819 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5820 case Match_InvalidMemoryIndexed8SImm10:
5821 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5822 case Match_InvalidMemoryIndexed4SImm7:
5823 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5824 case Match_InvalidMemoryIndexed8SImm7:
5825 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5826 case Match_InvalidMemoryIndexed16SImm7:
5827 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5828 case Match_InvalidMemoryIndexed8UImm5:
5829 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5830 case Match_InvalidMemoryIndexed8UImm3:
5831 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5832 case Match_InvalidMemoryIndexed4UImm5:
5833 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5834 case Match_InvalidMemoryIndexed2UImm5:
5835 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5836 case Match_InvalidMemoryIndexed8UImm6:
5837 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5838 case Match_InvalidMemoryIndexed16UImm6:
5839 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5840 case Match_InvalidMemoryIndexed4UImm6:
5841 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5842 case Match_InvalidMemoryIndexed2UImm6:
5843 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5844 case Match_InvalidMemoryIndexed1UImm6:
5845 return Error(Loc,
"index must be in range [0, 63].");
5846 case Match_InvalidMemoryWExtend8:
5848 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5849 case Match_InvalidMemoryWExtend16:
5851 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5852 case Match_InvalidMemoryWExtend32:
5854 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5855 case Match_InvalidMemoryWExtend64:
5857 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5858 case Match_InvalidMemoryWExtend128:
5860 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5861 case Match_InvalidMemoryXExtend8:
5863 "expected 'lsl' or 'sxtx' with optional shift of #0");
5864 case Match_InvalidMemoryXExtend16:
5866 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5867 case Match_InvalidMemoryXExtend32:
5869 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5870 case Match_InvalidMemoryXExtend64:
5872 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5873 case Match_InvalidMemoryXExtend128:
5875 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5876 case Match_InvalidMemoryIndexed1:
5877 return Error(Loc,
"index must be an integer in range [0, 4095].");
5878 case Match_InvalidMemoryIndexed2:
5879 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
5880 case Match_InvalidMemoryIndexed4:
5881 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
5882 case Match_InvalidMemoryIndexed8:
5883 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
5884 case Match_InvalidMemoryIndexed16:
5885 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
5886 case Match_InvalidImm0_0:
5887 return Error(Loc,
"immediate must be 0.");
5888 case Match_InvalidImm0_1:
5889 return Error(Loc,
"immediate must be an integer in range [0, 1].");
5890 case Match_InvalidImm0_3:
5891 return Error(Loc,
"immediate must be an integer in range [0, 3].");
5892 case Match_InvalidImm0_7:
5893 return Error(Loc,
"immediate must be an integer in range [0, 7].");
5894 case Match_InvalidImm0_15:
5895 return Error(Loc,
"immediate must be an integer in range [0, 15].");
5896 case Match_InvalidImm0_31:
5897 return Error(Loc,
"immediate must be an integer in range [0, 31].");
5898 case Match_InvalidImm0_63:
5899 return Error(Loc,
"immediate must be an integer in range [0, 63].");
5900 case Match_InvalidImm0_127:
5901 return Error(Loc,
"immediate must be an integer in range [0, 127].");
5902 case Match_InvalidImm0_255:
5903 return Error(Loc,
"immediate must be an integer in range [0, 255].");
5904 case Match_InvalidImm0_65535:
5905 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
5906 case Match_InvalidImm1_8:
5907 return Error(Loc,
"immediate must be an integer in range [1, 8].");
5908 case Match_InvalidImm1_16:
5909 return Error(Loc,
"immediate must be an integer in range [1, 16].");
5910 case Match_InvalidImm1_32:
5911 return Error(Loc,
"immediate must be an integer in range [1, 32].");
5912 case Match_InvalidImm1_64:
5913 return Error(Loc,
"immediate must be an integer in range [1, 64].");
5914 case Match_InvalidMemoryIndexedRange2UImm0:
5915 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
5916 case Match_InvalidMemoryIndexedRange2UImm1:
5917 return Error(Loc,
"vector select offset must be an immediate range of the "
5918 "form <immf>:<imml>, where the first "
5919 "immediate is a multiple of 2 in the range [0, 2], and "
5920 "the second immediate is immf + 1.");
5921 case Match_InvalidMemoryIndexedRange2UImm2:
5922 case Match_InvalidMemoryIndexedRange2UImm3:
5925 "vector select offset must be an immediate range of the form "
5927 "where the first immediate is a multiple of 2 in the range [0, 6] or "
5929 "depending on the instruction, and the second immediate is immf + 1.");
5930 case Match_InvalidMemoryIndexedRange4UImm0:
5931 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
5932 case Match_InvalidMemoryIndexedRange4UImm1:
5933 case Match_InvalidMemoryIndexedRange4UImm2:
5936 "vector select offset must be an immediate range of the form "
5938 "where the first immediate is a multiple of 4 in the range [0, 4] or "
5940 "depending on the instruction, and the second immediate is immf + 3.");
5941 case Match_InvalidSVEAddSubImm8:
5942 return Error(Loc,
"immediate must be an integer in range [0, 255]"
5943 " with a shift amount of 0");
5944 case Match_InvalidSVEAddSubImm16:
5945 case Match_InvalidSVEAddSubImm32:
5946 case Match_InvalidSVEAddSubImm64:
5947 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
5948 "multiple of 256 in range [256, 65280]");
5949 case Match_InvalidSVECpyImm8:
5950 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
5951 " with a shift amount of 0");
5952 case Match_InvalidSVECpyImm16:
5953 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5954 "multiple of 256 in range [-32768, 65280]");
5955 case Match_InvalidSVECpyImm32:
5956 case Match_InvalidSVECpyImm64:
5957 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5958 "multiple of 256 in range [-32768, 32512]");
5959 case Match_InvalidIndexRange0_0:
5960 return Error(Loc,
"expected lane specifier '[0]'");
5961 case Match_InvalidIndexRange1_1:
5962 return Error(Loc,
"expected lane specifier '[1]'");
5963 case Match_InvalidIndexRange0_15:
5964 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5965 case Match_InvalidIndexRange0_7:
5966 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5967 case Match_InvalidIndexRange0_3:
5968 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5969 case Match_InvalidIndexRange0_1:
5970 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
5971 case Match_InvalidSVEIndexRange0_63:
5972 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
5973 case Match_InvalidSVEIndexRange0_31:
5974 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
5975 case Match_InvalidSVEIndexRange0_15:
5976 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5977 case Match_InvalidSVEIndexRange0_7:
5978 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5979 case Match_InvalidSVEIndexRange0_3:
5980 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5981 case Match_InvalidLabel:
5982 return Error(Loc,
"expected label or encodable integer pc offset");
5984 return Error(Loc,
"expected readable system register");
5986 case Match_InvalidSVCR:
5987 return Error(Loc,
"expected writable system register or pstate");
5988 case Match_InvalidComplexRotationEven:
5989 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
5990 case Match_InvalidComplexRotationOdd:
5991 return Error(Loc,
"complex rotation must be 90 or 270.");
5992 case Match_MnemonicFail: {
5994 ((AArch64Operand &)*
Operands[0]).getToken(),
5995 ComputeAvailableFeatures(STI->getFeatureBits()));
5996 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
5998 case Match_InvalidGPR64shifted8:
5999 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6000 case Match_InvalidGPR64shifted16:
6001 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6002 case Match_InvalidGPR64shifted32:
6003 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6004 case Match_InvalidGPR64shifted64:
6005 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6006 case Match_InvalidGPR64shifted128:
6008 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6009 case Match_InvalidGPR64NoXZRshifted8:
6010 return Error(Loc,
"register must be x0..x30 without shift");
6011 case Match_InvalidGPR64NoXZRshifted16:
6012 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6013 case Match_InvalidGPR64NoXZRshifted32:
6014 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6015 case Match_InvalidGPR64NoXZRshifted64:
6016 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6017 case Match_InvalidGPR64NoXZRshifted128:
6018 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6019 case Match_InvalidZPR32UXTW8:
6020 case Match_InvalidZPR32SXTW8:
6021 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6022 case Match_InvalidZPR32UXTW16:
6023 case Match_InvalidZPR32SXTW16:
6024 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6025 case Match_InvalidZPR32UXTW32:
6026 case Match_InvalidZPR32SXTW32:
6027 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6028 case Match_InvalidZPR32UXTW64:
6029 case Match_InvalidZPR32SXTW64:
6030 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6031 case Match_InvalidZPR64UXTW8:
6032 case Match_InvalidZPR64SXTW8:
6033 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6034 case Match_InvalidZPR64UXTW16:
6035 case Match_InvalidZPR64SXTW16:
6036 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6037 case Match_InvalidZPR64UXTW32:
6038 case Match_InvalidZPR64SXTW32:
6039 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6040 case Match_InvalidZPR64UXTW64:
6041 case Match_InvalidZPR64SXTW64:
6042 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6043 case Match_InvalidZPR32LSL8:
6044 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6045 case Match_InvalidZPR32LSL16:
6046 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6047 case Match_InvalidZPR32LSL32:
6048 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6049 case Match_InvalidZPR32LSL64:
6050 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6051 case Match_InvalidZPR64LSL8:
6052 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6053 case Match_InvalidZPR64LSL16:
6054 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6055 case Match_InvalidZPR64LSL32:
6056 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6057 case Match_InvalidZPR64LSL64:
6058 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6059 case Match_InvalidZPR0:
6060 return Error(Loc,
"expected register without element width suffix");
6061 case Match_InvalidZPR8:
6062 case Match_InvalidZPR16:
6063 case Match_InvalidZPR32:
6064 case Match_InvalidZPR64:
6065 case Match_InvalidZPR128:
6066 return Error(Loc,
"invalid element width");
6067 case Match_InvalidZPR_3b8:
6068 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6069 case Match_InvalidZPR_3b16:
6070 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6071 case Match_InvalidZPR_3b32:
6072 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6073 case Match_InvalidZPR_4b8:
6075 "Invalid restricted vector register, expected z0.b..z15.b");
6076 case Match_InvalidZPR_4b16:
6077 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6078 case Match_InvalidZPR_4b32:
6079 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6080 case Match_InvalidZPR_4b64:
6081 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6082 case Match_InvalidSVEPattern:
6083 return Error(Loc,
"invalid predicate pattern");
6084 case Match_InvalidSVEPPRorPNRAnyReg:
6085 case Match_InvalidSVEPPRorPNRBReg:
6086 case Match_InvalidSVEPredicateAnyReg:
6087 case Match_InvalidSVEPredicateBReg:
6088 case Match_InvalidSVEPredicateHReg:
6089 case Match_InvalidSVEPredicateSReg:
6090 case Match_InvalidSVEPredicateDReg:
6091 return Error(Loc,
"invalid predicate register.");
6092 case Match_InvalidSVEPredicate3bAnyReg:
6093 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6094 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6095 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6096 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6097 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6098 return Error(Loc,
"Invalid predicate register, expected PN in range "
6099 "pn8..pn15 with element suffix.");
6100 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6101 return Error(Loc,
"invalid restricted predicate-as-counter register "
6102 "expected pn8..pn15");
6103 case Match_InvalidSVEPNPredicateBReg:
6104 case Match_InvalidSVEPNPredicateHReg:
6105 case Match_InvalidSVEPNPredicateSReg:
6106 case Match_InvalidSVEPNPredicateDReg:
6107 return Error(Loc,
"Invalid predicate register, expected PN in range "
6108 "pn0..pn15 with element suffix.");
6109 case Match_InvalidSVEVecLenSpecifier:
6110 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6111 case Match_InvalidSVEPredicateListMul2x8:
6112 case Match_InvalidSVEPredicateListMul2x16:
6113 case Match_InvalidSVEPredicateListMul2x32:
6114 case Match_InvalidSVEPredicateListMul2x64:
6115 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6116 "predicate registers, where the first vector is a multiple of 2 "
6117 "and with correct element type");
6118 case Match_InvalidSVEExactFPImmOperandHalfOne:
6119 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6120 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6121 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6122 case Match_InvalidSVEExactFPImmOperandZeroOne:
6123 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6124 case Match_InvalidMatrixTileVectorH8:
6125 case Match_InvalidMatrixTileVectorV8:
6126 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6127 case Match_InvalidMatrixTileVectorH16:
6128 case Match_InvalidMatrixTileVectorV16:
6130 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6131 case Match_InvalidMatrixTileVectorH32:
6132 case Match_InvalidMatrixTileVectorV32:
6134 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6135 case Match_InvalidMatrixTileVectorH64:
6136 case Match_InvalidMatrixTileVectorV64:
6138 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6139 case Match_InvalidMatrixTileVectorH128:
6140 case Match_InvalidMatrixTileVectorV128:
6142 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6143 case Match_InvalidMatrixTile32:
6144 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6145 case Match_InvalidMatrixTile64:
6146 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6147 case Match_InvalidMatrix:
6148 return Error(Loc,
"invalid matrix operand, expected za");
6149 case Match_InvalidMatrix8:
6150 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6151 case Match_InvalidMatrix16:
6152 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6153 case Match_InvalidMatrix32:
6154 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6155 case Match_InvalidMatrix64:
6156 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6157 case Match_InvalidMatrixIndexGPR32_12_15:
6158 return Error(Loc,
"operand must be a register in range [w12, w15]");
6159 case Match_InvalidMatrixIndexGPR32_8_11:
6160 return Error(Loc,
"operand must be a register in range [w8, w11]");
6161 case Match_InvalidSVEVectorListMul2x8:
6162 case Match_InvalidSVEVectorListMul2x16:
6163 case Match_InvalidSVEVectorListMul2x32:
6164 case Match_InvalidSVEVectorListMul2x64:
6165 case Match_InvalidSVEVectorListMul2x128:
6166 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6167 "SVE vectors, where the first vector is a multiple of 2 "
6168 "and with matching element types");
6169 case Match_InvalidSVEVectorListMul4x8:
6170 case Match_InvalidSVEVectorListMul4x16:
6171 case Match_InvalidSVEVectorListMul4x32:
6172 case Match_InvalidSVEVectorListMul4x64:
6173 case Match_InvalidSVEVectorListMul4x128:
6174 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6175 "SVE vectors, where the first vector is a multiple of 4 "
6176 "and with matching element types");
6177 case Match_InvalidLookupTable:
6178 return Error(Loc,
"Invalid lookup table, expected zt0");
6179 case Match_InvalidSVEVectorListStrided2x8:
6180 case Match_InvalidSVEVectorListStrided2x16:
6181 case Match_InvalidSVEVectorListStrided2x32:
6182 case Match_InvalidSVEVectorListStrided2x64:
6185 "Invalid vector list, expected list with each SVE vector in the list "
6186 "8 registers apart, and the first register in the range [z0, z7] or "
6187 "[z16, z23] and with correct element type");
6188 case Match_InvalidSVEVectorListStrided4x8:
6189 case Match_InvalidSVEVectorListStrided4x16:
6190 case Match_InvalidSVEVectorListStrided4x32:
6191 case Match_InvalidSVEVectorListStrided4x64:
6194 "Invalid vector list, expected list with each SVE vector in the list "
6195 "4 registers apart, and the first register in the range [z0, z3] or "
6196 "[z16, z19] and with correct element type");
6197 case Match_AddSubLSLImm3ShiftLarge:
6199 "expected 'lsl' with optional integer in range [0, 7]");
6207bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6211 bool MatchingInlineAsm) {
6213 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6214 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6217 unsigned NumOperands =
Operands.size();
6219 if (NumOperands == 4 && Tok ==
"lsl") {
6220 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6221 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6222 if (Op2.isScalarReg() && Op3.isImm()) {
6223 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6228 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6230 NewOp3Val = (32 - Op3Val) & 0x1f;
6231 NewOp4Val = 31 - Op3Val;
6233 NewOp3Val = (64 - Op3Val) & 0x3f;
6234 NewOp4Val = 63 - Op3Val;
6241 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6242 Operands.push_back(AArch64Operand::CreateImm(
6243 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6244 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6245 Op3.getEndLoc(), getContext());
6248 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6250 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6251 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6252 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6254 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6255 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6256 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6258 if (LSBCE && WidthCE) {
6263 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6269 if (LSB >= RegWidth)
6270 return Error(LSBOp.getStartLoc(),
6271 "expected integer in range [0, 31]");
6272 if (Width < 1 || Width > RegWidth)
6273 return Error(WidthOp.getStartLoc(),
6274 "expected integer in range [1, 32]");
6278 ImmR = (32 - LSB) & 0x1f;
6280 ImmR = (64 - LSB) & 0x3f;
6284 if (ImmR != 0 && ImmS >= ImmR)
6285 return Error(WidthOp.getStartLoc(),
6286 "requested insert overflows register");
6291 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6292 Operands[2] = AArch64Operand::CreateReg(
6293 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6295 Operands[3] = AArch64Operand::CreateImm(
6296 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6298 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6299 WidthOp.getEndLoc(), getContext()));
6302 }
else if (NumOperands == 5) {
6305 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6306 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6307 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6308 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6310 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6311 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6312 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6314 if (Op3CE && Op4CE) {
6319 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6325 if (Op3Val >= RegWidth)
6326 return Error(Op3.getStartLoc(),
6327 "expected integer in range [0, 31]");
6328 if (Op4Val < 1 || Op4Val > RegWidth)
6329 return Error(Op4.getStartLoc(),
6330 "expected integer in range [1, 32]");
6334 NewOp3Val = (32 - Op3Val) & 0x1f;
6336 NewOp3Val = (64 - Op3Val) & 0x3f;
6340 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6341 return Error(Op4.getStartLoc(),
6342 "requested insert overflows register");
6348 Operands[3] = AArch64Operand::CreateImm(
6349 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6350 Operands[4] = AArch64Operand::CreateImm(
6351 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6353 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6355 else if (Tok ==
"sbfiz")
6356 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6358 else if (Tok ==
"ubfiz")
6359 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6368 }
else if (NumOperands == 5 &&
6369 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6370 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6371 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6372 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6374 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6375 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6376 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6378 if (Op3CE && Op4CE) {
6383 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6389 if (Op3Val >= RegWidth)
6390 return Error(Op3.getStartLoc(),
6391 "expected integer in range [0, 31]");
6392 if (Op4Val < 1 || Op4Val > RegWidth)
6393 return Error(Op4.getStartLoc(),
6394 "expected integer in range [1, 32]");
6396 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6398 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6399 return Error(Op4.getStartLoc(),
6400 "requested extract overflows register");
6404 Operands[4] = AArch64Operand::CreateImm(
6405 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6407 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6409 else if (Tok ==
"sbfx")
6410 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6412 else if (Tok ==
"ubfx")
6413 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6426 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6427 NumOperands == 4 && Tok ==
"movi") {
6428 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6429 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6430 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6431 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6432 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6433 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6434 if (Suffix.
lower() ==
".2d" &&
6435 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6436 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6437 " correctly on this CPU, converting to equivalent movi.16b");
6439 unsigned Idx = Op1.isToken() ? 1 : 2;
6441 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6449 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6452 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6453 if (
Op.isScalarReg()) {
6455 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6456 Op.getStartLoc(),
Op.getEndLoc(),
6461 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6462 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6463 if (
Op.isScalarReg() &&
6464 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6468 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6469 if (
Op.isScalarReg()) {
6471 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6473 Op.getEndLoc(), getContext());
6478 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6479 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6480 if (
Op.isScalarReg() &&
6481 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6485 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6486 if (
Op.isScalarReg()) {
6488 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6490 Op.getEndLoc(), getContext());
6499 unsigned MatchResult =
6501 MatchingInlineAsm, 1);
6505 if (MatchResult != Match_Success) {
6508 auto ShortFormNEONErrorInfo =
ErrorInfo;
6509 auto ShortFormNEONMatchResult = MatchResult;
6510 auto ShortFormNEONMissingFeatures = MissingFeatures;
6514 MatchingInlineAsm, 0);
6519 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6521 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6522 MatchResult = ShortFormNEONMatchResult;
6524 MissingFeatures = ShortFormNEONMissingFeatures;
6528 switch (MatchResult) {
6529 case Match_Success: {
6533 for (
unsigned i = 1; i < NumOperands; ++i)
6535 if (validateInstruction(Inst, IDLoc, OperandLocs))
6542 case Match_MissingFeature: {
6543 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6546 std::string Msg =
"instruction requires:";
6547 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6548 if (MissingFeatures[i]) {
6553 return Error(IDLoc, Msg);
6555 case Match_MnemonicFail:
6557 case Match_InvalidOperand: {
6558 SMLoc ErrorLoc = IDLoc;
6562 return Error(IDLoc,
"too few operands for instruction",
6563 SMRange(IDLoc, getTok().getLoc()));
6566 if (ErrorLoc ==
SMLoc())
6573 MatchResult = Match_InvalidSuffix;
6577 case Match_InvalidTiedOperand:
6578 case Match_InvalidMemoryIndexed1:
6579 case Match_InvalidMemoryIndexed2:
6580 case Match_InvalidMemoryIndexed4:
6581 case Match_InvalidMemoryIndexed8:
6582 case Match_InvalidMemoryIndexed16:
6583 case Match_InvalidCondCode:
6584 case Match_AddSubLSLImm3ShiftLarge:
6585 case Match_AddSubRegExtendSmall:
6586 case Match_AddSubRegExtendLarge:
6587 case Match_AddSubSecondSource:
6588 case Match_LogicalSecondSource:
6589 case Match_AddSubRegShift32:
6590 case Match_AddSubRegShift64:
6591 case Match_InvalidMovImm32Shift:
6592 case Match_InvalidMovImm64Shift:
6593 case Match_InvalidFPImm:
6594 case Match_InvalidMemoryWExtend8:
6595 case Match_InvalidMemoryWExtend16:
6596 case Match_InvalidMemoryWExtend32:
6597 case Match_InvalidMemoryWExtend64:
6598 case Match_InvalidMemoryWExtend128:
6599 case Match_InvalidMemoryXExtend8:
6600 case Match_InvalidMemoryXExtend16:
6601 case Match_InvalidMemoryXExtend32:
6602 case Match_InvalidMemoryXExtend64:
6603 case Match_InvalidMemoryXExtend128:
6604 case Match_InvalidMemoryIndexed1SImm4:
6605 case Match_InvalidMemoryIndexed2SImm4:
6606 case Match_InvalidMemoryIndexed3SImm4:
6607 case Match_InvalidMemoryIndexed4SImm4:
6608 case Match_InvalidMemoryIndexed1SImm6:
6609 case Match_InvalidMemoryIndexed16SImm4:
6610 case Match_InvalidMemoryIndexed32SImm4:
6611 case Match_InvalidMemoryIndexed4SImm7:
6612 case Match_InvalidMemoryIndexed8SImm7:
6613 case Match_InvalidMemoryIndexed16SImm7:
6614 case Match_InvalidMemoryIndexed8UImm5:
6615 case Match_InvalidMemoryIndexed8UImm3:
6616 case Match_InvalidMemoryIndexed4UImm5:
6617 case Match_InvalidMemoryIndexed2UImm5:
6618 case Match_InvalidMemoryIndexed1UImm6:
6619 case Match_InvalidMemoryIndexed2UImm6:
6620 case Match_InvalidMemoryIndexed4UImm6:
6621 case Match_InvalidMemoryIndexed8UImm6:
6622 case Match_InvalidMemoryIndexed16UImm6:
6623 case Match_InvalidMemoryIndexedSImm6:
6624 case Match_InvalidMemoryIndexedSImm5:
6625 case Match_InvalidMemoryIndexedSImm8:
6626 case Match_InvalidMemoryIndexedSImm9:
6627 case Match_InvalidMemoryIndexed16SImm9:
6628 case Match_InvalidMemoryIndexed8SImm10:
6629 case Match_InvalidImm0_0:
6630 case Match_InvalidImm0_1:
6631 case Match_InvalidImm0_3:
6632 case Match_InvalidImm0_7:
6633 case Match_InvalidImm0_15:
6634 case Match_InvalidImm0_31:
6635 case Match_InvalidImm0_63:
6636 case Match_InvalidImm0_127:
6637 case Match_InvalidImm0_255:
6638 case Match_InvalidImm0_65535:
6639 case Match_InvalidImm1_8:
6640 case Match_InvalidImm1_16:
6641 case Match_InvalidImm1_32:
6642 case Match_InvalidImm1_64:
6643 case Match_InvalidMemoryIndexedRange2UImm0:
6644 case Match_InvalidMemoryIndexedRange2UImm1:
6645 case Match_InvalidMemoryIndexedRange2UImm2:
6646 case Match_InvalidMemoryIndexedRange2UImm3:
6647 case Match_InvalidMemoryIndexedRange4UImm0:
6648 case Match_InvalidMemoryIndexedRange4UImm1:
6649 case Match_InvalidMemoryIndexedRange4UImm2:
6650 case Match_InvalidSVEAddSubImm8:
6651 case Match_InvalidSVEAddSubImm16:
6652 case Match_InvalidSVEAddSubImm32:
6653 case Match_InvalidSVEAddSubImm64:
6654 case Match_InvalidSVECpyImm8:
6655 case Match_InvalidSVECpyImm16:
6656 case Match_InvalidSVECpyImm32:
6657 case Match_InvalidSVECpyImm64:
6658 case Match_InvalidIndexRange0_0:
6659 case Match_InvalidIndexRange1_1:
6660 case Match_InvalidIndexRange0_15:
6661 case Match_InvalidIndexRange0_7:
6662 case Match_InvalidIndexRange0_3:
6663 case Match_InvalidIndexRange0_1:
6664 case Match_InvalidSVEIndexRange0_63:
6665 case Match_InvalidSVEIndexRange0_31:
6666 case Match_InvalidSVEIndexRange0_15:
6667 case Match_InvalidSVEIndexRange0_7:
6668 case Match_InvalidSVEIndexRange0_3:
6669 case Match_InvalidLabel:
6670 case Match_InvalidComplexRotationEven:
6671 case Match_InvalidComplexRotationOdd:
6672 case Match_InvalidGPR64shifted8:
6673 case Match_InvalidGPR64shifted16:
6674 case Match_InvalidGPR64shifted32:
6675 case Match_InvalidGPR64shifted64:
6676 case Match_InvalidGPR64shifted128:
6677 case Match_InvalidGPR64NoXZRshifted8:
6678 case Match_InvalidGPR64NoXZRshifted16:
6679 case Match_InvalidGPR64NoXZRshifted32:
6680 case Match_InvalidGPR64NoXZRshifted64:
6681 case Match_InvalidGPR64NoXZRshifted128:
6682 case Match_InvalidZPR32UXTW8:
6683 case Match_InvalidZPR32UXTW16:
6684 case Match_InvalidZPR32UXTW32:
6685 case Match_InvalidZPR32UXTW64:
6686 case Match_InvalidZPR32SXTW8:
6687 case Match_InvalidZPR32SXTW16:
6688 case Match_InvalidZPR32SXTW32:
6689 case Match_InvalidZPR32SXTW64:
6690 case Match_InvalidZPR64UXTW8:
6691 case Match_InvalidZPR64SXTW8:
6692 case Match_InvalidZPR64UXTW16:
6693 case Match_InvalidZPR64SXTW16:
6694 case Match_InvalidZPR64UXTW32:
6695 case Match_InvalidZPR64SXTW32:
6696 case Match_InvalidZPR64UXTW64:
6697 case Match_InvalidZPR64SXTW64:
6698 case Match_InvalidZPR32LSL8:
6699 case Match_InvalidZPR32LSL16:
6700 case Match_InvalidZPR32LSL32:
6701 case Match_InvalidZPR32LSL64:
6702 case Match_InvalidZPR64LSL8:
6703 case Match_InvalidZPR64LSL16:
6704 case Match_InvalidZPR64LSL32:
6705 case Match_InvalidZPR64LSL64:
6706 case Match_InvalidZPR0:
6707 case Match_InvalidZPR8:
6708 case Match_InvalidZPR16:
6709 case Match_InvalidZPR32:
6710 case Match_InvalidZPR64:
6711 case Match_InvalidZPR128:
6712 case Match_InvalidZPR_3b8:
6713 case Match_InvalidZPR_3b16:
6714 case Match_InvalidZPR_3b32:
6715 case Match_InvalidZPR_4b8:
6716 case Match_InvalidZPR_4b16:
6717 case Match_InvalidZPR_4b32:
6718 case Match_InvalidZPR_4b64:
6719 case Match_InvalidSVEPPRorPNRAnyReg:
6720 case Match_InvalidSVEPPRorPNRBReg:
6721 case Match_InvalidSVEPredicateAnyReg:
6722 case Match_InvalidSVEPattern:
6723 case Match_InvalidSVEVecLenSpecifier:
6724 case Match_InvalidSVEPredicateBReg:
6725 case Match_InvalidSVEPredicateHReg:
6726 case Match_InvalidSVEPredicateSReg:
6727 case Match_InvalidSVEPredicateDReg:
6728 case Match_InvalidSVEPredicate3bAnyReg:
6729 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6730 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6731 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6732 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6733 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6734 case Match_InvalidSVEPNPredicateBReg:
6735 case Match_InvalidSVEPNPredicateHReg:
6736 case Match_InvalidSVEPNPredicateSReg:
6737 case Match_InvalidSVEPNPredicateDReg:
6738 case Match_InvalidSVEPredicateListMul2x8:
6739 case Match_InvalidSVEPredicateListMul2x16:
6740 case Match_InvalidSVEPredicateListMul2x32:
6741 case Match_InvalidSVEPredicateListMul2x64:
6742 case Match_InvalidSVEExactFPImmOperandHalfOne:
6743 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6744 case Match_InvalidSVEExactFPImmOperandZeroOne:
6745 case Match_InvalidMatrixTile32:
6746 case Match_InvalidMatrixTile64:
6747 case Match_InvalidMatrix:
6748 case Match_InvalidMatrix8:
6749 case Match_InvalidMatrix16:
6750 case Match_InvalidMatrix32:
6751 case Match_InvalidMatrix64:
6752 case Match_InvalidMatrixTileVectorH8:
6753 case Match_InvalidMatrixTileVectorH16:
6754 case Match_InvalidMatrixTileVectorH32:
6755 case Match_InvalidMatrixTileVectorH64:
6756 case Match_InvalidMatrixTileVectorH128:
6757 case Match_InvalidMatrixTileVectorV8:
6758 case Match_InvalidMatrixTileVectorV16:
6759 case Match_InvalidMatrixTileVectorV32:
6760 case Match_InvalidMatrixTileVectorV64:
6761 case Match_InvalidMatrixTileVectorV128:
6762 case Match_InvalidSVCR:
6763 case Match_InvalidMatrixIndexGPR32_12_15:
6764 case Match_InvalidMatrixIndexGPR32_8_11:
6765 case Match_InvalidLookupTable:
6766 case Match_InvalidSVEVectorListMul2x8:
6767 case Match_InvalidSVEVectorListMul2x16:
6768 case Match_InvalidSVEVectorListMul2x32:
6769 case Match_InvalidSVEVectorListMul2x64:
6770 case Match_InvalidSVEVectorListMul2x128:
6771 case Match_InvalidSVEVectorListMul4x8:
6772 case Match_InvalidSVEVectorListMul4x16:
6773 case Match_InvalidSVEVectorListMul4x32:
6774 case Match_InvalidSVEVectorListMul4x64:
6775 case Match_InvalidSVEVectorListMul4x128:
6776 case Match_InvalidSVEVectorListStrided2x8:
6777 case Match_InvalidSVEVectorListStrided2x16:
6778 case Match_InvalidSVEVectorListStrided2x32:
6779 case Match_InvalidSVEVectorListStrided2x64:
6780 case Match_InvalidSVEVectorListStrided4x8:
6781 case Match_InvalidSVEVectorListStrided4x16:
6782 case Match_InvalidSVEVectorListStrided4x32:
6783 case Match_InvalidSVEVectorListStrided4x64:
6787 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6791 if (ErrorLoc ==
SMLoc())
6801bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6808 if (IDVal ==
".arch")
6809 parseDirectiveArch(Loc);
6810 else if (IDVal ==
".cpu")
6811 parseDirectiveCPU(Loc);
6812 else if (IDVal ==
".tlsdesccall")
6813 parseDirectiveTLSDescCall(Loc);
6814 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6815 parseDirectiveLtorg(Loc);
6816 else if (IDVal ==
".unreq")
6817 parseDirectiveUnreq(Loc);
6818 else if (IDVal ==
".inst")
6819 parseDirectiveInst(Loc);
6820 else if (IDVal ==
".cfi_negate_ra_state")
6821 parseDirectiveCFINegateRAState();
6822 else if (IDVal ==
".cfi_b_key_frame")
6823 parseDirectiveCFIBKeyFrame();
6824 else if (IDVal ==
".cfi_mte_tagged_frame")
6825 parseDirectiveCFIMTETaggedFrame();
6826 else if (IDVal ==
".arch_extension")
6827 parseDirectiveArchExtension(Loc);
6828 else if (IDVal ==
".variant_pcs")
6829 parseDirectiveVariantPCS(Loc);
6832 parseDirectiveLOH(IDVal, Loc);
6835 }
else if (IsCOFF) {
6836 if (IDVal ==
".seh_stackalloc")
6837 parseDirectiveSEHAllocStack(Loc);
6838 else if (IDVal ==
".seh_endprologue")
6839 parseDirectiveSEHPrologEnd(Loc);
6840 else if (IDVal ==
".seh_save_r19r20_x")
6841 parseDirectiveSEHSaveR19R20X(Loc);
6842 else if (IDVal ==
".seh_save_fplr")
6843 parseDirectiveSEHSaveFPLR(Loc);
6844 else if (IDVal ==
".seh_save_fplr_x")
6845 parseDirectiveSEHSaveFPLRX(Loc);
6846 else if (IDVal ==
".seh_save_reg")
6847 parseDirectiveSEHSaveReg(Loc);
6848 else if (IDVal ==
".seh_save_reg_x")
6849 parseDirectiveSEHSaveRegX(Loc);
6850 else if (IDVal ==
".seh_save_regp")
6851 parseDirectiveSEHSaveRegP(Loc);
6852 else if (IDVal ==
".seh_save_regp_x")
6853 parseDirectiveSEHSaveRegPX(Loc);
6854 else if (IDVal ==
".seh_save_lrpair")
6855 parseDirectiveSEHSaveLRPair(Loc);
6856 else if (IDVal ==
".seh_save_freg")
6857 parseDirectiveSEHSaveFReg(Loc);
6858 else if (IDVal ==
".seh_save_freg_x")
6859 parseDirectiveSEHSaveFRegX(Loc);
6860 else if (IDVal ==
".seh_save_fregp")
6861 parseDirectiveSEHSaveFRegP(Loc);
6862 else if (IDVal ==
".seh_save_fregp_x")
6863 parseDirectiveSEHSaveFRegPX(Loc);
6864 else if (IDVal ==
".seh_set_fp")
6865 parseDirectiveSEHSetFP(Loc);
6866 else if (IDVal ==
".seh_add_fp")
6867 parseDirectiveSEHAddFP(Loc);
6868 else if (IDVal ==
".seh_nop")
6869 parseDirectiveSEHNop(Loc);
6870 else if (IDVal ==
".seh_save_next")
6871 parseDirectiveSEHSaveNext(Loc);
6872 else if (IDVal ==
".seh_startepilogue")
6873 parseDirectiveSEHEpilogStart(Loc);
6874 else if (IDVal ==
".seh_endepilogue")
6875 parseDirectiveSEHEpilogEnd(Loc);
6876 else if (IDVal ==
".seh_trap_frame")
6877 parseDirectiveSEHTrapFrame(Loc);
6878 else if (IDVal ==
".seh_pushframe")
6879 parseDirectiveSEHMachineFrame(Loc);
6880 else if (IDVal ==
".seh_context")
6881 parseDirectiveSEHContext(Loc);
6882 else if (IDVal ==
".seh_ec_context")
6883 parseDirectiveSEHECContext(Loc);
6884 else if (IDVal ==
".seh_clear_unwound_to_call")
6885 parseDirectiveSEHClearUnwoundToCall(Loc);
6886 else if (IDVal ==
".seh_pac_sign_lr")
6887 parseDirectiveSEHPACSignLR(Loc);
6888 else if (IDVal ==
".seh_save_any_reg")
6889 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
6890 else if (IDVal ==
".seh_save_any_reg_p")
6891 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
6892 else if (IDVal ==
".seh_save_any_reg_x")
6893 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
6894 else if (IDVal ==
".seh_save_any_reg_px")
6895 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
6908 if (!NoCrypto && Crypto) {
6911 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
6912 ArchInfo == AArch64::ARMV8_3A) {
6916 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
6917 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
6918 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
6919 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
6920 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
6921 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
6927 }
else if (NoCrypto) {
6930 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
6931 ArchInfo == AArch64::ARMV8_3A) {
6932 RequestedExtensions.
push_back(
"nosha2");
6935 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
6936 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
6937 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
6938 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
6939 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
6940 ArchInfo == AArch64::ARMV9_4A) {
6942 RequestedExtensions.
push_back(
"nosha3");
6943 RequestedExtensions.
push_back(
"nosha2");
6951bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
6952 SMLoc ArchLoc = getLoc();
6955 std::tie(Arch, ExtensionString) =
6956 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6960 return Error(ArchLoc,
"unknown arch name");
6966 std::vector<StringRef> AArch64Features;
6971 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6973 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
6976 if (!ExtensionString.
empty())
6977 ExtensionString.
split(RequestedExtensions,
'+');
6982 setAvailableFeatures(ComputeAvailableFeatures(Features));
6983 for (
auto Name : RequestedExtensions) {
6984 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
6997 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7006bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
7007 SMLoc ExtLoc = getLoc();
7009 StringRef Name = getParser().parseStringToEndOfStatement().trim();
7014 bool EnableFeature =
true;
7015 if (
Name.starts_with_insensitive(
"no")) {
7016 EnableFeature =
false;
7027 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7033 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7037 return Error(ExtLoc,
"unknown architectural extension: " +
Name);
7046bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7047 SMLoc CurLoc = getLoc();
7050 std::tie(CPU, ExtensionString) =
7051 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7057 if (!ExtensionString.
empty())
7058 ExtensionString.
split(RequestedExtensions,
'+');
7062 Error(CurLoc,
"unknown CPU name");
7071 for (
auto Name : RequestedExtensions) {
7075 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7077 bool FoundExtension =
false;
7090 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7091 FoundExtension =
true;
7096 if (!FoundExtension)
7097 Error(CurLoc,
"unsupported architectural extension");
7106bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7108 return Error(Loc,
"expected expression following '.inst' directive");
7110 auto parseOp = [&]() ->
bool {
7112 const MCExpr *Expr =
nullptr;
7113 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
7116 if (
check(!
Value, L,
"expected constant expression"))
7118 getTargetStreamer().emitInst(
Value->getValue());
7122 return parseMany(parseOp);
7127bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7129 if (
check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7141 getParser().getStreamer().emitInstruction(Inst, getSTI());
7147bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7151 return TokError(
"expected an identifier or a number in directive");
7154 int64_t
Id = getTok().getIntVal();
7156 return TokError(
"invalid numeric identifier in directive");
7165 return TokError(
"invalid identifier in directive");
7173 assert(NbArgs != -1 &&
"Invalid number of arguments");
7176 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7178 if (getParser().parseIdentifier(
Name))
7179 return TokError(
"expected identifier in directive");
7180 Args.push_back(getContext().getOrCreateSymbol(
Name));
7182 if (
Idx + 1 == NbArgs)
7190 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7196bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7199 getTargetStreamer().emitCurrentConstantPool();
7207 SMLoc SRegLoc = getLoc();
7208 RegKind RegisterKind = RegKind::Scalar;
7210 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7214 RegisterKind = RegKind::NeonVector;
7215 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7221 return Error(SRegLoc,
"vector register without type specifier expected");
7226 RegisterKind = RegKind::SVEDataVector;
7228 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7234 return Error(SRegLoc,
7235 "sve vector register without type specifier expected");
7240 RegisterKind = RegKind::SVEPredicateVector;
7241 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7247 return Error(SRegLoc,
7248 "sve predicate register without type specifier expected");
7252 return Error(SRegLoc,
"register name or alias expected");
7258 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7259 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7260 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7267bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7269 return TokError(
"unexpected input in .unreq directive.");
7270 RegisterReqs.
erase(getTok().getIdentifier().lower());
7275bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7278 getStreamer().emitCFINegateRAState();
7284bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7287 getStreamer().emitCFIBKeyFrame();
7293bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7296 getStreamer().emitCFIMTETaggedFrame();
7302bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7304 if (getParser().parseIdentifier(
Name))
7305 return TokError(
"expected symbol name");
7308 getTargetStreamer().emitDirectiveVariantPCS(
7309 getContext().getOrCreateSymbol(
Name));
7315bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7317 if (parseImmExpr(
Size))
7319 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7325bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7326 getTargetStreamer().emitARM64WinCFIPrologEnd();
7332bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7334 if (parseImmExpr(
Offset))
7336 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7342bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7344 if (parseImmExpr(
Offset))
7346 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7352bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7354 if (parseImmExpr(
Offset))
7356 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7362bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7365 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7366 parseComma() || parseImmExpr(
Offset))
7368 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7374bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7377 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7378 parseComma() || parseImmExpr(
Offset))
7380 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7386bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7389 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7390 parseComma() || parseImmExpr(
Offset))
7392 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7398bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7401 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7402 parseComma() || parseImmExpr(
Offset))
7404 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7410bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7414 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7415 parseComma() || parseImmExpr(
Offset))
7417 if (
check(((Reg - 19) % 2 != 0), L,
7418 "expected register with even offset from x19"))
7420 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7426bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7429 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7430 parseComma() || parseImmExpr(
Offset))
7432 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7438bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7441 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7442 parseComma() || parseImmExpr(
Offset))
7444 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7450bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7453 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7454 parseComma() || parseImmExpr(
Offset))
7456 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7462bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7465 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7466 parseComma() || parseImmExpr(
Offset))
7468 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7474bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7475 getTargetStreamer().emitARM64WinCFISetFP();
7481bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7483 if (parseImmExpr(
Size))
7485 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7491bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7492 getTargetStreamer().emitARM64WinCFINop();
7498bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7499 getTargetStreamer().emitARM64WinCFISaveNext();
7505bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7506 getTargetStreamer().emitARM64WinCFIEpilogStart();
7512bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7513 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7519bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7520 getTargetStreamer().emitARM64WinCFITrapFrame();
7526bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7527 getTargetStreamer().emitARM64WinCFIMachineFrame();
7533bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7534 getTargetStreamer().emitARM64WinCFIContext();
7540bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7541 getTargetStreamer().emitARM64WinCFIECContext();
7547bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7548 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7554bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7555 getTargetStreamer().emitARM64WinCFIPACSignLR();
7564bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7569 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7570 parseComma() || parseImmExpr(
Offset))
7573 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7574 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7575 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7576 return Error(L,
"invalid save_any_reg offset");
7577 unsigned EncodedReg;
7578 if (Reg == AArch64::FP)
7580 else if (Reg == AArch64::LR)
7583 EncodedReg =
Reg - AArch64::X0;
7585 if (Reg == AArch64::LR)
7586 return Error(Start,
"lr cannot be paired with another register");
7588 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7590 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7593 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7595 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7597 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7598 unsigned EncodedReg =
Reg - AArch64::D0;
7599 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7600 return Error(L,
"invalid save_any_reg offset");
7602 if (Reg == AArch64::D31)
7603 return Error(Start,
"d31 cannot be paired with another register");
7605 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7607 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7610 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7612 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7614 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7615 unsigned EncodedReg =
Reg - AArch64::Q0;
7617 return Error(L,
"invalid save_any_reg offset");
7619 if (Reg == AArch64::Q31)
7620 return Error(Start,
"q31 cannot be paired with another register");
7622 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7624 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7627 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7629 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7632 return Error(Start,
"save_any_reg register must be x, q or d register");
7637bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7639 if (!parseAuthExpr(Res, EndLoc))
7641 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7648bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7659 "combination of @AUTH with other modifiers not supported");
7682 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7704 return TokError(
"expected key name");
7709 return TokError(
"invalid key '" + KeyStr +
"'");
7716 return TokError(
"expected integer discriminator");
7719 if (!isUInt<16>(Discriminator))
7720 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7721 " out of range [0, 0xFFFF]");
7724 bool UseAddressDiversity =
false;
7729 return TokError(
"expected 'addr'");
7730 UseAddressDiversity =
true;
7739 UseAddressDiversity, Ctx);
7744AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7752 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7753 ELFRefKind = AE->getKind();
7754 Expr = AE->getSubExpr();
7760 DarwinRefKind = SE->
getKind();
7767 if (!Relocatable || Res.
getSymB())
7794#define GET_REGISTER_MATCHER
7795#define GET_SUBTARGET_FEATURE_NAME
7796#define GET_MATCHER_IMPLEMENTATION
7797#define GET_MNEMONIC_SPELL_CHECKER
7798#include "AArch64GenAsmMatcher.inc"
7804 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7806 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7808 return Match_InvalidOperand;
7811 return Match_InvalidOperand;
7812 if (CE->getValue() == ExpectedVal)
7813 return Match_Success;
7814 return Match_InvalidOperand;
7819 return Match_InvalidOperand;
7825 if (
Op.isTokenEqual(
"za"))
7826 return Match_Success;
7827 return Match_InvalidOperand;
7833#define MATCH_HASH(N) \
7834 case MCK__HASH_##N: \
7835 return MatchesOpImmediate(N);
7861#define MATCH_HASH_MINUS(N) \
7862 case MCK__HASH__MINUS_##N: \
7863 return MatchesOpImmediate(-N);
7867#undef MATCH_HASH_MINUS
7876 return Error(S,
"expected register");
7879 ParseStatus Res = tryParseScalarRegister(FirstReg);
7881 return Error(S,
"expected first even register of a consecutive same-size "
7882 "even/odd register pair");
7885 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
7887 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
7889 bool isXReg = XRegClass.
contains(FirstReg),
7890 isWReg = WRegClass.
contains(FirstReg);
7891 if (!isXReg && !isWReg)
7892 return Error(S,
"expected first even register of a consecutive same-size "
7893 "even/odd register pair");
7898 if (FirstEncoding & 0x1)
7899 return Error(S,
"expected first even register of a consecutive same-size "
7900 "even/odd register pair");
7903 return Error(getLoc(),
"expected comma");
7909 Res = tryParseScalarRegister(SecondReg);
7911 return Error(E,
"expected second odd register of a consecutive same-size "
7912 "even/odd register pair");
7915 (isXReg && !XRegClass.
contains(SecondReg)) ||
7916 (isWReg && !WRegClass.
contains(SecondReg)))
7917 return Error(E,
"expected second odd register of a consecutive same-size "
7918 "even/odd register pair");
7923 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
7926 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
7929 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
7930 getLoc(), getContext()));
7935template <
bool ParseShiftExtend,
bool ParseSuffix>
7937 const SMLoc S = getLoc();
7943 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7948 if (ParseSuffix &&
Kind.empty())
7955 unsigned ElementWidth = KindRes->second;
7959 Operands.push_back(AArch64Operand::CreateVectorReg(
7960 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
7973 Res = tryParseOptionalShiftExtend(ExtOpnd);
7977 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
7978 Operands.push_back(AArch64Operand::CreateVectorReg(
7979 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
7980 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
7981 Ext->hasShiftExtendAmount()));
8006 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
8008 return TokError(
"invalid operand for instruction");
8013 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8024 SS, getLoc(), getContext()));
8035 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8046 SS, getLoc(), getContext()));
8055 if (!tryParseScalarRegister(XReg).isSuccess())
8061 XReg, AArch64::x8sub_0,
8062 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8065 "expected an even-numbered x-register in the range [x0,x22]");
8068 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8082 if (getParser().parseExpression(ImmF))
8092 SMLoc E = getTok().getLoc();
8094 if (getParser().parseExpression(ImmL))
8097 unsigned ImmFVal = cast<MCConstantExpr>(ImmF)->getValue();
8098 unsigned ImmLVal = cast<MCConstantExpr>(ImmL)->getValue();
8101 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 MCAsmLayout *Layout, 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