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"
326 SMLoc &EndLoc)
override;
329 unsigned Kind)
override;
333 static bool classifySymbolRef(
const MCExpr *Expr,
365 SMLoc StartLoc, EndLoc;
374 struct ShiftExtendOp {
377 bool HasExplicitAmount;
387 RegConstraintEqualityTy EqualityTy;
403 ShiftExtendOp ShiftExtend;
408 unsigned ElementWidth;
412 struct MatrixTileListOp {
413 unsigned RegMask = 0;
416 struct VectorListOp {
420 unsigned NumElements;
421 unsigned ElementWidth;
422 RegKind RegisterKind;
425 struct VectorIndexOp {
433 struct ShiftedImmOp {
435 unsigned ShiftAmount;
492 unsigned PStateField;
498 struct MatrixRegOp MatrixReg;
499 struct MatrixTileListOp MatrixTileList;
500 struct VectorListOp VectorList;
501 struct VectorIndexOp VectorIndex;
503 struct ShiftedImmOp ShiftedImm;
504 struct ImmRangeOp ImmRange;
506 struct FPImmOp FPImm;
508 struct SysRegOp SysReg;
509 struct SysCRImmOp SysCRImm;
511 struct PSBHintOp PSBHint;
512 struct BTIHintOp BTIHint;
513 struct ShiftExtendOp ShiftExtend;
526 StartLoc =
o.StartLoc;
536 ShiftedImm =
o.ShiftedImm;
539 ImmRange =
o.ImmRange;
553 case k_MatrixRegister:
554 MatrixReg =
o.MatrixReg;
556 case k_MatrixTileList:
557 MatrixTileList =
o.MatrixTileList;
560 VectorList =
o.VectorList;
563 VectorIndex =
o.VectorIndex;
569 SysCRImm =
o.SysCRImm;
581 ShiftExtend =
o.ShiftExtend;
590 SMLoc getStartLoc()
const override {
return StartLoc; }
592 SMLoc getEndLoc()
const override {
return EndLoc; }
595 assert(Kind == k_Token &&
"Invalid access!");
599 bool isTokenSuffix()
const {
600 assert(Kind == k_Token &&
"Invalid access!");
604 const MCExpr *getImm()
const {
605 assert(Kind == k_Immediate &&
"Invalid access!");
609 const MCExpr *getShiftedImmVal()
const {
610 assert(Kind == k_ShiftedImm &&
"Invalid access!");
611 return ShiftedImm.Val;
614 unsigned getShiftedImmShift()
const {
615 assert(Kind == k_ShiftedImm &&
"Invalid access!");
616 return ShiftedImm.ShiftAmount;
619 unsigned getFirstImmVal()
const {
620 assert(Kind == k_ImmRange &&
"Invalid access!");
621 return ImmRange.First;
624 unsigned getLastImmVal()
const {
625 assert(Kind == k_ImmRange &&
"Invalid access!");
626 return ImmRange.Last;
630 assert(Kind == k_CondCode &&
"Invalid access!");
635 assert (Kind == k_FPImm &&
"Invalid access!");
636 return APFloat(APFloat::IEEEdouble(),
APInt(64, FPImm.Val,
true));
639 bool getFPImmIsExact()
const {
640 assert (Kind == k_FPImm &&
"Invalid access!");
641 return FPImm.IsExact;
644 unsigned getBarrier()
const {
645 assert(Kind == k_Barrier &&
"Invalid access!");
650 assert(Kind == k_Barrier &&
"Invalid access!");
654 bool getBarriernXSModifier()
const {
655 assert(Kind == k_Barrier &&
"Invalid access!");
660 assert(Kind == k_Register &&
"Invalid access!");
664 unsigned getMatrixReg()
const {
665 assert(Kind == k_MatrixRegister &&
"Invalid access!");
666 return MatrixReg.RegNum;
669 unsigned getMatrixElementWidth()
const {
670 assert(Kind == k_MatrixRegister &&
"Invalid access!");
671 return MatrixReg.ElementWidth;
674 MatrixKind getMatrixKind()
const {
675 assert(Kind == k_MatrixRegister &&
"Invalid access!");
676 return MatrixReg.Kind;
679 unsigned getMatrixTileListRegMask()
const {
680 assert(isMatrixTileList() &&
"Invalid access!");
681 return MatrixTileList.RegMask;
684 RegConstraintEqualityTy getRegEqualityTy()
const {
685 assert(Kind == k_Register &&
"Invalid access!");
686 return Reg.EqualityTy;
689 unsigned getVectorListStart()
const {
690 assert(Kind == k_VectorList &&
"Invalid access!");
691 return VectorList.RegNum;
694 unsigned getVectorListCount()
const {
695 assert(Kind == k_VectorList &&
"Invalid access!");
696 return VectorList.Count;
699 unsigned getVectorListStride()
const {
700 assert(Kind == k_VectorList &&
"Invalid access!");
701 return VectorList.Stride;
704 int getVectorIndex()
const {
705 assert(Kind == k_VectorIndex &&
"Invalid access!");
706 return VectorIndex.Val;
710 assert(Kind == k_SysReg &&
"Invalid access!");
711 return StringRef(SysReg.Data, SysReg.Length);
714 unsigned getSysCR()
const {
715 assert(Kind == k_SysCR &&
"Invalid access!");
719 unsigned getPrefetch()
const {
720 assert(Kind == k_Prefetch &&
"Invalid access!");
724 unsigned getPSBHint()
const {
725 assert(Kind == k_PSBHint &&
"Invalid access!");
730 assert(Kind == k_PSBHint &&
"Invalid access!");
731 return StringRef(PSBHint.Data, PSBHint.Length);
734 unsigned getBTIHint()
const {
735 assert(Kind == k_BTIHint &&
"Invalid access!");
740 assert(Kind == k_BTIHint &&
"Invalid access!");
741 return StringRef(BTIHint.Data, BTIHint.Length);
745 assert(Kind == k_SVCR &&
"Invalid access!");
746 return StringRef(SVCR.Data, SVCR.Length);
750 assert(Kind == k_Prefetch &&
"Invalid access!");
755 if (Kind == k_ShiftExtend)
756 return ShiftExtend.Type;
757 if (Kind == k_Register)
758 return Reg.ShiftExtend.Type;
762 unsigned getShiftExtendAmount()
const {
763 if (Kind == k_ShiftExtend)
764 return ShiftExtend.Amount;
765 if (Kind == k_Register)
766 return Reg.ShiftExtend.Amount;
770 bool hasShiftExtendAmount()
const {
771 if (Kind == k_ShiftExtend)
772 return ShiftExtend.HasExplicitAmount;
773 if (Kind == k_Register)
774 return Reg.ShiftExtend.HasExplicitAmount;
778 bool isImm()
const override {
return Kind == k_Immediate; }
779 bool isMem()
const override {
return false; }
781 bool isUImm6()
const {
788 return (Val >= 0 && Val < 64);
791 template <
int W
idth>
bool isSImm()
const {
return isSImmScaled<Width, 1>(); }
794 return isImmScaled<Bits, Scale>(
true);
797 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
799 if (IsRange && isImmRange() &&
800 (getLastImmVal() != getFirstImmVal() +
Offset))
801 return DiagnosticPredicateTy::NoMatch;
803 return isImmScaled<Bits, Scale, IsRange>(
false);
806 template <
int Bits,
int Scale,
bool IsRange = false>
808 if ((!
isImm() && !isImmRange()) || (
isImm() && IsRange) ||
809 (isImmRange() && !IsRange))
810 return DiagnosticPredicateTy::NoMatch;
814 Val = getFirstImmVal();
818 return DiagnosticPredicateTy::NoMatch;
822 int64_t MinVal, MaxVal;
824 int64_t Shift =
Bits - 1;
825 MinVal = (int64_t(1) << Shift) * -Scale;
826 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
829 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
832 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
833 return DiagnosticPredicateTy::Match;
835 return DiagnosticPredicateTy::NearMatch;
840 return DiagnosticPredicateTy::NoMatch;
841 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
843 return DiagnosticPredicateTy::NoMatch;
845 if (Val >= 0 && Val < 32)
846 return DiagnosticPredicateTy::Match;
847 return DiagnosticPredicateTy::NearMatch;
852 return DiagnosticPredicateTy::NoMatch;
853 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
855 return DiagnosticPredicateTy::NoMatch;
857 if (Val >= 0 && Val <= 1)
858 return DiagnosticPredicateTy::Match;
859 return DiagnosticPredicateTy::NearMatch;
862 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
866 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
898 template <
int Scale>
bool isUImm12Offset()
const {
904 return isSymbolicUImm12Offset(getImm());
907 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
910 template <
int N,
int M>
911 bool isImmInRange()
const {
918 return (Val >=
N && Val <= M);
923 template <
typename T>
924 bool isLogicalImm()
const {
941 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
943 bool isImmRange()
const {
return Kind == k_ImmRange; }
948 template <
unsigned W
idth>
949 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
950 if (isShiftedImm() && Width == getShiftedImmShift())
951 if (
auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
952 return std::make_pair(
CE->getValue(), Width);
955 if (
auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
956 int64_t Val =
CE->getValue();
958 return std::make_pair(Val >> Width, Width);
960 return std::make_pair(Val, 0u);
966 bool isAddSubImm()
const {
967 if (!isShiftedImm() && !
isImm())
973 if (isShiftedImm()) {
974 unsigned Shift = ShiftedImm.ShiftAmount;
975 Expr = ShiftedImm.Val;
976 if (Shift != 0 && Shift != 12)
985 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
986 DarwinRefKind, Addend)) {
1003 if (
auto ShiftedVal = getShiftedVal<12>())
1004 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1011 bool isAddSubImmNeg()
const {
1012 if (!isShiftedImm() && !
isImm())
1016 if (
auto ShiftedVal = getShiftedVal<12>())
1017 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1027 template <
typename T>
1029 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1030 return DiagnosticPredicateTy::NoMatch;
1032 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1033 std::is_same<int8_t, T>::value;
1034 if (
auto ShiftedImm = getShiftedVal<8>())
1035 if (!(IsByte && ShiftedImm->second) &&
1036 AArch64_AM::isSVECpyImm<T>(
uint64_t(ShiftedImm->first)
1037 << ShiftedImm->second))
1038 return DiagnosticPredicateTy::Match;
1040 return DiagnosticPredicateTy::NearMatch;
1047 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1048 return DiagnosticPredicateTy::NoMatch;
1050 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1051 std::is_same<int8_t, T>::value;
1052 if (
auto ShiftedImm = getShiftedVal<8>())
1053 if (!(IsByte && ShiftedImm->second) &&
1054 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
1055 << ShiftedImm->second))
1056 return DiagnosticPredicateTy::Match;
1058 return DiagnosticPredicateTy::NearMatch;
1062 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1063 return DiagnosticPredicateTy::Match;
1064 return DiagnosticPredicateTy::NoMatch;
1067 bool isCondCode()
const {
return Kind == k_CondCode; }
1069 bool isSIMDImmType10()
const {
1079 bool isBranchTarget()
const {
1088 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1089 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1100 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1101 DarwinRefKind, Addend)) {
1110 bool isMovWSymbolG3()
const {
1114 bool isMovWSymbolG2()
const {
1115 return isMovWSymbol(
1122 bool isMovWSymbolG1()
const {
1123 return isMovWSymbol(
1131 bool isMovWSymbolG0()
const {
1132 return isMovWSymbol(
1140 template<
int RegW
idth,
int Shift>
1141 bool isMOVZMovAlias()
const {
1142 if (!
isImm())
return false;
1155 template<
int RegW
idth,
int Shift>
1156 bool isMOVNMovAlias()
const {
1157 if (!
isImm())
return false;
1160 if (!CE)
return false;
1166 bool isFPImm()
const {
1167 return Kind == k_FPImm &&
1171 bool isBarrier()
const {
1172 return Kind == k_Barrier && !getBarriernXSModifier();
1174 bool isBarriernXS()
const {
1175 return Kind == k_Barrier && getBarriernXSModifier();
1177 bool isSysReg()
const {
return Kind == k_SysReg; }
1179 bool isMRSSystemRegister()
const {
1180 if (!isSysReg())
return false;
1182 return SysReg.MRSReg != -1U;
1185 bool isMSRSystemRegister()
const {
1186 if (!isSysReg())
return false;
1187 return SysReg.MSRReg != -1U;
1190 bool isSystemPStateFieldWithImm0_1()
const {
1191 if (!isSysReg())
return false;
1192 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1195 bool isSystemPStateFieldWithImm0_15()
const {
1198 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1201 bool isSVCR()
const {
1204 return SVCR.PStateField != -1U;
1207 bool isReg()
const override {
1208 return Kind == k_Register;
1211 bool isVectorList()
const {
return Kind == k_VectorList; }
1213 bool isScalarReg()
const {
1214 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1217 bool isNeonVectorReg()
const {
1218 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1221 bool isNeonVectorRegLo()
const {
1222 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1223 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1225 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1229 bool isNeonVectorReg0to7()
const {
1230 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1231 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1235 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1236 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1238 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1241 case AArch64::PPRRegClassID:
1242 case AArch64::PPR_3bRegClassID:
1243 case AArch64::PPR_p8to15RegClassID:
1244 case AArch64::PNRRegClassID:
1245 case AArch64::PNR_p8to15RegClassID:
1246 case AArch64::PPRorPNRRegClassID:
1247 RK = RegKind::SVEPredicateAsCounter;
1253 return (Kind == k_Register &&
Reg.Kind == RK) &&
1254 AArch64MCRegisterClasses[
Class].contains(
getReg());
1257 template <
unsigned Class>
bool isSVEVectorReg()
const {
1260 case AArch64::ZPRRegClassID:
1261 case AArch64::ZPR_3bRegClassID:
1262 case AArch64::ZPR_4bRegClassID:
1263 RK = RegKind::SVEDataVector;
1265 case AArch64::PPRRegClassID:
1266 case AArch64::PPR_3bRegClassID:
1267 case AArch64::PPR_p8to15RegClassID:
1268 case AArch64::PNRRegClassID:
1269 case AArch64::PNR_p8to15RegClassID:
1270 case AArch64::PPRorPNRRegClassID:
1271 RK = RegKind::SVEPredicateVector;
1277 return (Kind == k_Register &&
Reg.Kind == RK) &&
1278 AArch64MCRegisterClasses[
Class].contains(
getReg());
1281 template <
unsigned Class>
bool isFPRasZPR()
const {
1282 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1283 AArch64MCRegisterClasses[
Class].contains(
getReg());
1286 template <
int ElementW
idth,
unsigned Class>
1288 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1289 return DiagnosticPredicateTy::NoMatch;
1291 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1292 return DiagnosticPredicateTy::Match;
1294 return DiagnosticPredicateTy::NearMatch;
1297 template <
int ElementW
idth,
unsigned Class>
1299 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1300 Reg.Kind != RegKind::SVEPredicateVector))
1301 return DiagnosticPredicateTy::NoMatch;
1303 if ((isSVEPredicateAsCounterReg<Class>() ||
1304 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1305 Reg.ElementWidth == ElementWidth)
1306 return DiagnosticPredicateTy::Match;
1308 return DiagnosticPredicateTy::NearMatch;
1311 template <
int ElementW
idth,
unsigned Class>
1313 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1314 return DiagnosticPredicateTy::NoMatch;
1316 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1317 return DiagnosticPredicateTy::Match;
1319 return DiagnosticPredicateTy::NearMatch;
1322 template <
int ElementW
idth,
unsigned Class>
1324 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1325 return DiagnosticPredicateTy::NoMatch;
1327 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1328 return DiagnosticPredicateTy::Match;
1330 return DiagnosticPredicateTy::NearMatch;
1333 template <
int ElementWidth,
unsigned Class,
1335 bool ShiftWidthAlwaysSame>
1337 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1338 if (!VectorMatch.isMatch())
1339 return DiagnosticPredicateTy::NoMatch;
1344 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1347 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1348 return DiagnosticPredicateTy::NoMatch;
1350 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1351 return DiagnosticPredicateTy::Match;
1353 return DiagnosticPredicateTy::NearMatch;
1356 bool isGPR32as64()
const {
1357 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1358 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1361 bool isGPR64as32()
const {
1362 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1363 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1366 bool isGPR64x8()
const {
1367 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1368 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1372 bool isWSeqPair()
const {
1373 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1374 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1378 bool isXSeqPair()
const {
1379 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1380 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1384 bool isSyspXzrPair()
const {
1385 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1388 template<
int64_t Angle,
int64_t Remainder>
1390 if (!
isImm())
return DiagnosticPredicateTy::NoMatch;
1393 if (!CE)
return DiagnosticPredicateTy::NoMatch;
1396 if (
Value % Angle == Remainder &&
Value <= 270)
1397 return DiagnosticPredicateTy::Match;
1398 return DiagnosticPredicateTy::NearMatch;
1401 template <
unsigned RegClassID>
bool isGPR64()
const {
1402 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1403 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1406 template <
unsigned RegClassID,
int ExtW
idth>
1408 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1409 return DiagnosticPredicateTy::NoMatch;
1411 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1412 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1413 return DiagnosticPredicateTy::Match;
1414 return DiagnosticPredicateTy::NearMatch;
1419 template <RegKind VectorKind,
unsigned NumRegs>
1420 bool isImplicitlyTypedVectorList()
const {
1421 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1422 VectorList.NumElements == 0 &&
1423 VectorList.RegisterKind == VectorKind;
1426 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1427 unsigned ElementWidth,
unsigned Stride = 1>
1428 bool isTypedVectorList()
const {
1429 if (Kind != k_VectorList)
1431 if (VectorList.Count != NumRegs)
1433 if (VectorList.RegisterKind != VectorKind)
1435 if (VectorList.ElementWidth != ElementWidth)
1437 if (VectorList.Stride != Stride)
1439 return VectorList.NumElements == NumElements;
1442 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1443 unsigned ElementWidth>
1446 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1448 return DiagnosticPredicateTy::NoMatch;
1449 if (((VectorList.RegNum - AArch64::Z0) % NumRegs) != 0)
1450 return DiagnosticPredicateTy::NearMatch;
1451 return DiagnosticPredicateTy::Match;
1454 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1455 unsigned ElementWidth>
1457 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1458 ElementWidth, Stride>();
1460 return DiagnosticPredicateTy::NoMatch;
1461 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1462 ((VectorList.RegNum >= AArch64::Z16) &&
1463 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1464 return DiagnosticPredicateTy::Match;
1465 return DiagnosticPredicateTy::NoMatch;
1468 template <
int Min,
int Max>
1470 if (Kind != k_VectorIndex)
1471 return DiagnosticPredicateTy::NoMatch;
1472 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1473 return DiagnosticPredicateTy::Match;
1474 return DiagnosticPredicateTy::NearMatch;
1477 bool isToken()
const override {
return Kind == k_Token; }
1479 bool isTokenEqual(
StringRef Str)
const {
1480 return Kind == k_Token && getToken() == Str;
1482 bool isSysCR()
const {
return Kind == k_SysCR; }
1483 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1484 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1485 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1486 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1487 bool isShifter()
const {
1488 if (!isShiftExtend())
1498 if (Kind != k_FPImm)
1499 return DiagnosticPredicateTy::NoMatch;
1501 if (getFPImmIsExact()) {
1503 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1507 APFloat RealVal(APFloat::IEEEdouble());
1509 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1510 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1513 if (
getFPImm().bitwiseIsEqual(RealVal))
1514 return DiagnosticPredicateTy::Match;
1517 return DiagnosticPredicateTy::NearMatch;
1520 template <
unsigned ImmA,
unsigned ImmB>
1523 if ((Res = isExactFPImm<ImmA>()))
1524 return DiagnosticPredicateTy::Match;
1525 if ((Res = isExactFPImm<ImmB>()))
1526 return DiagnosticPredicateTy::Match;
1530 bool isExtend()
const {
1531 if (!isShiftExtend())
1540 getShiftExtendAmount() <= 4;
1543 bool isExtend64()
const {
1553 bool isExtendLSL64()
const {
1559 getShiftExtendAmount() <= 4;
1562 bool isLSLImm3Shift()
const {
1563 if (!isShiftExtend())
1569 template<
int W
idth>
bool isMemXExtend()
const {
1574 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1575 getShiftExtendAmount() == 0);
1578 template<
int W
idth>
bool isMemWExtend()
const {
1583 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1584 getShiftExtendAmount() == 0);
1587 template <
unsigned w
idth>
1588 bool isArithmeticShifter()
const {
1598 template <
unsigned w
idth>
1599 bool isLogicalShifter()
const {
1607 getShiftExtendAmount() < width;
1610 bool isMovImm32Shifter()
const {
1618 uint64_t Val = getShiftExtendAmount();
1619 return (Val == 0 || Val == 16);
1622 bool isMovImm64Shifter()
const {
1630 uint64_t Val = getShiftExtendAmount();
1631 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1634 bool isLogicalVecShifter()
const {
1639 unsigned Shift = getShiftExtendAmount();
1641 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1644 bool isLogicalVecHalfWordShifter()
const {
1645 if (!isLogicalVecShifter())
1649 unsigned Shift = getShiftExtendAmount();
1651 (Shift == 0 || Shift == 8);
1654 bool isMoveVecShifter()
const {
1655 if (!isShiftExtend())
1659 unsigned Shift = getShiftExtendAmount();
1661 (Shift == 8 || Shift == 16);
1670 bool isSImm9OffsetFB()
const {
1671 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1674 bool isAdrpLabel()
const {
1681 int64_t Val =
CE->getValue();
1682 int64_t Min = - (4096 * (1LL << (21 - 1)));
1683 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1684 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1690 bool isAdrLabel()
const {
1697 int64_t Val =
CE->getValue();
1698 int64_t Min = - (1LL << (21 - 1));
1699 int64_t
Max = ((1LL << (21 - 1)) - 1);
1700 return Val >= Min && Val <=
Max;
1706 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1709 return DiagnosticPredicateTy::NoMatch;
1710 if (getMatrixKind() != Kind ||
1711 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1712 EltSize != getMatrixElementWidth())
1713 return DiagnosticPredicateTy::NearMatch;
1714 return DiagnosticPredicateTy::Match;
1717 bool isPAuthPCRelLabel16Operand()
const {
1729 return (Val <= 0) && (Val > -(1 << 18));
1736 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1742 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1743 assert(
N == 1 &&
"Invalid number of operands!");
1747 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1748 assert(
N == 1 &&
"Invalid number of operands!");
1752 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1753 assert(
N == 1 &&
"Invalid number of operands!");
1755 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1764 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1765 assert(
N == 1 &&
"Invalid number of operands!");
1767 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1776 template <
int W
idth>
1777 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1780 case 8:
Base = AArch64::B0;
break;
1781 case 16:
Base = AArch64::H0;
break;
1782 case 32:
Base = AArch64::S0;
break;
1783 case 64:
Base = AArch64::D0;
break;
1784 case 128:
Base = AArch64::Q0;
break;
1791 void addPPRorPNRRegOperands(
MCInst &Inst,
unsigned N)
const {
1792 assert(
N == 1 &&
"Invalid number of operands!");
1795 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1796 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1800 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1801 assert(
N == 1 &&
"Invalid number of operands!");
1806 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1807 assert(
N == 1 &&
"Invalid number of operands!");
1809 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1813 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1814 assert(
N == 1 &&
"Invalid number of operands!");
1816 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1820 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1821 assert(
N == 1 &&
"Invalid number of operands!");
1825 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1826 assert(
N == 1 &&
"Invalid number of operands!");
1830 enum VecListIndexType {
1831 VecListIdx_DReg = 0,
1832 VecListIdx_QReg = 1,
1833 VecListIdx_ZReg = 2,
1834 VecListIdx_PReg = 3,
1837 template <VecListIndexType RegTy,
unsigned NumRegs>
1838 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1839 assert(
N == 1 &&
"Invalid number of operands!");
1840 static const unsigned FirstRegs[][5] = {
1842 AArch64::D0, AArch64::D0_D1,
1843 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1845 AArch64::Q0, AArch64::Q0_Q1,
1846 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1848 AArch64::Z0, AArch64::Z0_Z1,
1849 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1851 AArch64::P0, AArch64::P0_P1 }
1854 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1855 " NumRegs must be <= 4 for ZRegs");
1857 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1858 " NumRegs must be <= 2 for PRegs");
1860 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1862 FirstRegs[(
unsigned)RegTy][0]));
1865 template <
unsigned NumRegs>
1866 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1867 assert(
N == 1 &&
"Invalid number of operands!");
1868 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1872 if (getVectorListStart() < AArch64::Z16) {
1873 assert((getVectorListStart() < AArch64::Z8) &&
1874 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1876 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1878 assert((getVectorListStart() < AArch64::Z24) &&
1879 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1881 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1885 if (getVectorListStart() < AArch64::Z16) {
1886 assert((getVectorListStart() < AArch64::Z4) &&
1887 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1889 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1891 assert((getVectorListStart() < AArch64::Z20) &&
1892 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1894 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1902 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1903 assert(
N == 1 &&
"Invalid number of operands!");
1904 unsigned RegMask = getMatrixTileListRegMask();
1905 assert(RegMask <= 0xFF &&
"Invalid mask!");
1909 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1910 assert(
N == 1 &&
"Invalid number of operands!");
1914 template <
unsigned ImmIs0,
unsigned ImmIs1>
1915 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1916 assert(
N == 1 &&
"Invalid number of operands!");
1917 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1921 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1922 assert(
N == 1 &&
"Invalid number of operands!");
1926 addExpr(Inst, getImm());
1929 template <
int Shift>
1930 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1931 assert(
N == 2 &&
"Invalid number of operands!");
1932 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1935 }
else if (isShiftedImm()) {
1936 addExpr(Inst, getShiftedImmVal());
1939 addExpr(Inst, getImm());
1944 template <
int Shift>
1945 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1946 assert(
N == 2 &&
"Invalid number of operands!");
1947 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1954 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1955 assert(
N == 1 &&
"Invalid number of operands!");
1959 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1960 assert(
N == 1 &&
"Invalid number of operands!");
1963 addExpr(Inst, getImm());
1968 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
1969 addImmOperands(Inst,
N);
1973 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
1974 assert(
N == 1 &&
"Invalid number of operands!");
1984 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
1985 assert(
N == 1 &&
"Invalid number of operands!");
1990 template <
int Scale>
1991 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
1992 assert(
N == 1 &&
"Invalid number of operands!");
1997 template <
int Scale>
1998 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
1999 assert(
N == 1 &&
"Invalid number of operands!");
2003 template <
typename T>
2004 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
2005 assert(
N == 1 &&
"Invalid number of operands!");
2007 std::make_unsigned_t<T> Val = MCE->
getValue();
2012 template <
typename T>
2013 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2014 assert(
N == 1 &&
"Invalid number of operands!");
2016 std::make_unsigned_t<T> Val = ~MCE->getValue();
2021 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
2022 assert(
N == 1 &&
"Invalid number of operands!");
2028 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2032 assert(
N == 1 &&
"Invalid number of operands!");
2035 addExpr(Inst, getImm());
2038 assert(MCE &&
"Invalid constant immediate operand!");
2042 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2046 assert(
N == 1 &&
"Invalid number of operands!");
2049 addExpr(Inst, getImm());
2055 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2059 assert(
N == 1 &&
"Invalid number of operands!");
2062 addExpr(Inst, getImm());
2065 assert(MCE &&
"Invalid constant immediate operand!");
2069 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2073 assert(
N == 1 &&
"Invalid number of operands!");
2076 addExpr(Inst, getImm());
2079 assert(MCE &&
"Invalid constant immediate operand!");
2083 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2084 assert(
N == 1 &&
"Invalid number of operands!");
2089 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2090 assert(
N == 1 &&
"Invalid number of operands!");
2094 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2095 assert(
N == 1 &&
"Invalid number of operands!");
2099 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2100 assert(
N == 1 &&
"Invalid number of operands!");
2105 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2106 assert(
N == 1 &&
"Invalid number of operands!");
2111 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2112 assert(
N == 1 &&
"Invalid number of operands!");
2117 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2118 assert(
N == 1 &&
"Invalid number of operands!");
2123 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2124 assert(
N == 1 &&
"Invalid number of operands!");
2129 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2130 assert(
N == 1 &&
"Invalid number of operands!");
2134 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2135 assert(
N == 1 &&
"Invalid number of operands!");
2139 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2140 assert(
N == 1 &&
"Invalid number of operands!");
2144 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2145 assert(
N == 1 &&
"Invalid number of operands!");
2149 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2150 assert(
N == 1 &&
"Invalid number of operands!");
2156 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2157 assert(
N == 1 &&
"Invalid number of operands!");
2158 unsigned Imm = getShiftExtendAmount();
2162 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2171 if (
Reg != AArch64::XZR)
2177 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2178 assert(
N == 1 &&
"Invalid number of operands!");
2185 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2186 assert(
N == 1 &&
"Invalid number of operands!");
2193 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2194 assert(
N == 2 &&
"Invalid number of operands!");
2205 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2206 assert(
N == 2 &&
"Invalid number of operands!");
2214 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2215 assert(
N == 1 &&
"Invalid number of operands!");
2222 addExpr(Inst, getImm());
2227 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2228 assert(
N == 1 &&
"Invalid number of operands!");
2235 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2236 assert(
N == 1 &&
"Invalid number of operands!");
2241 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2242 assert(
N == 1 &&
"Invalid number of operands!");
2249 static std::unique_ptr<AArch64Operand>
2251 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2252 Op->Tok.Data = Str.data();
2253 Op->Tok.Length = Str.size();
2254 Op->Tok.IsSuffix = IsSuffix;
2260 static std::unique_ptr<AArch64Operand>
2262 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2264 unsigned ShiftAmount = 0,
2265 unsigned HasExplicitAmount =
false) {
2266 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2267 Op->Reg.RegNum = RegNum;
2269 Op->Reg.ElementWidth = 0;
2270 Op->Reg.EqualityTy = EqTy;
2271 Op->Reg.ShiftExtend.Type = ExtTy;
2272 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2273 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2279 static std::unique_ptr<AArch64Operand>
2280 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2283 unsigned ShiftAmount = 0,
2284 unsigned HasExplicitAmount =
false) {
2285 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2286 Kind == RegKind::SVEPredicateVector ||
2287 Kind == RegKind::SVEPredicateAsCounter) &&
2288 "Invalid vector kind");
2289 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2291 Op->Reg.ElementWidth = ElementWidth;
2295 static std::unique_ptr<AArch64Operand>
2296 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2297 unsigned NumElements,
unsigned ElementWidth,
2299 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2300 Op->VectorList.RegNum = RegNum;
2301 Op->VectorList.Count = Count;
2302 Op->VectorList.Stride = Stride;
2303 Op->VectorList.NumElements = NumElements;
2304 Op->VectorList.ElementWidth = ElementWidth;
2305 Op->VectorList.RegisterKind = RegisterKind;
2311 static std::unique_ptr<AArch64Operand>
2313 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2314 Op->VectorIndex.Val =
Idx;
2320 static std::unique_ptr<AArch64Operand>
2322 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2323 Op->MatrixTileList.RegMask = RegMask;
2330 const unsigned ElementWidth) {
2331 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2333 {{0, AArch64::ZAB0},
2334 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2335 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2336 {{8, AArch64::ZAB0},
2337 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2338 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2339 {{16, AArch64::ZAH0},
2340 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2341 {{16, AArch64::ZAH1},
2342 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2343 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2344 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2345 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2346 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2349 if (ElementWidth == 64)
2352 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2353 assert(!Regs.empty() &&
"Invalid tile or element width!");
2354 for (
auto OutReg : Regs)
2359 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2361 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2368 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2369 unsigned ShiftAmount,
2372 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2373 Op->ShiftedImm .Val = Val;
2374 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2380 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2384 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2386 Op->ImmRange.Last =
Last;
2391 static std::unique_ptr<AArch64Operand>
2393 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2394 Op->CondCode.Code =
Code;
2400 static std::unique_ptr<AArch64Operand>
2402 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2404 Op->FPImm.IsExact = IsExact;
2410 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2414 bool HasnXSModifier) {
2415 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2416 Op->Barrier.Val = Val;
2417 Op->Barrier.Data = Str.data();
2418 Op->Barrier.Length = Str.size();
2419 Op->Barrier.HasnXSModifier = HasnXSModifier;
2425 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2430 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2431 Op->SysReg.Data = Str.data();
2432 Op->SysReg.Length = Str.size();
2433 Op->SysReg.MRSReg = MRSReg;
2434 Op->SysReg.MSRReg = MSRReg;
2435 Op->SysReg.PStateField = PStateField;
2441 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2443 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2444 Op->SysCRImm.Val = Val;
2450 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2454 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2455 Op->Prefetch.Val = Val;
2456 Op->Barrier.Data = Str.data();
2457 Op->Barrier.Length = Str.size();
2463 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2467 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2468 Op->PSBHint.Val = Val;
2469 Op->PSBHint.Data = Str.data();
2470 Op->PSBHint.Length = Str.size();
2476 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2480 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2481 Op->BTIHint.Val = Val | 32;
2482 Op->BTIHint.Data = Str.data();
2483 Op->BTIHint.Length = Str.size();
2489 static std::unique_ptr<AArch64Operand>
2490 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2492 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2493 Op->MatrixReg.RegNum = RegNum;
2494 Op->MatrixReg.ElementWidth = ElementWidth;
2495 Op->MatrixReg.Kind =
Kind;
2501 static std::unique_ptr<AArch64Operand>
2503 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2504 Op->SVCR.PStateField = PStateField;
2505 Op->SVCR.Data = Str.data();
2506 Op->SVCR.Length = Str.size();
2512 static std::unique_ptr<AArch64Operand>
2515 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2516 Op->ShiftExtend.Type = ShOp;
2517 Op->ShiftExtend.Amount = Val;
2518 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2530 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2531 if (!getFPImmIsExact())
2538 OS <<
"<barrier " <<
Name <<
">";
2540 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2546 case k_ShiftedImm: {
2547 unsigned Shift = getShiftedImmShift();
2548 OS <<
"<shiftedimm ";
2549 OS << *getShiftedImmVal();
2555 OS << getFirstImmVal();
2556 OS <<
":" << getLastImmVal() <<
">";
2562 case k_VectorList: {
2563 OS <<
"<vectorlist ";
2564 unsigned Reg = getVectorListStart();
2565 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2566 OS <<
Reg + i * getVectorListStride() <<
" ";
2571 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2574 OS <<
"<sysreg: " << getSysReg() <<
'>';
2577 OS <<
"'" << getToken() <<
"'";
2580 OS <<
"c" << getSysCR();
2585 OS <<
"<prfop " <<
Name <<
">";
2587 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2591 OS << getPSBHintName();
2594 OS << getBTIHintName();
2596 case k_MatrixRegister:
2597 OS <<
"<matrix " << getMatrixReg() <<
">";
2599 case k_MatrixTileList: {
2600 OS <<
"<matrixlist ";
2601 unsigned RegMask = getMatrixTileListRegMask();
2602 unsigned MaxBits = 8;
2603 for (
unsigned I = MaxBits;
I > 0; --
I)
2604 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2613 OS <<
"<register " <<
getReg() <<
">";
2614 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2619 << getShiftExtendAmount();
2620 if (!hasShiftExtendAmount())
2636 .
Case(
"v0", AArch64::Q0)
2637 .
Case(
"v1", AArch64::Q1)
2638 .
Case(
"v2", AArch64::Q2)
2639 .
Case(
"v3", AArch64::Q3)
2640 .
Case(
"v4", AArch64::Q4)
2641 .
Case(
"v5", AArch64::Q5)
2642 .
Case(
"v6", AArch64::Q6)
2643 .
Case(
"v7", AArch64::Q7)
2644 .
Case(
"v8", AArch64::Q8)
2645 .
Case(
"v9", AArch64::Q9)
2646 .
Case(
"v10", AArch64::Q10)
2647 .
Case(
"v11", AArch64::Q11)
2648 .
Case(
"v12", AArch64::Q12)
2649 .
Case(
"v13", AArch64::Q13)
2650 .
Case(
"v14", AArch64::Q14)
2651 .
Case(
"v15", AArch64::Q15)
2652 .
Case(
"v16", AArch64::Q16)
2653 .
Case(
"v17", AArch64::Q17)
2654 .
Case(
"v18", AArch64::Q18)
2655 .
Case(
"v19", AArch64::Q19)
2656 .
Case(
"v20", AArch64::Q20)
2657 .
Case(
"v21", AArch64::Q21)
2658 .
Case(
"v22", AArch64::Q22)
2659 .
Case(
"v23", AArch64::Q23)
2660 .
Case(
"v24", AArch64::Q24)
2661 .
Case(
"v25", AArch64::Q25)
2662 .
Case(
"v26", AArch64::Q26)
2663 .
Case(
"v27", AArch64::Q27)
2664 .
Case(
"v28", AArch64::Q28)
2665 .
Case(
"v29", AArch64::Q29)
2666 .
Case(
"v30", AArch64::Q30)
2667 .
Case(
"v31", AArch64::Q31)
2676 RegKind VectorKind) {
2677 std::pair<int, int> Res = {-1, -1};
2679 switch (VectorKind) {
2680 case RegKind::NeonVector:
2683 .Case(
".1d", {1, 64})
2684 .Case(
".1q", {1, 128})
2686 .Case(
".2h", {2, 16})
2687 .Case(
".2b", {2, 8})
2688 .Case(
".2s", {2, 32})
2689 .Case(
".2d", {2, 64})
2692 .Case(
".4b", {4, 8})
2693 .Case(
".4h", {4, 16})
2694 .Case(
".4s", {4, 32})
2695 .Case(
".8b", {8, 8})
2696 .Case(
".8h", {8, 16})
2697 .Case(
".16b", {16, 8})
2702 .Case(
".h", {0, 16})
2703 .Case(
".s", {0, 32})
2704 .Case(
".d", {0, 64})
2707 case RegKind::SVEPredicateAsCounter:
2708 case RegKind::SVEPredicateVector:
2709 case RegKind::SVEDataVector:
2710 case RegKind::Matrix:
2714 .Case(
".h", {0, 16})
2715 .Case(
".s", {0, 32})
2716 .Case(
".d", {0, 64})
2717 .Case(
".q", {0, 128})
2724 if (Res == std::make_pair(-1, -1))
2725 return std::nullopt;
2727 return std::optional<std::pair<int, int>>(Res);
2736 .
Case(
"z0", AArch64::Z0)
2737 .
Case(
"z1", AArch64::Z1)
2738 .
Case(
"z2", AArch64::Z2)
2739 .
Case(
"z3", AArch64::Z3)
2740 .
Case(
"z4", AArch64::Z4)
2741 .
Case(
"z5", AArch64::Z5)
2742 .
Case(
"z6", AArch64::Z6)
2743 .
Case(
"z7", AArch64::Z7)
2744 .
Case(
"z8", AArch64::Z8)
2745 .
Case(
"z9", AArch64::Z9)
2746 .
Case(
"z10", AArch64::Z10)
2747 .
Case(
"z11", AArch64::Z11)
2748 .
Case(
"z12", AArch64::Z12)
2749 .
Case(
"z13", AArch64::Z13)
2750 .
Case(
"z14", AArch64::Z14)
2751 .
Case(
"z15", AArch64::Z15)
2752 .
Case(
"z16", AArch64::Z16)
2753 .
Case(
"z17", AArch64::Z17)
2754 .
Case(
"z18", AArch64::Z18)
2755 .
Case(
"z19", AArch64::Z19)
2756 .
Case(
"z20", AArch64::Z20)
2757 .
Case(
"z21", AArch64::Z21)
2758 .
Case(
"z22", AArch64::Z22)
2759 .
Case(
"z23", AArch64::Z23)
2760 .
Case(
"z24", AArch64::Z24)
2761 .
Case(
"z25", AArch64::Z25)
2762 .
Case(
"z26", AArch64::Z26)
2763 .
Case(
"z27", AArch64::Z27)
2764 .
Case(
"z28", AArch64::Z28)
2765 .
Case(
"z29", AArch64::Z29)
2766 .
Case(
"z30", AArch64::Z30)
2767 .
Case(
"z31", AArch64::Z31)
2773 .
Case(
"p0", AArch64::P0)
2774 .
Case(
"p1", AArch64::P1)
2775 .
Case(
"p2", AArch64::P2)
2776 .
Case(
"p3", AArch64::P3)
2777 .
Case(
"p4", AArch64::P4)
2778 .
Case(
"p5", AArch64::P5)
2779 .
Case(
"p6", AArch64::P6)
2780 .
Case(
"p7", AArch64::P7)
2781 .
Case(
"p8", AArch64::P8)
2782 .
Case(
"p9", AArch64::P9)
2783 .
Case(
"p10", AArch64::P10)
2784 .
Case(
"p11", AArch64::P11)
2785 .
Case(
"p12", AArch64::P12)
2786 .
Case(
"p13", AArch64::P13)
2787 .
Case(
"p14", AArch64::P14)
2788 .
Case(
"p15", AArch64::P15)
2794 .
Case(
"pn0", AArch64::PN0)
2795 .
Case(
"pn1", AArch64::PN1)
2796 .
Case(
"pn2", AArch64::PN2)
2797 .
Case(
"pn3", AArch64::PN3)
2798 .
Case(
"pn4", AArch64::PN4)
2799 .
Case(
"pn5", AArch64::PN5)
2800 .
Case(
"pn6", AArch64::PN6)
2801 .
Case(
"pn7", AArch64::PN7)
2802 .
Case(
"pn8", AArch64::PN8)
2803 .
Case(
"pn9", AArch64::PN9)
2804 .
Case(
"pn10", AArch64::PN10)
2805 .
Case(
"pn11", AArch64::PN11)
2806 .
Case(
"pn12", AArch64::PN12)
2807 .
Case(
"pn13", AArch64::PN13)
2808 .
Case(
"pn14", AArch64::PN14)
2809 .
Case(
"pn15", AArch64::PN15)
2815 .
Case(
"za0.d", AArch64::ZAD0)
2816 .
Case(
"za1.d", AArch64::ZAD1)
2817 .
Case(
"za2.d", AArch64::ZAD2)
2818 .
Case(
"za3.d", AArch64::ZAD3)
2819 .
Case(
"za4.d", AArch64::ZAD4)
2820 .
Case(
"za5.d", AArch64::ZAD5)
2821 .
Case(
"za6.d", AArch64::ZAD6)
2822 .
Case(
"za7.d", AArch64::ZAD7)
2823 .
Case(
"za0.s", AArch64::ZAS0)
2824 .
Case(
"za1.s", AArch64::ZAS1)
2825 .
Case(
"za2.s", AArch64::ZAS2)
2826 .
Case(
"za3.s", AArch64::ZAS3)
2827 .
Case(
"za0.h", AArch64::ZAH0)
2828 .
Case(
"za1.h", AArch64::ZAH1)
2829 .
Case(
"za0.b", AArch64::ZAB0)
2835 .
Case(
"za", AArch64::ZA)
2836 .
Case(
"za0.q", AArch64::ZAQ0)
2837 .
Case(
"za1.q", AArch64::ZAQ1)
2838 .
Case(
"za2.q", AArch64::ZAQ2)
2839 .
Case(
"za3.q", AArch64::ZAQ3)
2840 .
Case(
"za4.q", AArch64::ZAQ4)
2841 .
Case(
"za5.q", AArch64::ZAQ5)
2842 .
Case(
"za6.q", AArch64::ZAQ6)
2843 .
Case(
"za7.q", AArch64::ZAQ7)
2844 .
Case(
"za8.q", AArch64::ZAQ8)
2845 .
Case(
"za9.q", AArch64::ZAQ9)
2846 .
Case(
"za10.q", AArch64::ZAQ10)
2847 .
Case(
"za11.q", AArch64::ZAQ11)
2848 .
Case(
"za12.q", AArch64::ZAQ12)
2849 .
Case(
"za13.q", AArch64::ZAQ13)
2850 .
Case(
"za14.q", AArch64::ZAQ14)
2851 .
Case(
"za15.q", AArch64::ZAQ15)
2852 .
Case(
"za0.d", AArch64::ZAD0)
2853 .
Case(
"za1.d", AArch64::ZAD1)
2854 .
Case(
"za2.d", AArch64::ZAD2)
2855 .
Case(
"za3.d", AArch64::ZAD3)
2856 .
Case(
"za4.d", AArch64::ZAD4)
2857 .
Case(
"za5.d", AArch64::ZAD5)
2858 .
Case(
"za6.d", AArch64::ZAD6)
2859 .
Case(
"za7.d", AArch64::ZAD7)
2860 .
Case(
"za0.s", AArch64::ZAS0)
2861 .
Case(
"za1.s", AArch64::ZAS1)
2862 .
Case(
"za2.s", AArch64::ZAS2)
2863 .
Case(
"za3.s", AArch64::ZAS3)
2864 .
Case(
"za0.h", AArch64::ZAH0)
2865 .
Case(
"za1.h", AArch64::ZAH1)
2866 .
Case(
"za0.b", AArch64::ZAB0)
2867 .
Case(
"za0h.q", AArch64::ZAQ0)
2868 .
Case(
"za1h.q", AArch64::ZAQ1)
2869 .
Case(
"za2h.q", AArch64::ZAQ2)
2870 .
Case(
"za3h.q", AArch64::ZAQ3)
2871 .
Case(
"za4h.q", AArch64::ZAQ4)
2872 .
Case(
"za5h.q", AArch64::ZAQ5)
2873 .
Case(
"za6h.q", AArch64::ZAQ6)
2874 .
Case(
"za7h.q", AArch64::ZAQ7)
2875 .
Case(
"za8h.q", AArch64::ZAQ8)
2876 .
Case(
"za9h.q", AArch64::ZAQ9)
2877 .
Case(
"za10h.q", AArch64::ZAQ10)
2878 .
Case(
"za11h.q", AArch64::ZAQ11)
2879 .
Case(
"za12h.q", AArch64::ZAQ12)
2880 .
Case(
"za13h.q", AArch64::ZAQ13)
2881 .
Case(
"za14h.q", AArch64::ZAQ14)
2882 .
Case(
"za15h.q", AArch64::ZAQ15)
2883 .
Case(
"za0h.d", AArch64::ZAD0)
2884 .
Case(
"za1h.d", AArch64::ZAD1)
2885 .
Case(
"za2h.d", AArch64::ZAD2)
2886 .
Case(
"za3h.d", AArch64::ZAD3)
2887 .
Case(
"za4h.d", AArch64::ZAD4)
2888 .
Case(
"za5h.d", AArch64::ZAD5)
2889 .
Case(
"za6h.d", AArch64::ZAD6)
2890 .
Case(
"za7h.d", AArch64::ZAD7)
2891 .
Case(
"za0h.s", AArch64::ZAS0)
2892 .
Case(
"za1h.s", AArch64::ZAS1)
2893 .
Case(
"za2h.s", AArch64::ZAS2)
2894 .
Case(
"za3h.s", AArch64::ZAS3)
2895 .
Case(
"za0h.h", AArch64::ZAH0)
2896 .
Case(
"za1h.h", AArch64::ZAH1)
2897 .
Case(
"za0h.b", AArch64::ZAB0)
2898 .
Case(
"za0v.q", AArch64::ZAQ0)
2899 .
Case(
"za1v.q", AArch64::ZAQ1)
2900 .
Case(
"za2v.q", AArch64::ZAQ2)
2901 .
Case(
"za3v.q", AArch64::ZAQ3)
2902 .
Case(
"za4v.q", AArch64::ZAQ4)
2903 .
Case(
"za5v.q", AArch64::ZAQ5)
2904 .
Case(
"za6v.q", AArch64::ZAQ6)
2905 .
Case(
"za7v.q", AArch64::ZAQ7)
2906 .
Case(
"za8v.q", AArch64::ZAQ8)
2907 .
Case(
"za9v.q", AArch64::ZAQ9)
2908 .
Case(
"za10v.q", AArch64::ZAQ10)
2909 .
Case(
"za11v.q", AArch64::ZAQ11)
2910 .
Case(
"za12v.q", AArch64::ZAQ12)
2911 .
Case(
"za13v.q", AArch64::ZAQ13)
2912 .
Case(
"za14v.q", AArch64::ZAQ14)
2913 .
Case(
"za15v.q", AArch64::ZAQ15)
2914 .
Case(
"za0v.d", AArch64::ZAD0)
2915 .
Case(
"za1v.d", AArch64::ZAD1)
2916 .
Case(
"za2v.d", AArch64::ZAD2)
2917 .
Case(
"za3v.d", AArch64::ZAD3)
2918 .
Case(
"za4v.d", AArch64::ZAD4)
2919 .
Case(
"za5v.d", AArch64::ZAD5)
2920 .
Case(
"za6v.d", AArch64::ZAD6)
2921 .
Case(
"za7v.d", AArch64::ZAD7)
2922 .
Case(
"za0v.s", AArch64::ZAS0)
2923 .
Case(
"za1v.s", AArch64::ZAS1)
2924 .
Case(
"za2v.s", AArch64::ZAS2)
2925 .
Case(
"za3v.s", AArch64::ZAS3)
2926 .
Case(
"za0v.h", AArch64::ZAH0)
2927 .
Case(
"za1v.h", AArch64::ZAH1)
2928 .
Case(
"za0v.b", AArch64::ZAB0)
2934 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2939 StartLoc = getLoc();
2946unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
2948 unsigned RegNum = 0;
2950 return Kind == RegKind::SVEDataVector ? RegNum : 0;
2953 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
2956 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
2959 return Kind == RegKind::NeonVector ? RegNum : 0;
2962 return Kind == RegKind::Matrix ? RegNum : 0;
2964 if (
Name.equals_insensitive(
"zt0"))
2965 return Kind == RegKind::LookupTable ? AArch64::ZT0 : 0;
2969 return (Kind == RegKind::Scalar) ? RegNum : 0;
2974 .
Case(
"fp", AArch64::FP)
2975 .
Case(
"lr", AArch64::LR)
2976 .
Case(
"x31", AArch64::XZR)
2977 .
Case(
"w31", AArch64::WZR)
2979 return Kind == RegKind::Scalar ? RegNum : 0;
2984 auto Entry = RegisterReqs.
find(
Name.lower());
2985 if (Entry == RegisterReqs.
end())
2989 if (Kind == Entry->getValue().first)
2990 RegNum = Entry->getValue().second;
2995unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2997 case RegKind::Scalar:
2998 case RegKind::NeonVector:
2999 case RegKind::SVEDataVector:
3001 case RegKind::Matrix:
3002 case RegKind::SVEPredicateVector:
3003 case RegKind::SVEPredicateAsCounter:
3005 case RegKind::LookupTable:
3020 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3034 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3037 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3038 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3042 if (BadNum || CRNum > 15)
3043 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3047 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3056 unsigned MaxVal = 63;
3062 if (getParser().parseExpression(ImmVal))
3067 return TokError(
"immediate value expected for prefetch operand");
3070 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3073 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3074 Operands.push_back(AArch64Operand::CreatePrefetch(
3075 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3080 return TokError(
"prefetch hint expected");
3082 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3084 return TokError(
"prefetch hint expected");
3086 Operands.push_back(AArch64Operand::CreatePrefetch(
3087 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3093template <
bool IsSVEPrefetch>
3099 if (IsSVEPrefetch) {
3100 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3101 return std::optional<unsigned>(Res->Encoding);
3102 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3103 return std::optional<unsigned>(Res->Encoding);
3104 return std::optional<unsigned>();
3107 auto LookupByEncoding = [](
unsigned E) {
3108 if (IsSVEPrefetch) {
3109 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3110 return std::optional<StringRef>(Res->Name);
3111 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3112 return std::optional<StringRef>(Res->Name);
3113 return std::optional<StringRef>();
3115 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3122 if (getParser().parseExpression(ImmVal))
3127 return TokError(
"immediate value expected for prefetch operand");
3130 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3133 auto PRFM = LookupByEncoding(MCE->
getValue());
3134 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3140 return TokError(
"prefetch hint expected");
3142 auto PRFM = LookupByName(Tok.
getString());
3144 return TokError(
"prefetch hint expected");
3146 Operands.push_back(AArch64Operand::CreatePrefetch(
3147 *PRFM, Tok.
getString(), S, getContext()));
3157 return TokError(
"invalid operand for instruction");
3159 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3161 return TokError(
"invalid operand for instruction");
3163 Operands.push_back(AArch64Operand::CreatePSBHint(
3164 PSB->Encoding, Tok.
getString(), S, getContext()));
3170 SMLoc StartLoc = getLoc();
3176 auto RegTok = getTok();
3177 if (!tryParseScalarRegister(RegNum).isSuccess())
3180 if (RegNum != AArch64::XZR) {
3181 getLexer().UnLex(RegTok);
3188 if (!tryParseScalarRegister(RegNum).isSuccess())
3189 return TokError(
"expected register operand");
3191 if (RegNum != AArch64::XZR)
3192 return TokError(
"xzr must be followed by xzr");
3196 Operands.push_back(AArch64Operand::CreateReg(
3197 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3207 return TokError(
"invalid operand for instruction");
3209 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3211 return TokError(
"invalid operand for instruction");
3213 Operands.push_back(AArch64Operand::CreateBTIHint(
3214 BTI->Encoding, Tok.
getString(), S, getContext()));
3223 const MCExpr *Expr =
nullptr;
3229 if (parseSymbolicImmVal(Expr))
3235 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3245 return Error(S,
"gotpage label reference not allowed an addend");
3255 return Error(S,
"page or gotpage label reference expected");
3263 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3272 const MCExpr *Expr =
nullptr;
3281 if (parseSymbolicImmVal(Expr))
3287 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3294 return Error(S,
"unexpected adr label");
3299 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3304template <
bool AddFPZeroAsLiteral>
3317 return TokError(
"invalid floating point immediate");
3322 if (Tok.
getIntVal() > 255 || isNegative)
3323 return TokError(
"encoded floating point value out of range");
3327 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3330 APFloat RealVal(APFloat::IEEEdouble());
3332 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3334 return TokError(
"invalid floating point representation");
3337 RealVal.changeSign();
3339 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3340 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3341 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3343 Operands.push_back(AArch64Operand::CreateFPImm(
3344 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3369 if (parseSymbolicImmVal(Imm))
3373 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3380 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3382 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3384 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3390 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3391 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3399 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3401 int64_t ShiftAmount = getTok().getIntVal();
3403 if (ShiftAmount < 0)
3404 return Error(getLoc(),
"positive shift amount required");
3408 if (ShiftAmount == 0 && Imm !=
nullptr) {
3410 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3414 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3415 getLoc(), getContext()));
3422AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3459 Suggestion =
"nfrst";
3466 bool invertCondCode) {
3472 std::string Suggestion;
3475 std::string
Msg =
"invalid condition code";
3476 if (!Suggestion.empty())
3477 Msg +=
", did you mean " + Suggestion +
"?";
3478 return TokError(Msg);
3482 if (invertCondCode) {
3484 return TokError(
"condition codes AL and NV are invalid for this instruction");
3489 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3498 return TokError(
"invalid operand for instruction");
3500 unsigned PStateImm = -1;
3501 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3504 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3505 PStateImm = SVCR->Encoding;
3508 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3519 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3521 unsigned ElementWidth = 0;
3522 auto DotPosition =
Name.find(
'.');
3524 const auto &KindRes =
3528 "Expected the register to be followed by element width suffix");
3529 ElementWidth = KindRes->second;
3531 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3532 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3537 if (parseOperand(
Operands,
false,
false))
3544 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3548 size_t DotPosition =
Name.find(
'.');
3556 .
Case(
"h", MatrixKind::Row)
3557 .
Case(
"v", MatrixKind::Col)
3564 "Expected the register to be followed by element width suffix");
3565 unsigned ElementWidth = KindRes->second;
3569 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3570 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3575 if (parseOperand(
Operands,
false,
false))
3617 return TokError(
"expected #imm after shift specifier");
3623 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3632 return Error(
E,
"expected integer shift amount");
3635 if (getParser().parseExpression(ImmVal))
3640 return Error(
E,
"expected constant '#imm' after shift specifier");
3643 Operands.push_back(AArch64Operand::CreateShiftExtend(
3644 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3652 {
"crc", {AArch64::FeatureCRC}},
3653 {
"sm4", {AArch64::FeatureSM4}},
3654 {
"sha3", {AArch64::FeatureSHA3}},
3655 {
"sha2", {AArch64::FeatureSHA2}},
3656 {
"aes", {AArch64::FeatureAES}},
3657 {
"crypto", {AArch64::FeatureCrypto}},
3658 {
"fp", {AArch64::FeatureFPARMv8}},
3659 {
"simd", {AArch64::FeatureNEON}},
3660 {
"ras", {AArch64::FeatureRAS}},
3661 {
"rasv2", {AArch64::FeatureRASv2}},
3662 {
"lse", {AArch64::FeatureLSE}},
3663 {
"predres", {AArch64::FeaturePredRes}},
3664 {
"predres2", {AArch64::FeatureSPECRES2}},
3665 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3666 {
"mte", {AArch64::FeatureMTE}},
3667 {
"memtag", {AArch64::FeatureMTE}},
3668 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3669 {
"pan", {AArch64::FeaturePAN}},
3670 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3671 {
"ccpp", {AArch64::FeatureCCPP}},
3672 {
"rcpc", {AArch64::FeatureRCPC}},
3673 {
"rng", {AArch64::FeatureRandGen}},
3674 {
"sve", {AArch64::FeatureSVE}},
3675 {
"sve2", {AArch64::FeatureSVE2}},
3676 {
"sve2-aes", {AArch64::FeatureSVE2AES}},
3677 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3678 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3679 {
"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3680 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3681 {
"b16b16", {AArch64::FeatureB16B16}},
3682 {
"ls64", {AArch64::FeatureLS64}},
3683 {
"xs", {AArch64::FeatureXS}},
3684 {
"pauth", {AArch64::FeaturePAuth}},
3685 {
"flagm", {AArch64::FeatureFlagM}},
3686 {
"rme", {AArch64::FeatureRME}},
3687 {
"sme", {AArch64::FeatureSME}},
3688 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3689 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3690 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3691 {
"sme2", {AArch64::FeatureSME2}},
3692 {
"sme2p1", {AArch64::FeatureSME2p1}},
3693 {
"hbc", {AArch64::FeatureHBC}},
3694 {
"mops", {AArch64::FeatureMOPS}},
3695 {
"mec", {AArch64::FeatureMEC}},
3696 {
"the", {AArch64::FeatureTHE}},
3697 {
"d128", {AArch64::FeatureD128}},
3698 {
"lse128", {AArch64::FeatureLSE128}},
3699 {
"ite", {AArch64::FeatureITE}},
3700 {
"cssc", {AArch64::FeatureCSSC}},
3701 {
"rcpc3", {AArch64::FeatureRCPC3}},
3702 {
"gcs", {AArch64::FeatureGCS}},
3703 {
"bf16", {AArch64::FeatureBF16}},
3704 {
"compnum", {AArch64::FeatureComplxNum}},
3705 {
"dotprod", {AArch64::FeatureDotProd}},
3706 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3707 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3708 {
"fp16", {AArch64::FeatureFullFP16}},
3709 {
"fp16fml", {AArch64::FeatureFP16FML}},
3710 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3711 {
"lor", {AArch64::FeatureLOR}},
3712 {
"profile", {AArch64::FeatureSPE}},
3716 {
"rdm", {AArch64::FeatureRDM}},
3717 {
"rdma", {AArch64::FeatureRDM}},
3718 {
"sb", {AArch64::FeatureSB}},
3719 {
"ssbs", {AArch64::FeatureSSBS}},
3720 {
"tme", {AArch64::FeatureTME}},
3721 {
"fpmr", {AArch64::FeatureFPMR}},
3722 {
"fp8", {AArch64::FeatureFP8}},
3723 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3724 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3725 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3726 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3727 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3728 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3729 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3730 {
"lut", {AArch64::FeatureLUT}},
3731 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3732 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3733 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3734 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3735 {
"cpa", {AArch64::FeatureCPA}},
3736 {
"tlbiw", {AArch64::FeatureTLBIW}},
3740 if (FBS[AArch64::HasV8_0aOps])
3742 if (FBS[AArch64::HasV8_1aOps])
3744 else if (FBS[AArch64::HasV8_2aOps])
3746 else if (FBS[AArch64::HasV8_3aOps])
3748 else if (FBS[AArch64::HasV8_4aOps])
3750 else if (FBS[AArch64::HasV8_5aOps])
3752 else if (FBS[AArch64::HasV8_6aOps])
3754 else if (FBS[AArch64::HasV8_7aOps])
3756 else if (FBS[AArch64::HasV8_8aOps])
3758 else if (FBS[AArch64::HasV8_9aOps])
3760 else if (FBS[AArch64::HasV9_0aOps])
3762 else if (FBS[AArch64::HasV9_1aOps])
3764 else if (FBS[AArch64::HasV9_2aOps])
3766 else if (FBS[AArch64::HasV9_3aOps])
3768 else if (FBS[AArch64::HasV9_4aOps])
3770 else if (FBS[AArch64::HasV9_5aOps])
3772 else if (FBS[AArch64::HasV8_0rOps])
3781 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3788 const uint16_t Cm = (Encoding & 0x78) >> 3;
3789 const uint16_t Cn = (Encoding & 0x780) >> 7;
3790 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3795 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3797 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3799 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3802 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3809 if (
Name.contains(
'.'))
3810 return TokError(
"invalid operand");
3813 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3819 if (Mnemonic ==
"ic") {
3822 return TokError(
"invalid operand for IC instruction");
3823 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3824 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3826 return TokError(Str);
3829 }
else if (Mnemonic ==
"dc") {
3832 return TokError(
"invalid operand for DC instruction");
3833 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3834 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3836 return TokError(Str);
3839 }
else if (Mnemonic ==
"at") {
3842 return TokError(
"invalid operand for AT instruction");
3843 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3844 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3846 return TokError(Str);
3849 }
else if (Mnemonic ==
"tlbi") {
3852 return TokError(
"invalid operand for TLBI instruction");
3853 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3854 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3856 return TokError(Str);
3859 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3861 if (
Op.lower() !=
"rctx")
3862 return TokError(
"invalid operand for prediction restriction instruction");
3864 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3865 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3866 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3868 if (Mnemonic ==
"cosp" && !hasSpecres2)
3869 return TokError(
"COSP requires: predres2");
3871 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3873 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3874 : Mnemonic ==
"dvp" ? 0b101
3875 : Mnemonic ==
"cosp" ? 0b110
3876 : Mnemonic ==
"cpp" ? 0b111
3879 "Invalid mnemonic for prediction restriction instruction");
3880 const auto SYS_3_7_3 = 0b01101110011;
3881 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3883 createSysAlias(Encoding,
Operands, S);
3888 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3889 bool HasRegister =
false;
3894 return TokError(
"expected register operand");
3898 if (ExpectRegister && !HasRegister)
3899 return TokError(
"specified " + Mnemonic +
" op requires a register");
3900 else if (!ExpectRegister && HasRegister)
3901 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3913 if (
Name.contains(
'.'))
3914 return TokError(
"invalid operand");
3918 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
3924 if (Mnemonic ==
"tlbip") {
3925 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
3926 if (HasnXSQualifier) {
3927 Op =
Op.drop_back(3);
3931 return TokError(
"invalid operand for TLBIP instruction");
3933 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
3940 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
3941 std::string Str(
"TLBIP " +
Name +
" requires: ");
3943 return TokError(Str);
3954 return TokError(
"expected register identifier");
3959 return TokError(
"specified " + Mnemonic +
3960 " op requires a pair of registers");
3973 return TokError(
"'csync' operand expected");
3977 SMLoc ExprLoc = getLoc();
3979 if (getParser().parseExpression(ImmVal))
3983 return Error(ExprLoc,
"immediate value expected for barrier operand");
3985 if (Mnemonic ==
"dsb" &&
Value > 15) {
3992 if (Value < 0 || Value > 15)
3993 return Error(ExprLoc,
"barrier operand out of range");
3994 auto DB = AArch64DB::lookupDBByEncoding(
Value);
3995 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
3996 ExprLoc, getContext(),
4002 return TokError(
"invalid operand for instruction");
4005 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4006 auto DB = AArch64DB::lookupDBByName(Operand);
4008 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4009 return TokError(
"'sy' or #imm operand expected");
4011 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4012 return TokError(
"'csync' operand expected");
4014 if (Mnemonic ==
"dsb") {
4019 return TokError(
"invalid barrier option name");
4022 Operands.push_back(AArch64Operand::CreateBarrier(
4023 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4024 getContext(),
false ));
4034 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4035 if (Mnemonic !=
"dsb")
4041 SMLoc ExprLoc = getLoc();
4042 if (getParser().parseExpression(ImmVal))
4046 return Error(ExprLoc,
"immediate value expected for barrier operand");
4051 return Error(ExprLoc,
"barrier operand out of range");
4052 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4053 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4054 ExprLoc, getContext(),
4060 return TokError(
"invalid operand for instruction");
4063 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4066 return TokError(
"invalid barrier option name");
4069 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4070 getContext(),
true ));
4082 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4087 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4088 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4089 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4093 unsigned PStateImm = -1;
4094 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4095 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4096 PStateImm = PState15->Encoding;
4098 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4099 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4100 PStateImm = PState1->Encoding;
4104 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4105 PStateImm, getContext()));
4120 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4128 unsigned ElementWidth = KindRes->second;
4130 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4131 S, getLoc(), getContext()));
4136 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4138 return tryParseVectorIndex(
Operands).isFailure();
4142 SMLoc SIdx = getLoc();
4145 if (getParser().parseExpression(ImmVal))
4149 return TokError(
"immediate value expected for vector index");
4156 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4169 RegKind MatchKind) {
4178 size_t Start = 0, Next =
Name.find(
'.');
4180 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4186 return TokError(
"invalid vector kind qualifier");
4197ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4200 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4202 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4207template <RegKind RK>
4211 const SMLoc S = getLoc();
4214 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4222 unsigned ElementWidth = KindRes->second;
4223 Operands.push_back(AArch64Operand::CreateVectorReg(
4224 RegNum, RK, ElementWidth, S,
4225 getLoc(), getContext()));
4228 if (RK == RegKind::SVEPredicateAsCounter) {
4235 if (parseOperand(
Operands,
false,
false))
4246 return Error(S,
"not expecting size suffix");
4249 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4254 auto Pred = getTok().getString().lower();
4255 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4256 return Error(getLoc(),
"expecting 'z' predication");
4258 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4259 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4262 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4263 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4272 if (!tryParseNeonVectorRegister(
Operands))
4275 if (tryParseZTOperand(
Operands).isSuccess())
4279 if (tryParseGPROperand<false>(
Operands).isSuccess())
4285bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4286 bool HasELFModifier =
false;
4290 HasELFModifier =
true;
4293 return TokError(
"expect relocation specifier in operand after ':'");
4295 std::string LowerCase = getTok().getIdentifier().lower();
4346 return TokError(
"expect relocation specifier in operand after ':'");
4350 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4354 if (getParser().parseExpression(ImmVal))
4367 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4370 size_t DotPosition =
Name.find(
'.');
4379 const std::optional<std::pair<int, int>> &KindRes =
4383 "Expected the register to be followed by element width suffix");
4384 ElementWidth = KindRes->second;
4391 auto LCurly = getTok();
4396 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4397 0, S, getLoc(), getContext()));
4402 if (getTok().getString().equals_insensitive(
"za")) {
4408 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4409 0xFF, S, getLoc(), getContext()));
4413 SMLoc TileLoc = getLoc();
4415 unsigned FirstReg, ElementWidth;
4416 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4417 if (!ParseRes.isSuccess()) {
4418 getLexer().UnLex(LCurly);
4424 unsigned PrevReg = FirstReg;
4427 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4430 SeenRegs.
insert(FirstReg);
4434 unsigned Reg, NextElementWidth;
4435 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4436 if (!ParseRes.isSuccess())
4440 if (ElementWidth != NextElementWidth)
4441 return Error(TileLoc,
"mismatched register size suffix");
4444 Warning(TileLoc,
"tile list not in ascending order");
4447 Warning(TileLoc,
"duplicate tile in list");
4450 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4459 unsigned RegMask = 0;
4460 for (
auto Reg : DRegs)
4464 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4469template <RegKind VectorKind>
4479 auto RegTok = getTok();
4480 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4481 if (ParseRes.isSuccess()) {
4488 RegTok.getString().equals_insensitive(
"zt0"))
4492 (ParseRes.isNoMatch() && NoMatchIsError &&
4493 !RegTok.getString().starts_with_insensitive(
"za")))
4494 return Error(Loc,
"vector register expected");
4499 int NumRegs = getNumRegsForRegKind(VectorKind);
4501 auto LCurly = getTok();
4506 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4510 if (ParseRes.isNoMatch())
4513 if (!ParseRes.isSuccess())
4516 int64_t PrevReg = FirstReg;
4521 SMLoc Loc = getLoc();
4525 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4526 if (!ParseRes.isSuccess())
4530 if (Kind != NextKind)
4531 return Error(Loc,
"mismatched register size suffix");
4534 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4536 if (Space == 0 || Space > 3)
4537 return Error(Loc,
"invalid number of vectors");
4542 bool HasCalculatedStride =
false;
4544 SMLoc Loc = getLoc();
4547 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4548 if (!ParseRes.isSuccess())
4552 if (Kind != NextKind)
4553 return Error(Loc,
"mismatched register size suffix");
4555 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4556 unsigned PrevRegVal =
4557 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4558 if (!HasCalculatedStride) {
4559 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4560 : (RegVal + NumRegs - PrevRegVal);
4561 HasCalculatedStride =
true;
4565 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4566 return Error(Loc,
"registers must have the same sequential stride");
4577 return Error(S,
"invalid number of vectors");
4579 unsigned NumElements = 0;
4580 unsigned ElementWidth = 0;
4581 if (!
Kind.empty()) {
4583 std::tie(NumElements, ElementWidth) = *VK;
4586 Operands.push_back(AArch64Operand::CreateVectorList(
4587 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4588 getLoc(), getContext()));
4595 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4596 if (!ParseRes.isSuccess())
4599 return tryParseVectorIndex(
Operands).isFailure();
4603 SMLoc StartLoc = getLoc();
4611 Operands.push_back(AArch64Operand::CreateReg(
4612 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4619 return Error(getLoc(),
"index must be absent or #0");
4622 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4623 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4624 return Error(getLoc(),
"index must be absent or #0");
4626 Operands.push_back(AArch64Operand::CreateReg(
4627 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4632 SMLoc StartLoc = getLoc();
4636 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4641 Operands.push_back(AArch64Operand::CreateReg(
4642 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4648 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4650 if (getParser().parseExpression(ImmVal))
4654 return TokError(
"immediate value expected for vector index");
4655 Operands.push_back(AArch64Operand::CreateImm(
4657 getLoc(), getContext()));
4659 if (parseOptionalMulOperand(
Operands))
4664 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4669template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4671 SMLoc StartLoc = getLoc();
4680 Operands.push_back(AArch64Operand::CreateReg(
4681 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4690 Res = tryParseOptionalShiftExtend(ExtOpnd);
4694 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4695 Operands.push_back(AArch64Operand::CreateReg(
4696 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4697 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4698 Ext->hasShiftExtendAmount()));
4712 if (!getTok().getString().equals_insensitive(
"mul") ||
4713 !(NextIsVL || NextIsHash))
4717 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4722 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4734 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4735 Operands.push_back(AArch64Operand::CreateImm(
4742 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4748 auto Tok = Parser.
getTok();
4753 .
Case(
"vgx2",
"vgx2")
4754 .
Case(
"vgx4",
"vgx4")
4766 auto Tok = getTok();
4776 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4785 bool invertCondCode) {
4789 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4803 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4808 getLexer().UnLex(SavedTok);
4812 switch (getLexer().getKind()) {
4816 if (parseSymbolicImmVal(Expr))
4817 return Error(S,
"invalid operand");
4820 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
4821 return parseOptionalShiftExtend(getTok());
4825 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4830 return parseOperand(
Operands,
false,
false);
4833 if (!parseNeonVectorList(
Operands))
4837 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4842 return parseOperand(
Operands,
false,
false);
4847 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4849 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4854 return parseCondCode(
Operands, invertCondCode);
4868 Res = tryParseOptionalShiftExtend(
Operands);
4871 getLexer().UnLex(SavedTok);
4878 if (!parseOptionalMulOperand(
Operands))
4883 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
4885 return parseKeywordOperand(
Operands);
4891 if (getParser().parseExpression(IdVal))
4894 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
4906 bool isNegative =
false;
4922 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
4923 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
4924 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
4925 return TokError(
"unexpected floating point literal");
4926 else if (IntVal != 0 || isNegative)
4927 return TokError(
"expected floating-point constant #0.0");
4930 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
4931 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
4936 if (parseSymbolicImmVal(ImmVal))
4940 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
4943 return parseOptionalShiftExtend(Tok);
4946 SMLoc Loc = getLoc();
4947 if (Mnemonic !=
"ldr")
4948 return TokError(
"unexpected token in operand");
4950 const MCExpr *SubExprVal;
4951 if (getParser().parseExpression(SubExprVal))
4955 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
4956 return Error(Loc,
"Only valid when first operand is register");
4959 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4965 if (isa<MCConstantExpr>(SubExprVal)) {
4966 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4967 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4972 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4973 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
4974 Operands.push_back(AArch64Operand::CreateImm(
4978 ShiftAmt,
true, S, E, Ctx));
4984 return Error(Loc,
"Immediate too large for register");
4988 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4989 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
4995bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4996 const MCExpr *Expr =
nullptr;
4998 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
5001 if (
check(!
Value, L,
"expected constant expression"))
5003 Out =
Value->getValue();
5007bool AArch64AsmParser::parseComma() {
5015bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5019 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
5024 unsigned RangeEnd =
Last;
5025 if (
Base == AArch64::X0) {
5026 if (
Last == AArch64::FP) {
5027 RangeEnd = AArch64::X28;
5028 if (Reg == AArch64::FP) {
5033 if (
Last == AArch64::LR) {
5034 RangeEnd = AArch64::X28;
5035 if (Reg == AArch64::FP) {
5038 }
else if (Reg == AArch64::LR) {
5045 if (
check(Reg < First || Reg > RangeEnd, Start,
5046 Twine(
"expected register in range ") +
5056 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5057 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5059 if (AOp1.isVectorList() && AOp2.isVectorList())
5060 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5061 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5062 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5064 if (!AOp1.isReg() || !AOp2.isReg())
5067 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5068 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5071 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5072 "Testing equality of non-scalar registers not supported");
5075 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5077 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5079 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5081 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5093 .
Case(
"beq",
"b.eq")
5094 .
Case(
"bne",
"b.ne")
5095 .
Case(
"bhs",
"b.hs")
5096 .
Case(
"bcs",
"b.cs")
5097 .
Case(
"blo",
"b.lo")
5098 .
Case(
"bcc",
"b.cc")
5099 .
Case(
"bmi",
"b.mi")
5100 .
Case(
"bpl",
"b.pl")
5101 .
Case(
"bvs",
"b.vs")
5102 .
Case(
"bvc",
"b.vc")
5103 .
Case(
"bhi",
"b.hi")
5104 .
Case(
"bls",
"b.ls")
5105 .
Case(
"bge",
"b.ge")
5106 .
Case(
"blt",
"b.lt")
5107 .
Case(
"bgt",
"b.gt")
5108 .
Case(
"ble",
"b.le")
5109 .
Case(
"bal",
"b.al")
5110 .
Case(
"bnv",
"b.nv")
5115 getTok().getIdentifier().lower() ==
".req") {
5116 parseDirectiveReq(
Name, NameLoc);
5123 size_t Start = 0, Next =
Name.find(
'.');
5128 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5129 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5130 return parseSysAlias(Head, NameLoc,
Operands);
5133 if (Head ==
"tlbip")
5134 return parseSyspAlias(Head, NameLoc,
Operands);
5136 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5142 Next =
Name.find(
'.', Start + 1);
5143 Head =
Name.slice(Start + 1, Next);
5147 std::string Suggestion;
5150 std::string
Msg =
"invalid condition code";
5151 if (!Suggestion.empty())
5152 Msg +=
", did you mean " + Suggestion +
"?";
5153 return Error(SuffixLoc, Msg);
5155 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5158 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5164 Next =
Name.find(
'.', Start + 1);
5165 Head =
Name.slice(Start, Next);
5168 Operands.push_back(AArch64Operand::CreateToken(
5169 Head, SuffixLoc, getContext(),
true));
5174 bool condCodeFourthOperand =
5175 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5176 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5177 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5185 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5186 bool condCodeThirdOperand =
5187 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5195 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5196 (
N == 3 && condCodeThirdOperand) ||
5197 (
N == 2 && condCodeSecondOperand),
5198 condCodeSecondOperand || condCodeThirdOperand)) {
5218 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5221 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5224 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5237 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5238 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5239 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5240 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5241 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5242 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5243 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5249bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5258 PrefixInfo
Prefix = NextPrefix;
5259 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5271 return Error(IDLoc,
"instruction is unpredictable when following a"
5272 " movprfx, suggest replacing movprfx with mov");
5276 return Error(Loc[0],
"instruction is unpredictable when following a"
5277 " movprfx writing to a different destination");
5284 return Error(Loc[0],
"instruction is unpredictable when following a"
5285 " movprfx and destination also used as non-destructive"
5289 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5290 if (
Prefix.isPredicated()) {
5304 return Error(IDLoc,
"instruction is unpredictable when following a"
5305 " predicated movprfx, suggest using unpredicated movprfx");
5309 return Error(IDLoc,
"instruction is unpredictable when following a"
5310 " predicated movprfx using a different general predicate");
5314 return Error(IDLoc,
"instruction is unpredictable when following a"
5315 " predicated movprfx with a different element size");
5323 case AArch64::LDPSWpre:
5324 case AArch64::LDPWpost:
5325 case AArch64::LDPWpre:
5326 case AArch64::LDPXpost:
5327 case AArch64::LDPXpre: {
5332 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5333 "is also a destination");
5335 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5336 "is also a destination");
5339 case AArch64::LDR_ZA:
5340 case AArch64::STR_ZA: {
5343 return Error(Loc[1],
5344 "unpredictable instruction, immediate and offset mismatch.");
5347 case AArch64::LDPDi:
5348 case AArch64::LDPQi:
5349 case AArch64::LDPSi:
5350 case AArch64::LDPSWi:
5351 case AArch64::LDPWi:
5352 case AArch64::LDPXi: {
5356 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5359 case AArch64::LDPDpost:
5360 case AArch64::LDPDpre:
5361 case AArch64::LDPQpost:
5362 case AArch64::LDPQpre:
5363 case AArch64::LDPSpost:
5364 case AArch64::LDPSpre:
5365 case AArch64::LDPSWpost: {
5369 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5372 case AArch64::STPDpost:
5373 case AArch64::STPDpre:
5374 case AArch64::STPQpost:
5375 case AArch64::STPQpre:
5376 case AArch64::STPSpost:
5377 case AArch64::STPSpre:
5378 case AArch64::STPWpost:
5379 case AArch64::STPWpre:
5380 case AArch64::STPXpost:
5381 case AArch64::STPXpre: {
5386 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5387 "is also a source");
5389 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5390 "is also a source");
5393 case AArch64::LDRBBpre:
5394 case AArch64::LDRBpre:
5395 case AArch64::LDRHHpre:
5396 case AArch64::LDRHpre:
5397 case AArch64::LDRSBWpre:
5398 case AArch64::LDRSBXpre:
5399 case AArch64::LDRSHWpre:
5400 case AArch64::LDRSHXpre:
5401 case AArch64::LDRSWpre:
5402 case AArch64::LDRWpre:
5403 case AArch64::LDRXpre:
5404 case AArch64::LDRBBpost:
5405 case AArch64::LDRBpost:
5406 case AArch64::LDRHHpost:
5407 case AArch64::LDRHpost:
5408 case AArch64::LDRSBWpost:
5409 case AArch64::LDRSBXpost:
5410 case AArch64::LDRSHWpost:
5411 case AArch64::LDRSHXpost:
5412 case AArch64::LDRSWpost:
5413 case AArch64::LDRWpost:
5414 case AArch64::LDRXpost: {
5418 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5419 "is also a source");
5422 case AArch64::STRBBpost:
5423 case AArch64::STRBpost:
5424 case AArch64::STRHHpost:
5425 case AArch64::STRHpost:
5426 case AArch64::STRWpost:
5427 case AArch64::STRXpost:
5428 case AArch64::STRBBpre:
5429 case AArch64::STRBpre:
5430 case AArch64::STRHHpre:
5431 case AArch64::STRHpre:
5432 case AArch64::STRWpre:
5433 case AArch64::STRXpre: {
5437 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5438 "is also a source");
5441 case AArch64::STXRB:
5442 case AArch64::STXRH:
5443 case AArch64::STXRW:
5444 case AArch64::STXRX:
5445 case AArch64::STLXRB:
5446 case AArch64::STLXRH:
5447 case AArch64::STLXRW:
5448 case AArch64::STLXRX: {
5454 return Error(Loc[0],
5455 "unpredictable STXR instruction, status is also a source");
5458 case AArch64::STXPW:
5459 case AArch64::STXPX:
5460 case AArch64::STLXPW:
5461 case AArch64::STLXPX: {
5468 return Error(Loc[0],
5469 "unpredictable STXP instruction, status is also a source");
5472 case AArch64::LDRABwriteback:
5473 case AArch64::LDRAAwriteback: {
5477 return Error(Loc[0],
5478 "unpredictable LDRA instruction, writeback base"
5479 " is also a destination");
5486 case AArch64::CPYFP:
5487 case AArch64::CPYFPWN:
5488 case AArch64::CPYFPRN:
5489 case AArch64::CPYFPN:
5490 case AArch64::CPYFPWT:
5491 case AArch64::CPYFPWTWN:
5492 case AArch64::CPYFPWTRN:
5493 case AArch64::CPYFPWTN:
5494 case AArch64::CPYFPRT:
5495 case AArch64::CPYFPRTWN:
5496 case AArch64::CPYFPRTRN:
5497 case AArch64::CPYFPRTN:
5498 case AArch64::CPYFPT:
5499 case AArch64::CPYFPTWN:
5500 case AArch64::CPYFPTRN:
5501 case AArch64::CPYFPTN:
5502 case AArch64::CPYFM:
5503 case AArch64::CPYFMWN:
5504 case AArch64::CPYFMRN:
5505 case AArch64::CPYFMN:
5506 case AArch64::CPYFMWT:
5507 case AArch64::CPYFMWTWN:
5508 case AArch64::CPYFMWTRN:
5509 case AArch64::CPYFMWTN:
5510 case AArch64::CPYFMRT:
5511 case AArch64::CPYFMRTWN:
5512 case AArch64::CPYFMRTRN:
5513 case AArch64::CPYFMRTN:
5514 case AArch64::CPYFMT:
5515 case AArch64::CPYFMTWN:
5516 case AArch64::CPYFMTRN:
5517 case AArch64::CPYFMTN:
5518 case AArch64::CPYFE:
5519 case AArch64::CPYFEWN:
5520 case AArch64::CPYFERN:
5521 case AArch64::CPYFEN:
5522 case AArch64::CPYFEWT:
5523 case AArch64::CPYFEWTWN:
5524 case AArch64::CPYFEWTRN:
5525 case AArch64::CPYFEWTN:
5526 case AArch64::CPYFERT:
5527 case AArch64::CPYFERTWN:
5528 case AArch64::CPYFERTRN:
5529 case AArch64::CPYFERTN:
5530 case AArch64::CPYFET:
5531 case AArch64::CPYFETWN:
5532 case AArch64::CPYFETRN:
5533 case AArch64::CPYFETN:
5535 case AArch64::CPYPWN:
5536 case AArch64::CPYPRN:
5537 case AArch64::CPYPN:
5538 case AArch64::CPYPWT:
5539 case AArch64::CPYPWTWN:
5540 case AArch64::CPYPWTRN:
5541 case AArch64::CPYPWTN:
5542 case AArch64::CPYPRT:
5543 case AArch64::CPYPRTWN:
5544 case AArch64::CPYPRTRN:
5545 case AArch64::CPYPRTN:
5546 case AArch64::CPYPT:
5547 case AArch64::CPYPTWN:
5548 case AArch64::CPYPTRN:
5549 case AArch64::CPYPTN:
5551 case AArch64::CPYMWN:
5552 case AArch64::CPYMRN:
5553 case AArch64::CPYMN:
5554 case AArch64::CPYMWT:
5555 case AArch64::CPYMWTWN:
5556 case AArch64::CPYMWTRN:
5557 case AArch64::CPYMWTN:
5558 case AArch64::CPYMRT:
5559 case AArch64::CPYMRTWN:
5560 case AArch64::CPYMRTRN:
5561 case AArch64::CPYMRTN:
5562 case AArch64::CPYMT:
5563 case AArch64::CPYMTWN:
5564 case AArch64::CPYMTRN:
5565 case AArch64::CPYMTN:
5567 case AArch64::CPYEWN:
5568 case AArch64::CPYERN:
5569 case AArch64::CPYEN:
5570 case AArch64::CPYEWT:
5571 case AArch64::CPYEWTWN:
5572 case AArch64::CPYEWTRN:
5573 case AArch64::CPYEWTN:
5574 case AArch64::CPYERT:
5575 case AArch64::CPYERTWN:
5576 case AArch64::CPYERTRN:
5577 case AArch64::CPYERTN:
5578 case AArch64::CPYET:
5579 case AArch64::CPYETWN:
5580 case AArch64::CPYETRN:
5581 case AArch64::CPYETN: {
5589 return Error(Loc[0],
5590 "invalid CPY instruction, Xd_wb and Xd do not match");
5592 return Error(Loc[0],
5593 "invalid CPY instruction, Xs_wb and Xs do not match");
5595 return Error(Loc[0],
5596 "invalid CPY instruction, Xn_wb and Xn do not match");
5598 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5599 " registers are the same");
5601 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5602 " registers are the same");
5604 return Error(Loc[0],
"invalid CPY instruction, source and size"
5605 " registers are the same");
5609 case AArch64::SETPT:
5610 case AArch64::SETPN:
5611 case AArch64::SETPTN:
5613 case AArch64::SETMT:
5614 case AArch64::SETMN:
5615 case AArch64::SETMTN:
5617 case AArch64::SETET:
5618 case AArch64::SETEN:
5619 case AArch64::SETETN:
5620 case AArch64::SETGP:
5621 case AArch64::SETGPT:
5622 case AArch64::SETGPN:
5623 case AArch64::SETGPTN:
5624 case AArch64::SETGM:
5625 case AArch64::SETGMT:
5626 case AArch64::SETGMN:
5627 case AArch64::SETGMTN:
5628 case AArch64::MOPSSETGE:
5629 case AArch64::MOPSSETGET:
5630 case AArch64::MOPSSETGEN:
5631 case AArch64::MOPSSETGETN: {
5638 return Error(Loc[0],
5639 "invalid SET instruction, Xd_wb and Xd do not match");
5641 return Error(Loc[0],
5642 "invalid SET instruction, Xn_wb and Xn do not match");
5644 return Error(Loc[0],
"invalid SET instruction, destination and size"
5645 " registers are the same");
5647 return Error(Loc[0],
"invalid SET instruction, destination and source"
5648 " registers are the same");
5650 return Error(Loc[0],
"invalid SET instruction, source and size"
5651 " registers are the same");
5660 case AArch64::ADDSWri:
5661 case AArch64::ADDSXri:
5662 case AArch64::ADDWri:
5663 case AArch64::ADDXri:
5664 case AArch64::SUBSWri:
5665 case AArch64::SUBSXri:
5666 case AArch64::SUBWri:
5667 case AArch64::SUBXri: {
5675 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5702 return Error(Loc.
back(),
"invalid immediate expression");
5715 unsigned VariantID = 0);
5717bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5721 case Match_InvalidTiedOperand: {
5723 if (
Op.isVectorList())
5724 return Error(Loc,
"operand must match destination register list");
5726 assert(
Op.isReg() &&
"Unexpected operand type");
5727 switch (
Op.getRegEqualityTy()) {
5728 case RegConstraintEqualityTy::EqualsSubReg:
5729 return Error(Loc,
"operand must be 64-bit form of destination register");
5730 case RegConstraintEqualityTy::EqualsSuperReg:
5731 return Error(Loc,
"operand must be 32-bit form of destination register");
5732 case RegConstraintEqualityTy::EqualsReg:
5733 return Error(Loc,
"operand must match destination register");
5737 case Match_MissingFeature:
5739 "instruction requires a CPU feature not currently enabled");
5740 case Match_InvalidOperand:
5741 return Error(Loc,
"invalid operand for instruction");
5742 case Match_InvalidSuffix:
5743 return Error(Loc,
"invalid type suffix for instruction");
5744 case Match_InvalidCondCode:
5745 return Error(Loc,
"expected AArch64 condition code");
5746 case Match_AddSubRegExtendSmall:
5748 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5749 case Match_AddSubRegExtendLarge:
5751 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5752 case Match_AddSubSecondSource:
5754 "expected compatible register, symbol or integer in range [0, 4095]");
5755 case Match_LogicalSecondSource:
5756 return Error(Loc,
"expected compatible register or logical immediate");
5757 case Match_InvalidMovImm32Shift:
5758 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5759 case Match_InvalidMovImm64Shift:
5760 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5761 case Match_AddSubRegShift32:
5763 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5764 case Match_AddSubRegShift64:
5766 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5767 case Match_InvalidFPImm:
5769 "expected compatible register or floating-point constant");
5770 case Match_InvalidMemoryIndexedSImm6:
5771 return Error(Loc,
"index must be an integer in range [-32, 31].");
5772 case Match_InvalidMemoryIndexedSImm5:
5773 return Error(Loc,
"index must be an integer in range [-16, 15].");
5774 case Match_InvalidMemoryIndexed1SImm4:
5775 return Error(Loc,
"index must be an integer in range [-8, 7].");
5776 case Match_InvalidMemoryIndexed2SImm4:
5777 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5778 case Match_InvalidMemoryIndexed3SImm4:
5779 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5780 case Match_InvalidMemoryIndexed4SImm4:
5781 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5782 case Match_InvalidMemoryIndexed16SImm4:
5783 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5784 case Match_InvalidMemoryIndexed32SImm4:
5785 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5786 case Match_InvalidMemoryIndexed1SImm6:
5787 return Error(Loc,
"index must be an integer in range [-32, 31].");
5788 case Match_InvalidMemoryIndexedSImm8:
5789 return Error(Loc,
"index must be an integer in range [-128, 127].");
5790 case Match_InvalidMemoryIndexedSImm9:
5791 return Error(Loc,
"index must be an integer in range [-256, 255].");
5792 case Match_InvalidMemoryIndexed16SImm9:
5793 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5794 case Match_InvalidMemoryIndexed8SImm10:
5795 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5796 case Match_InvalidMemoryIndexed4SImm7:
5797 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5798 case Match_InvalidMemoryIndexed8SImm7:
5799 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5800 case Match_InvalidMemoryIndexed16SImm7:
5801 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5802 case Match_InvalidMemoryIndexed8UImm5:
5803 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5804 case Match_InvalidMemoryIndexed8UImm3:
5805 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5806 case Match_InvalidMemoryIndexed4UImm5:
5807 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5808 case Match_InvalidMemoryIndexed2UImm5:
5809 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5810 case Match_InvalidMemoryIndexed8UImm6:
5811 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5812 case Match_InvalidMemoryIndexed16UImm6:
5813 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5814 case Match_InvalidMemoryIndexed4UImm6:
5815 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5816 case Match_InvalidMemoryIndexed2UImm6:
5817 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5818 case Match_InvalidMemoryIndexed1UImm6:
5819 return Error(Loc,
"index must be in range [0, 63].");
5820 case Match_InvalidMemoryWExtend8:
5822 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5823 case Match_InvalidMemoryWExtend16:
5825 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5826 case Match_InvalidMemoryWExtend32:
5828 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5829 case Match_InvalidMemoryWExtend64:
5831 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5832 case Match_InvalidMemoryWExtend128:
5834 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5835 case Match_InvalidMemoryXExtend8:
5837 "expected 'lsl' or 'sxtx' with optional shift of #0");
5838 case Match_InvalidMemoryXExtend16:
5840 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5841 case Match_InvalidMemoryXExtend32:
5843 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5844 case Match_InvalidMemoryXExtend64:
5846 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5847 case Match_InvalidMemoryXExtend128:
5849 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5850 case Match_InvalidMemoryIndexed1:
5851 return Error(Loc,
"index must be an integer in range [0, 4095].");
5852 case Match_InvalidMemoryIndexed2:
5853 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
5854 case Match_InvalidMemoryIndexed4:
5855 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
5856 case Match_InvalidMemoryIndexed8:
5857 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
5858 case Match_InvalidMemoryIndexed16:
5859 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
5860 case Match_InvalidImm0_0:
5861 return Error(Loc,
"immediate must be 0.");
5862 case Match_InvalidImm0_1:
5863 return Error(Loc,
"immediate must be an integer in range [0, 1].");
5864 case Match_InvalidImm0_3:
5865 return Error(Loc,
"immediate must be an integer in range [0, 3].");
5866 case Match_InvalidImm0_7:
5867 return Error(Loc,
"immediate must be an integer in range [0, 7].");
5868 case Match_InvalidImm0_15:
5869 return Error(Loc,
"immediate must be an integer in range [0, 15].");
5870 case Match_InvalidImm0_31:
5871 return Error(Loc,
"immediate must be an integer in range [0, 31].");
5872 case Match_InvalidImm0_63:
5873 return Error(Loc,
"immediate must be an integer in range [0, 63].");
5874 case Match_InvalidImm0_127:
5875 return Error(Loc,
"immediate must be an integer in range [0, 127].");
5876 case Match_InvalidImm0_255:
5877 return Error(Loc,
"immediate must be an integer in range [0, 255].");
5878 case Match_InvalidImm0_65535:
5879 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
5880 case Match_InvalidImm1_8:
5881 return Error(Loc,
"immediate must be an integer in range [1, 8].");
5882 case Match_InvalidImm1_16:
5883 return Error(Loc,
"immediate must be an integer in range [1, 16].");
5884 case Match_InvalidImm1_32:
5885 return Error(Loc,
"immediate must be an integer in range [1, 32].");
5886 case Match_InvalidImm1_64:
5887 return Error(Loc,
"immediate must be an integer in range [1, 64].");
5888 case Match_InvalidMemoryIndexedRange2UImm0:
5889 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
5890 case Match_InvalidMemoryIndexedRange2UImm1:
5891 return Error(Loc,
"vector select offset must be an immediate range of the "
5892 "form <immf>:<imml>, where the first "
5893 "immediate is a multiple of 2 in the range [0, 2], and "
5894 "the second immediate is immf + 1.");
5895 case Match_InvalidMemoryIndexedRange2UImm2:
5896 case Match_InvalidMemoryIndexedRange2UImm3:
5899 "vector select offset must be an immediate range of the form "
5901 "where the first immediate is a multiple of 2 in the range [0, 6] or "
5903 "depending on the instruction, and the second immediate is immf + 1.");
5904 case Match_InvalidMemoryIndexedRange4UImm0:
5905 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
5906 case Match_InvalidMemoryIndexedRange4UImm1:
5907 case Match_InvalidMemoryIndexedRange4UImm2:
5910 "vector select offset must be an immediate range of the form "
5912 "where the first immediate is a multiple of 4 in the range [0, 4] or "
5914 "depending on the instruction, and the second immediate is immf + 3.");
5915 case Match_InvalidSVEAddSubImm8:
5916 return Error(Loc,
"immediate must be an integer in range [0, 255]"
5917 " with a shift amount of 0");
5918 case Match_InvalidSVEAddSubImm16:
5919 case Match_InvalidSVEAddSubImm32:
5920 case Match_InvalidSVEAddSubImm64:
5921 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
5922 "multiple of 256 in range [256, 65280]");
5923 case Match_InvalidSVECpyImm8:
5924 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
5925 " with a shift amount of 0");
5926 case Match_InvalidSVECpyImm16:
5927 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5928 "multiple of 256 in range [-32768, 65280]");
5929 case Match_InvalidSVECpyImm32:
5930 case Match_InvalidSVECpyImm64:
5931 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5932 "multiple of 256 in range [-32768, 32512]");
5933 case Match_InvalidIndexRange0_0:
5934 return Error(Loc,
"expected lane specifier '[0]'");
5935 case Match_InvalidIndexRange1_1:
5936 return Error(Loc,
"expected lane specifier '[1]'");
5937 case Match_InvalidIndexRange0_15:
5938 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5939 case Match_InvalidIndexRange0_7:
5940 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5941 case Match_InvalidIndexRange0_3:
5942 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5943 case Match_InvalidIndexRange0_1:
5944 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
5945 case Match_InvalidSVEIndexRange0_63:
5946 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
5947 case Match_InvalidSVEIndexRange0_31:
5948 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
5949 case Match_InvalidSVEIndexRange0_15:
5950 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5951 case Match_InvalidSVEIndexRange0_7:
5952 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5953 case Match_InvalidSVEIndexRange0_3:
5954 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5955 case Match_InvalidLabel:
5956 return Error(Loc,
"expected label or encodable integer pc offset");
5958 return Error(Loc,
"expected readable system register");
5960 case Match_InvalidSVCR:
5961 return Error(Loc,
"expected writable system register or pstate");
5962 case Match_InvalidComplexRotationEven:
5963 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
5964 case Match_InvalidComplexRotationOdd:
5965 return Error(Loc,
"complex rotation must be 90 or 270.");
5966 case Match_MnemonicFail: {
5968 ((AArch64Operand &)*
Operands[0]).getToken(),
5969 ComputeAvailableFeatures(STI->getFeatureBits()));
5970 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
5972 case Match_InvalidGPR64shifted8:
5973 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
5974 case Match_InvalidGPR64shifted16:
5975 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
5976 case Match_InvalidGPR64shifted32:
5977 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
5978 case Match_InvalidGPR64shifted64:
5979 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
5980 case Match_InvalidGPR64shifted128:
5982 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
5983 case Match_InvalidGPR64NoXZRshifted8:
5984 return Error(Loc,
"register must be x0..x30 without shift");
5985 case Match_InvalidGPR64NoXZRshifted16:
5986 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
5987 case Match_InvalidGPR64NoXZRshifted32:
5988 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
5989 case Match_InvalidGPR64NoXZRshifted64:
5990 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
5991 case Match_InvalidGPR64NoXZRshifted128:
5992 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
5993 case Match_InvalidZPR32UXTW8:
5994 case Match_InvalidZPR32SXTW8:
5995 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
5996 case Match_InvalidZPR32UXTW16:
5997 case Match_InvalidZPR32SXTW16:
5998 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
5999 case Match_InvalidZPR32UXTW32:
6000 case Match_InvalidZPR32SXTW32:
6001 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6002 case Match_InvalidZPR32UXTW64:
6003 case Match_InvalidZPR32SXTW64:
6004 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6005 case Match_InvalidZPR64UXTW8:
6006 case Match_InvalidZPR64SXTW8:
6007 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6008 case Match_InvalidZPR64UXTW16:
6009 case Match_InvalidZPR64SXTW16:
6010 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6011 case Match_InvalidZPR64UXTW32:
6012 case Match_InvalidZPR64SXTW32:
6013 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6014 case Match_InvalidZPR64UXTW64:
6015 case Match_InvalidZPR64SXTW64:
6016 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6017 case Match_InvalidZPR32LSL8:
6018 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6019 case Match_InvalidZPR32LSL16:
6020 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6021 case Match_InvalidZPR32LSL32:
6022 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6023 case Match_InvalidZPR32LSL64:
6024 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6025 case Match_InvalidZPR64LSL8:
6026 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6027 case Match_InvalidZPR64LSL16:
6028 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6029 case Match_InvalidZPR64LSL32:
6030 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6031 case Match_InvalidZPR64LSL64:
6032 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6033 case Match_InvalidZPR0:
6034 return Error(Loc,
"expected register without element width suffix");
6035 case Match_InvalidZPR8:
6036 case Match_InvalidZPR16:
6037 case Match_InvalidZPR32:
6038 case Match_InvalidZPR64:
6039 case Match_InvalidZPR128:
6040 return Error(Loc,
"invalid element width");
6041 case Match_InvalidZPR_3b8:
6042 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6043 case Match_InvalidZPR_3b16:
6044 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6045 case Match_InvalidZPR_3b32:
6046 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6047 case Match_InvalidZPR_4b8:
6049 "Invalid restricted vector register, expected z0.b..z15.b");
6050 case Match_InvalidZPR_4b16:
6051 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6052 case Match_InvalidZPR_4b32:
6053 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6054 case Match_InvalidZPR_4b64:
6055 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6056 case Match_InvalidSVEPattern:
6057 return Error(Loc,
"invalid predicate pattern");
6058 case Match_InvalidSVEPPRorPNRAnyReg:
6059 case Match_InvalidSVEPPRorPNRBReg:
6060 case Match_InvalidSVEPredicateAnyReg:
6061 case Match_InvalidSVEPredicateBReg:
6062 case Match_InvalidSVEPredicateHReg:
6063 case Match_InvalidSVEPredicateSReg:
6064 case Match_InvalidSVEPredicateDReg:
6065 return Error(Loc,
"invalid predicate register.");
6066 case Match_InvalidSVEPredicate3bAnyReg:
6067 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6068 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6069 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6070 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6071 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6072 return Error(Loc,
"Invalid predicate register, expected PN in range "
6073 "pn8..pn15 with element suffix.");
6074 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6075 return Error(Loc,
"invalid restricted predicate-as-counter register "
6076 "expected pn8..pn15");
6077 case Match_InvalidSVEPNPredicateBReg:
6078 case Match_InvalidSVEPNPredicateHReg:
6079 case Match_InvalidSVEPNPredicateSReg:
6080 case Match_InvalidSVEPNPredicateDReg:
6081 return Error(Loc,
"Invalid predicate register, expected PN in range "
6082 "pn0..pn15 with element suffix.");
6083 case Match_InvalidSVEVecLenSpecifier:
6084 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6085 case Match_InvalidSVEPredicateListMul2x8:
6086 case Match_InvalidSVEPredicateListMul2x16:
6087 case Match_InvalidSVEPredicateListMul2x32:
6088 case Match_InvalidSVEPredicateListMul2x64:
6089 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6090 "predicate registers, where the first vector is a multiple of 2 "
6091 "and with correct element type");
6092 case Match_InvalidSVEExactFPImmOperandHalfOne:
6093 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6094 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6095 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6096 case Match_InvalidSVEExactFPImmOperandZeroOne:
6097 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6098 case Match_InvalidMatrixTileVectorH8:
6099 case Match_InvalidMatrixTileVectorV8:
6100 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6101 case Match_InvalidMatrixTileVectorH16:
6102 case Match_InvalidMatrixTileVectorV16:
6104 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6105 case Match_InvalidMatrixTileVectorH32:
6106 case Match_InvalidMatrixTileVectorV32:
6108 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6109 case Match_InvalidMatrixTileVectorH64:
6110 case Match_InvalidMatrixTileVectorV64:
6112 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6113 case Match_InvalidMatrixTileVectorH128:
6114 case Match_InvalidMatrixTileVectorV128:
6116 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6117 case Match_InvalidMatrixTile32:
6118 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6119 case Match_InvalidMatrixTile64:
6120 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6121 case Match_InvalidMatrix:
6122 return Error(Loc,
"invalid matrix operand, expected za");
6123 case Match_InvalidMatrix8:
6124 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6125 case Match_InvalidMatrix16:
6126 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6127 case Match_InvalidMatrix32:
6128 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6129 case Match_InvalidMatrix64:
6130 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6131 case Match_InvalidMatrixIndexGPR32_12_15:
6132 return Error(Loc,
"operand must be a register in range [w12, w15]");
6133 case Match_InvalidMatrixIndexGPR32_8_11:
6134 return Error(Loc,
"operand must be a register in range [w8, w11]");
6135 case Match_InvalidSVEVectorListMul2x8:
6136 case Match_InvalidSVEVectorListMul2x16:
6137 case Match_InvalidSVEVectorListMul2x32:
6138 case Match_InvalidSVEVectorListMul2x64:
6139 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6140 "SVE vectors, where the first vector is a multiple of 2 "
6141 "and with matching element types");
6142 case Match_InvalidSVEVectorListMul4x8:
6143 case Match_InvalidSVEVectorListMul4x16:
6144 case Match_InvalidSVEVectorListMul4x32:
6145 case Match_InvalidSVEVectorListMul4x64:
6146 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6147 "SVE vectors, where the first vector is a multiple of 4 "
6148 "and with matching element types");
6149 case Match_InvalidLookupTable:
6150 return Error(Loc,
"Invalid lookup table, expected zt0");
6151 case Match_InvalidSVEVectorListStrided2x8:
6152 case Match_InvalidSVEVectorListStrided2x16:
6153 case Match_InvalidSVEVectorListStrided2x32:
6154 case Match_InvalidSVEVectorListStrided2x64:
6157 "Invalid vector list, expected list with each SVE vector in the list "
6158 "8 registers apart, and the first register in the range [z0, z7] or "
6159 "[z16, z23] and with correct element type");
6160 case Match_InvalidSVEVectorListStrided4x8:
6161 case Match_InvalidSVEVectorListStrided4x16:
6162 case Match_InvalidSVEVectorListStrided4x32:
6163 case Match_InvalidSVEVectorListStrided4x64:
6166 "Invalid vector list, expected list with each SVE vector in the list "
6167 "4 registers apart, and the first register in the range [z0, z3] or "
6168 "[z16, z19] and with correct element type");
6169 case Match_AddSubLSLImm3ShiftLarge:
6171 "expected 'lsl' with optional integer in range [0, 7]");
6179bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6183 bool MatchingInlineAsm) {
6185 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6186 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6189 unsigned NumOperands =
Operands.size();
6191 if (NumOperands == 4 && Tok ==
"lsl") {
6192 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6193 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6194 if (Op2.isScalarReg() && Op3.isImm()) {
6195 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6200 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6202 NewOp3Val = (32 - Op3Val) & 0x1f;
6203 NewOp4Val = 31 - Op3Val;
6205 NewOp3Val = (64 - Op3Val) & 0x3f;
6206 NewOp4Val = 63 - Op3Val;
6213 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6214 Operands.push_back(AArch64Operand::CreateImm(
6215 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6216 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6217 Op3.getEndLoc(), getContext());
6220 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6222 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6223 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6224 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6226 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6227 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6228 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6230 if (LSBCE && WidthCE) {
6235 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6241 if (LSB >= RegWidth)
6242 return Error(LSBOp.getStartLoc(),
6243 "expected integer in range [0, 31]");
6244 if (Width < 1 || Width > RegWidth)
6245 return Error(WidthOp.getStartLoc(),
6246 "expected integer in range [1, 32]");
6250 ImmR = (32 - LSB) & 0x1f;
6252 ImmR = (64 - LSB) & 0x3f;
6256 if (ImmR != 0 && ImmS >= ImmR)
6257 return Error(WidthOp.getStartLoc(),
6258 "requested insert overflows register");
6263 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6264 Operands[2] = AArch64Operand::CreateReg(
6265 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6267 Operands[3] = AArch64Operand::CreateImm(
6268 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6270 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6271 WidthOp.getEndLoc(), getContext()));
6274 }
else if (NumOperands == 5) {
6277 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6278 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6279 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6280 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6282 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6283 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6284 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6286 if (Op3CE && Op4CE) {
6291 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6297 if (Op3Val >= RegWidth)
6298 return Error(Op3.getStartLoc(),
6299 "expected integer in range [0, 31]");
6300 if (Op4Val < 1 || Op4Val > RegWidth)
6301 return Error(Op4.getStartLoc(),
6302 "expected integer in range [1, 32]");
6306 NewOp3Val = (32 - Op3Val) & 0x1f;
6308 NewOp3Val = (64 - Op3Val) & 0x3f;
6312 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6313 return Error(Op4.getStartLoc(),
6314 "requested insert overflows register");
6320 Operands[3] = AArch64Operand::CreateImm(
6321 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6322 Operands[4] = AArch64Operand::CreateImm(
6323 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6325 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6327 else if (Tok ==
"sbfiz")
6328 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6330 else if (Tok ==
"ubfiz")
6331 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6340 }
else if (NumOperands == 5 &&
6341 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6342 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6343 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6344 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6346 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6347 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6348 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6350 if (Op3CE && Op4CE) {
6355 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6361 if (Op3Val >= RegWidth)
6362 return Error(Op3.getStartLoc(),
6363 "expected integer in range [0, 31]");
6364 if (Op4Val < 1 || Op4Val > RegWidth)
6365 return Error(Op4.getStartLoc(),
6366 "expected integer in range [1, 32]");
6368 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6370 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6371 return Error(Op4.getStartLoc(),
6372 "requested extract overflows register");
6376 Operands[4] = AArch64Operand::CreateImm(
6377 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6379 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6381 else if (Tok ==
"sbfx")
6382 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6384 else if (Tok ==
"ubfx")
6385 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6398 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6399 NumOperands == 4 && Tok ==
"movi") {
6400 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6401 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6402 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6403 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6404 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6405 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6406 if (Suffix.
lower() ==
".2d" &&
6407 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6408 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6409 " correctly on this CPU, converting to equivalent movi.16b");
6411 unsigned Idx = Op1.isToken() ? 1 : 2;
6413 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6421 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6424 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6425 if (
Op.isScalarReg()) {
6427 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6428 Op.getStartLoc(),
Op.getEndLoc(),
6433 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6434 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6435 if (
Op.isScalarReg() &&
6436 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6440 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6441 if (
Op.isScalarReg()) {
6443 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6445 Op.getEndLoc(), getContext());
6450 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6451 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6452 if (
Op.isScalarReg() &&
6453 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6457 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6458 if (
Op.isScalarReg()) {
6460 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6462 Op.getEndLoc(), getContext());
6471 unsigned MatchResult =
6473 MatchingInlineAsm, 1);
6477 if (MatchResult != Match_Success) {
6480 auto ShortFormNEONErrorInfo =
ErrorInfo;
6481 auto ShortFormNEONMatchResult = MatchResult;
6482 auto ShortFormNEONMissingFeatures = MissingFeatures;
6486 MatchingInlineAsm, 0);
6491 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6493 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6494 MatchResult = ShortFormNEONMatchResult;
6496 MissingFeatures = ShortFormNEONMissingFeatures;
6500 switch (MatchResult) {
6501 case Match_Success: {
6505 for (
unsigned i = 1; i < NumOperands; ++i)
6507 if (validateInstruction(Inst, IDLoc, OperandLocs))
6514 case Match_MissingFeature: {
6515 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6518 std::string
Msg =
"instruction requires:";
6519 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6520 if (MissingFeatures[i]) {
6525 return Error(IDLoc, Msg);
6527 case Match_MnemonicFail:
6529 case Match_InvalidOperand: {
6530 SMLoc ErrorLoc = IDLoc;
6534 return Error(IDLoc,
"too few operands for instruction",
6535 SMRange(IDLoc, getTok().getLoc()));
6538 if (ErrorLoc ==
SMLoc())
6545 MatchResult = Match_InvalidSuffix;
6549 case Match_InvalidTiedOperand:
6550 case Match_InvalidMemoryIndexed1:
6551 case Match_InvalidMemoryIndexed2:
6552 case Match_InvalidMemoryIndexed4:
6553 case Match_InvalidMemoryIndexed8:
6554 case Match_InvalidMemoryIndexed16:
6555 case Match_InvalidCondCode:
6556 case Match_AddSubLSLImm3ShiftLarge:
6557 case Match_AddSubRegExtendSmall:
6558 case Match_AddSubRegExtendLarge:
6559 case Match_AddSubSecondSource:
6560 case Match_LogicalSecondSource:
6561 case Match_AddSubRegShift32:
6562 case Match_AddSubRegShift64:
6563 case Match_InvalidMovImm32Shift:
6564 case Match_InvalidMovImm64Shift:
6565 case Match_InvalidFPImm:
6566 case Match_InvalidMemoryWExtend8:
6567 case Match_InvalidMemoryWExtend16:
6568 case Match_InvalidMemoryWExtend32:
6569 case Match_InvalidMemoryWExtend64:
6570 case Match_InvalidMemoryWExtend128:
6571 case Match_InvalidMemoryXExtend8:
6572 case Match_InvalidMemoryXExtend16:
6573 case Match_InvalidMemoryXExtend32:
6574 case Match_InvalidMemoryXExtend64:
6575 case Match_InvalidMemoryXExtend128:
6576 case Match_InvalidMemoryIndexed1SImm4:
6577 case Match_InvalidMemoryIndexed2SImm4:
6578 case Match_InvalidMemoryIndexed3SImm4:
6579 case Match_InvalidMemoryIndexed4SImm4:
6580 case Match_InvalidMemoryIndexed1SImm6:
6581 case Match_InvalidMemoryIndexed16SImm4:
6582 case Match_InvalidMemoryIndexed32SImm4:
6583 case Match_InvalidMemoryIndexed4SImm7:
6584 case Match_InvalidMemoryIndexed8SImm7:
6585 case Match_InvalidMemoryIndexed16SImm7:
6586 case Match_InvalidMemoryIndexed8UImm5:
6587 case Match_InvalidMemoryIndexed8UImm3:
6588 case Match_InvalidMemoryIndexed4UImm5:
6589 case Match_InvalidMemoryIndexed2UImm5:
6590 case Match_InvalidMemoryIndexed1UImm6:
6591 case Match_InvalidMemoryIndexed2UImm6:
6592 case Match_InvalidMemoryIndexed4UImm6:
6593 case Match_InvalidMemoryIndexed8UImm6:
6594 case Match_InvalidMemoryIndexed16UImm6:
6595 case Match_InvalidMemoryIndexedSImm6:
6596 case Match_InvalidMemoryIndexedSImm5:
6597 case Match_InvalidMemoryIndexedSImm8:
6598 case Match_InvalidMemoryIndexedSImm9:
6599 case Match_InvalidMemoryIndexed16SImm9:
6600 case Match_InvalidMemoryIndexed8SImm10:
6601 case Match_InvalidImm0_0:
6602 case Match_InvalidImm0_1:
6603 case Match_InvalidImm0_3:
6604 case Match_InvalidImm0_7:
6605 case Match_InvalidImm0_15:
6606 case Match_InvalidImm0_31:
6607 case Match_InvalidImm0_63:
6608 case Match_InvalidImm0_127:
6609 case Match_InvalidImm0_255:
6610 case Match_InvalidImm0_65535:
6611 case Match_InvalidImm1_8:
6612 case Match_InvalidImm1_16:
6613 case Match_InvalidImm1_32:
6614 case Match_InvalidImm1_64:
6615 case Match_InvalidMemoryIndexedRange2UImm0:
6616 case Match_InvalidMemoryIndexedRange2UImm1:
6617 case Match_InvalidMemoryIndexedRange2UImm2:
6618 case Match_InvalidMemoryIndexedRange2UImm3:
6619 case Match_InvalidMemoryIndexedRange4UImm0:
6620 case Match_InvalidMemoryIndexedRange4UImm1:
6621 case Match_InvalidMemoryIndexedRange4UImm2:
6622 case Match_InvalidSVEAddSubImm8:
6623 case Match_InvalidSVEAddSubImm16:
6624 case Match_InvalidSVEAddSubImm32:
6625 case Match_InvalidSVEAddSubImm64:
6626 case Match_InvalidSVECpyImm8:
6627 case Match_InvalidSVECpyImm16:
6628 case Match_InvalidSVECpyImm32:
6629 case Match_InvalidSVECpyImm64:
6630 case Match_InvalidIndexRange0_0:
6631 case Match_InvalidIndexRange1_1:
6632 case Match_InvalidIndexRange0_15:
6633 case Match_InvalidIndexRange0_7:
6634 case Match_InvalidIndexRange0_3:
6635 case Match_InvalidIndexRange0_1:
6636 case Match_InvalidSVEIndexRange0_63:
6637 case Match_InvalidSVEIndexRange0_31:
6638 case Match_InvalidSVEIndexRange0_15:
6639 case Match_InvalidSVEIndexRange0_7:
6640 case Match_InvalidSVEIndexRange0_3:
6641 case Match_InvalidLabel:
6642 case Match_InvalidComplexRotationEven:
6643 case Match_InvalidComplexRotationOdd:
6644 case Match_InvalidGPR64shifted8:
6645 case Match_InvalidGPR64shifted16:
6646 case Match_InvalidGPR64shifted32:
6647 case Match_InvalidGPR64shifted64:
6648 case Match_InvalidGPR64shifted128:
6649 case Match_InvalidGPR64NoXZRshifted8:
6650 case Match_InvalidGPR64NoXZRshifted16:
6651 case Match_InvalidGPR64NoXZRshifted32:
6652 case Match_InvalidGPR64NoXZRshifted64:
6653 case Match_InvalidGPR64NoXZRshifted128:
6654 case Match_InvalidZPR32UXTW8:
6655 case Match_InvalidZPR32UXTW16:
6656 case Match_InvalidZPR32UXTW32:
6657 case Match_InvalidZPR32UXTW64:
6658 case Match_InvalidZPR32SXTW8:
6659 case Match_InvalidZPR32SXTW16:
6660 case Match_InvalidZPR32SXTW32:
6661 case Match_InvalidZPR32SXTW64:
6662 case Match_InvalidZPR64UXTW8:
6663 case Match_InvalidZPR64SXTW8:
6664 case Match_InvalidZPR64UXTW16:
6665 case Match_InvalidZPR64SXTW16:
6666 case Match_InvalidZPR64UXTW32:
6667 case Match_InvalidZPR64SXTW32:
6668 case Match_InvalidZPR64UXTW64:
6669 case Match_InvalidZPR64SXTW64:
6670 case Match_InvalidZPR32LSL8:
6671 case Match_InvalidZPR32LSL16:
6672 case Match_InvalidZPR32LSL32:
6673 case Match_InvalidZPR32LSL64:
6674 case Match_InvalidZPR64LSL8:
6675 case Match_InvalidZPR64LSL16:
6676 case Match_InvalidZPR64LSL32:
6677 case Match_InvalidZPR64LSL64:
6678 case Match_InvalidZPR0:
6679 case Match_InvalidZPR8:
6680 case Match_InvalidZPR16:
6681 case Match_InvalidZPR32:
6682 case Match_InvalidZPR64:
6683 case Match_InvalidZPR128:
6684 case Match_InvalidZPR_3b8:
6685 case Match_InvalidZPR_3b16:
6686 case Match_InvalidZPR_3b32:
6687 case Match_InvalidZPR_4b8:
6688 case Match_InvalidZPR_4b16:
6689 case Match_InvalidZPR_4b32:
6690 case Match_InvalidZPR_4b64:
6691 case Match_InvalidSVEPPRorPNRAnyReg:
6692 case Match_InvalidSVEPPRorPNRBReg:
6693 case Match_InvalidSVEPredicateAnyReg:
6694 case Match_InvalidSVEPattern:
6695 case Match_InvalidSVEVecLenSpecifier:
6696 case Match_InvalidSVEPredicateBReg:
6697 case Match_InvalidSVEPredicateHReg:
6698 case Match_InvalidSVEPredicateSReg:
6699 case Match_InvalidSVEPredicateDReg:
6700 case Match_InvalidSVEPredicate3bAnyReg:
6701 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6702 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6703 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6704 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6705 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6706 case Match_InvalidSVEPNPredicateBReg:
6707 case Match_InvalidSVEPNPredicateHReg:
6708 case Match_InvalidSVEPNPredicateSReg:
6709 case Match_InvalidSVEPNPredicateDReg:
6710 case Match_InvalidSVEPredicateListMul2x8:
6711 case Match_InvalidSVEPredicateListMul2x16:
6712 case Match_InvalidSVEPredicateListMul2x32:
6713 case Match_InvalidSVEPredicateListMul2x64:
6714 case Match_InvalidSVEExactFPImmOperandHalfOne:
6715 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6716 case Match_InvalidSVEExactFPImmOperandZeroOne:
6717 case Match_InvalidMatrixTile32:
6718 case Match_InvalidMatrixTile64:
6719 case Match_InvalidMatrix:
6720 case Match_InvalidMatrix8:
6721 case Match_InvalidMatrix16:
6722 case Match_InvalidMatrix32:
6723 case Match_InvalidMatrix64:
6724 case Match_InvalidMatrixTileVectorH8:
6725 case Match_InvalidMatrixTileVectorH16:
6726 case Match_InvalidMatrixTileVectorH32:
6727 case Match_InvalidMatrixTileVectorH64:
6728 case Match_InvalidMatrixTileVectorH128:
6729 case Match_InvalidMatrixTileVectorV8:
6730 case Match_InvalidMatrixTileVectorV16:
6731 case Match_InvalidMatrixTileVectorV32:
6732 case Match_InvalidMatrixTileVectorV64:
6733 case Match_InvalidMatrixTileVectorV128:
6734 case Match_InvalidSVCR:
6735 case Match_InvalidMatrixIndexGPR32_12_15:
6736 case Match_InvalidMatrixIndexGPR32_8_11:
6737 case Match_InvalidLookupTable:
6738 case Match_InvalidSVEVectorListMul2x8:
6739 case Match_InvalidSVEVectorListMul2x16:
6740 case Match_InvalidSVEVectorListMul2x32:
6741 case Match_InvalidSVEVectorListMul2x64:
6742 case Match_InvalidSVEVectorListMul4x8:
6743 case Match_InvalidSVEVectorListMul4x16:
6744 case Match_InvalidSVEVectorListMul4x32:
6745 case Match_InvalidSVEVectorListMul4x64:
6746 case Match_InvalidSVEVectorListStrided2x8:
6747 case Match_InvalidSVEVectorListStrided2x16:
6748 case Match_InvalidSVEVectorListStrided2x32:
6749 case Match_InvalidSVEVectorListStrided2x64:
6750 case Match_InvalidSVEVectorListStrided4x8:
6751 case Match_InvalidSVEVectorListStrided4x16:
6752 case Match_InvalidSVEVectorListStrided4x32:
6753 case Match_InvalidSVEVectorListStrided4x64:
6757 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6761 if (ErrorLoc ==
SMLoc())
6771bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6778 if (IDVal ==
".arch")
6779 parseDirectiveArch(Loc);
6780 else if (IDVal ==
".cpu")
6781 parseDirectiveCPU(Loc);
6782 else if (IDVal ==
".tlsdesccall")
6783 parseDirectiveTLSDescCall(Loc);
6784 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6785 parseDirectiveLtorg(Loc);
6786 else if (IDVal ==
".unreq")
6787 parseDirectiveUnreq(Loc);
6788 else if (IDVal ==
".inst")
6789 parseDirectiveInst(Loc);
6790 else if (IDVal ==
".cfi_negate_ra_state")
6791 parseDirectiveCFINegateRAState();
6792 else if (IDVal ==
".cfi_b_key_frame")
6793 parseDirectiveCFIBKeyFrame();
6794 else if (IDVal ==
".cfi_mte_tagged_frame")
6795 parseDirectiveCFIMTETaggedFrame();
6796 else if (IDVal ==
".arch_extension")
6797 parseDirectiveArchExtension(Loc);
6798 else if (IDVal ==
".variant_pcs")
6799 parseDirectiveVariantPCS(Loc);
6802 parseDirectiveLOH(IDVal, Loc);
6805 }
else if (IsCOFF) {
6806 if (IDVal ==
".seh_stackalloc")
6807 parseDirectiveSEHAllocStack(Loc);
6808 else if (IDVal ==
".seh_endprologue")
6809 parseDirectiveSEHPrologEnd(Loc);
6810 else if (IDVal ==
".seh_save_r19r20_x")
6811 parseDirectiveSEHSaveR19R20X(Loc);
6812 else if (IDVal ==
".seh_save_fplr")
6813 parseDirectiveSEHSaveFPLR(Loc);
6814 else if (IDVal ==
".seh_save_fplr_x")
6815 parseDirectiveSEHSaveFPLRX(Loc);
6816 else if (IDVal ==
".seh_save_reg")
6817 parseDirectiveSEHSaveReg(Loc);
6818 else if (IDVal ==
".seh_save_reg_x")
6819 parseDirectiveSEHSaveRegX(Loc);
6820 else if (IDVal ==
".seh_save_regp")
6821 parseDirectiveSEHSaveRegP(Loc);
6822 else if (IDVal ==
".seh_save_regp_x")
6823 parseDirectiveSEHSaveRegPX(Loc);
6824 else if (IDVal ==
".seh_save_lrpair")
6825 parseDirectiveSEHSaveLRPair(Loc);
6826 else if (IDVal ==
".seh_save_freg")
6827 parseDirectiveSEHSaveFReg(Loc);
6828 else if (IDVal ==
".seh_save_freg_x")
6829 parseDirectiveSEHSaveFRegX(Loc);
6830 else if (IDVal ==
".seh_save_fregp")
6831 parseDirectiveSEHSaveFRegP(Loc);
6832 else if (IDVal ==
".seh_save_fregp_x")
6833 parseDirectiveSEHSaveFRegPX(Loc);
6834 else if (IDVal ==
".seh_set_fp")
6835 parseDirectiveSEHSetFP(Loc);
6836 else if (IDVal ==
".seh_add_fp")
6837 parseDirectiveSEHAddFP(Loc);
6838 else if (IDVal ==
".seh_nop")
6839 parseDirectiveSEHNop(Loc);
6840 else if (IDVal ==
".seh_save_next")
6841 parseDirectiveSEHSaveNext(Loc);
6842 else if (IDVal ==
".seh_startepilogue")
6843 parseDirectiveSEHEpilogStart(Loc);
6844 else if (IDVal ==
".seh_endepilogue")
6845 parseDirectiveSEHEpilogEnd(Loc);
6846 else if (IDVal ==
".seh_trap_frame")
6847 parseDirectiveSEHTrapFrame(Loc);
6848 else if (IDVal ==
".seh_pushframe")
6849 parseDirectiveSEHMachineFrame(Loc);
6850 else if (IDVal ==
".seh_context")
6851 parseDirectiveSEHContext(Loc);
6852 else if (IDVal ==
".seh_ec_context")
6853 parseDirectiveSEHECContext(Loc);
6854 else if (IDVal ==
".seh_clear_unwound_to_call")
6855 parseDirectiveSEHClearUnwoundToCall(Loc);
6856 else if (IDVal ==
".seh_pac_sign_lr")
6857 parseDirectiveSEHPACSignLR(Loc);
6858 else if (IDVal ==
".seh_save_any_reg")
6859 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
6860 else if (IDVal ==
".seh_save_any_reg_p")
6861 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
6862 else if (IDVal ==
".seh_save_any_reg_x")
6863 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
6864 else if (IDVal ==
".seh_save_any_reg_px")
6865 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
6878 if (!NoCrypto && Crypto) {
6897 }
else if (NoCrypto) {
6902 RequestedExtensions.
push_back(
"nosha2");
6912 RequestedExtensions.
push_back(
"nosha3");
6913 RequestedExtensions.
push_back(
"nosha2");
6921bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
6922 SMLoc ArchLoc = getLoc();
6925 std::tie(Arch, ExtensionString) =
6926 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6930 return Error(ArchLoc,
"unknown arch name");
6936 std::vector<StringRef> AArch64Features;
6941 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6943 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
6946 if (!ExtensionString.
empty())
6947 ExtensionString.
split(RequestedExtensions,
'+');
6952 setAvailableFeatures(ComputeAvailableFeatures(Features));
6953 for (
auto Name : RequestedExtensions) {
6954 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
6967 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
6976bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
6977 SMLoc ExtLoc = getLoc();
6979 StringRef Name = getParser().parseStringToEndOfStatement().trim();
6984 bool EnableFeature =
true;
6985 if (
Name.starts_with_insensitive(
"no")) {
6986 EnableFeature =
false;
6997 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7003 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7007 return Error(ExtLoc,
"unknown architectural extension: " +
Name);
7016bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7017 SMLoc CurLoc = getLoc();
7020 std::tie(CPU, ExtensionString) =
7021 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7027 if (!ExtensionString.
empty())
7028 ExtensionString.
split(RequestedExtensions,
'+');
7032 Error(CurLoc,
"unknown CPU name");
7041 for (
auto Name : RequestedExtensions) {
7045 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7047 bool FoundExtension =
false;
7060 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7061 FoundExtension =
true;
7066 if (!FoundExtension)
7067 Error(CurLoc,
"unsupported architectural extension");
7076bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7078 return Error(Loc,
"expected expression following '.inst' directive");
7080 auto parseOp = [&]() ->
bool {
7082 const MCExpr *Expr =
nullptr;
7083 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
7086 if (
check(!
Value, L,
"expected constant expression"))
7088 getTargetStreamer().emitInst(
Value->getValue());
7092 return parseMany(parseOp);
7097bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7099 if (
check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7111 getParser().getStreamer().emitInstruction(Inst, getSTI());
7117bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7121 return TokError(
"expected an identifier or a number in directive");
7124 int64_t
Id = getTok().getIntVal();
7126 return TokError(
"invalid numeric identifier in directive");
7135 return TokError(
"invalid identifier in directive");
7143 assert(NbArgs != -1 &&
"Invalid number of arguments");
7146 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7148 if (getParser().parseIdentifier(
Name))
7149 return TokError(
"expected identifier in directive");
7150 Args.push_back(getContext().getOrCreateSymbol(
Name));
7152 if (
Idx + 1 == NbArgs)
7160 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7166bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7169 getTargetStreamer().emitCurrentConstantPool();
7177 SMLoc SRegLoc = getLoc();
7178 RegKind RegisterKind = RegKind::Scalar;
7180 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7184 RegisterKind = RegKind::NeonVector;
7185 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7191 return Error(SRegLoc,
"vector register without type specifier expected");
7196 RegisterKind = RegKind::SVEDataVector;
7198 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7204 return Error(SRegLoc,
7205 "sve vector register without type specifier expected");
7210 RegisterKind = RegKind::SVEPredicateVector;
7211 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7217 return Error(SRegLoc,
7218 "sve predicate register without type specifier expected");
7222 return Error(SRegLoc,
"register name or alias expected");
7228 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7229 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7230 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7237bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7239 return TokError(
"unexpected input in .unreq directive.");
7240 RegisterReqs.
erase(getTok().getIdentifier().lower());
7245bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7248 getStreamer().emitCFINegateRAState();
7254bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7257 getStreamer().emitCFIBKeyFrame();
7263bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7266 getStreamer().emitCFIMTETaggedFrame();
7272bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7274 if (getParser().parseIdentifier(
Name))
7275 return TokError(
"expected symbol name");
7278 getTargetStreamer().emitDirectiveVariantPCS(
7279 getContext().getOrCreateSymbol(
Name));
7285bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7287 if (parseImmExpr(
Size))
7289 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7295bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7296 getTargetStreamer().emitARM64WinCFIPrologEnd();
7302bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7304 if (parseImmExpr(
Offset))
7306 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7312bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7314 if (parseImmExpr(
Offset))
7316 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7322bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7324 if (parseImmExpr(
Offset))
7326 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7332bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7335 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7336 parseComma() || parseImmExpr(
Offset))
7338 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7344bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7347 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7348 parseComma() || parseImmExpr(
Offset))
7350 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7356bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7359 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7360 parseComma() || parseImmExpr(
Offset))
7362 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7368bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7371 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7372 parseComma() || parseImmExpr(
Offset))
7374 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7380bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7384 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7385 parseComma() || parseImmExpr(
Offset))
7387 if (
check(((Reg - 19) % 2 != 0), L,
7388 "expected register with even offset from x19"))
7390 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7396bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7399 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7400 parseComma() || parseImmExpr(
Offset))
7402 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7408bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7411 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7412 parseComma() || parseImmExpr(
Offset))
7414 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7420bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7423 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7424 parseComma() || parseImmExpr(
Offset))
7426 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7432bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7435 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7436 parseComma() || parseImmExpr(
Offset))
7438 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7444bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7445 getTargetStreamer().emitARM64WinCFISetFP();
7451bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7453 if (parseImmExpr(
Size))
7455 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7461bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7462 getTargetStreamer().emitARM64WinCFINop();
7468bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7469 getTargetStreamer().emitARM64WinCFISaveNext();
7475bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7476 getTargetStreamer().emitARM64WinCFIEpilogStart();
7482bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7483 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7489bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7490 getTargetStreamer().emitARM64WinCFITrapFrame();
7496bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7497 getTargetStreamer().emitARM64WinCFIMachineFrame();
7503bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7504 getTargetStreamer().emitARM64WinCFIContext();
7510bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7511 getTargetStreamer().emitARM64WinCFIECContext();
7517bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7518 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7524bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7525 getTargetStreamer().emitARM64WinCFIPACSignLR();
7534bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7539 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7540 parseComma() || parseImmExpr(
Offset))
7543 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7544 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7545 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7546 return Error(L,
"invalid save_any_reg offset");
7547 unsigned EncodedReg;
7548 if (Reg == AArch64::FP)
7550 else if (Reg == AArch64::LR)
7553 EncodedReg =
Reg - AArch64::X0;
7555 if (Reg == AArch64::LR)
7556 return Error(Start,
"lr cannot be paired with another register");
7558 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7560 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7563 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7565 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7567 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7568 unsigned EncodedReg =
Reg - AArch64::D0;
7569 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7570 return Error(L,
"invalid save_any_reg offset");
7572 if (Reg == AArch64::D31)
7573 return Error(Start,
"d31 cannot be paired with another register");
7575 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7577 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7580 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7582 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7584 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7585 unsigned EncodedReg =
Reg - AArch64::Q0;
7587 return Error(L,
"invalid save_any_reg offset");
7589 if (Reg == AArch64::Q31)
7590 return Error(Start,
"q31 cannot be paired with another register");
7592 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7594 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7597 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7599 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7602 return Error(Start,
"save_any_reg register must be x, q or d register");
7607bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7609 if (!parseAuthExpr(Res, EndLoc))
7611 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7618bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7629 "combination of @AUTH with other modifiers not supported");
7652 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7674 return TokError(
"expected key name");
7679 return TokError(
"invalid key '" + KeyStr +
"'");
7686 return TokError(
"expected integer discriminator");
7689 if (!isUInt<16>(Discriminator))
7690 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7691 " out of range [0, 0xFFFF]");
7694 bool UseAddressDiversity =
false;
7699 return TokError(
"expected 'addr'");
7700 UseAddressDiversity =
true;
7709 UseAddressDiversity, Ctx);
7714AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7722 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7723 ELFRefKind = AE->getKind();
7724 Expr = AE->getSubExpr();
7730 DarwinRefKind = SE->
getKind();
7737 if (!Relocatable || Res.
getSymB())
7764#define GET_REGISTER_MATCHER
7765#define GET_SUBTARGET_FEATURE_NAME
7766#define GET_MATCHER_IMPLEMENTATION
7767#define GET_MNEMONIC_SPELL_CHECKER
7768#include "AArch64GenAsmMatcher.inc"
7774 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7776 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7778 return Match_InvalidOperand;
7781 return Match_InvalidOperand;
7782 if (CE->getValue() == ExpectedVal)
7783 return Match_Success;
7784 return Match_InvalidOperand;
7789 return Match_InvalidOperand;
7795 if (
Op.isTokenEqual(
"za"))
7796 return Match_Success;
7797 return Match_InvalidOperand;
7803#define MATCH_HASH(N) \
7804 case MCK__HASH_##N: \
7805 return MatchesOpImmediate(N);
7831#define MATCH_HASH_MINUS(N) \
7832 case MCK__HASH__MINUS_##N: \
7833 return MatchesOpImmediate(-N);
7837#undef MATCH_HASH_MINUS
7846 return Error(S,
"expected register");
7849 ParseStatus Res = tryParseScalarRegister(FirstReg);
7851 return Error(S,
"expected first even register of a consecutive same-size "
7852 "even/odd register pair");
7855 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
7857 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
7859 bool isXReg = XRegClass.
contains(FirstReg),
7860 isWReg = WRegClass.
contains(FirstReg);
7861 if (!isXReg && !isWReg)
7862 return Error(S,
"expected first even register of a consecutive same-size "
7863 "even/odd register pair");
7868 if (FirstEncoding & 0x1)
7869 return Error(S,
"expected first even register of a consecutive same-size "
7870 "even/odd register pair");
7873 return Error(getLoc(),
"expected comma");
7879 Res = tryParseScalarRegister(SecondReg);
7881 return Error(E,
"expected second odd register of a consecutive same-size "
7882 "even/odd register pair");
7885 (isXReg && !XRegClass.
contains(SecondReg)) ||
7886 (isWReg && !WRegClass.
contains(SecondReg)))
7887 return Error(E,
"expected second odd register of a consecutive same-size "
7888 "even/odd register pair");
7893 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
7896 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
7899 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
7900 getLoc(), getContext()));
7905template <
bool ParseShiftExtend,
bool ParseSuffix>
7907 const SMLoc S = getLoc();
7913 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7918 if (ParseSuffix &&
Kind.empty())
7925 unsigned ElementWidth = KindRes->second;
7929 Operands.push_back(AArch64Operand::CreateVectorReg(
7930 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
7943 Res = tryParseOptionalShiftExtend(ExtOpnd);
7947 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
7948 Operands.push_back(AArch64Operand::CreateVectorReg(
7949 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
7950 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
7951 Ext->hasShiftExtendAmount()));
7976 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
7978 return TokError(
"invalid operand for instruction");
7983 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
7994 SS, getLoc(), getContext()));
8005 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8016 SS, getLoc(), getContext()));
8025 if (!tryParseScalarRegister(XReg).isSuccess())
8031 XReg, AArch64::x8sub_0,
8032 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8035 "expected an even-numbered x-register in the range [x0,x22]");
8038 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8052 if (getParser().parseExpression(ImmF))
8062 SMLoc E = getTok().getLoc();
8064 if (getParser().parseExpression(ImmL))
8067 unsigned ImmFVal = dyn_cast<MCConstantExpr>(ImmF)->getValue();
8068 unsigned ImmLVal = dyn_cast<MCConstantExpr>(ImmL)->getValue();
8071 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.
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.
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 ==...
constexpr ArchInfo ARMV8_9A
constexpr ArchInfo ARMV8_3A
constexpr ArchInfo ARMV8_7A
constexpr ArchInfo ARMV8R
constexpr ArchInfo ARMV8_4A
constexpr ArchInfo ARMV9_3A
const ArchInfo * parseArch(StringRef Arch)
constexpr ArchInfo ARMV8_6A
constexpr ArchInfo ARMV8_5A
const ArchInfo * getArchForCpu(StringRef CPU)
constexpr ArchInfo ARMV9_1A
constexpr ArchInfo ARMV9A
constexpr ArchInfo ARMV9_2A
@ DestructiveInstTypeMask
constexpr ArchInfo ARMV9_4A
bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr ArchInfo ARMV8_8A
constexpr ArchInfo ARMV8_1A
constexpr ArchInfo ARMV8_2A
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const CustomOperand< const MCSubtargetInfo & > Msg[]
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