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 case Match_InvalidSVEVectorListMul2x128:
6140 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6141 "SVE vectors, where the first vector is a multiple of 2 "
6142 "and with matching element types");
6143 case Match_InvalidSVEVectorListMul4x8:
6144 case Match_InvalidSVEVectorListMul4x16:
6145 case Match_InvalidSVEVectorListMul4x32:
6146 case Match_InvalidSVEVectorListMul4x64:
6147 case Match_InvalidSVEVectorListMul4x128:
6148 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6149 "SVE vectors, where the first vector is a multiple of 4 "
6150 "and with matching element types");
6151 case Match_InvalidLookupTable:
6152 return Error(Loc,
"Invalid lookup table, expected zt0");
6153 case Match_InvalidSVEVectorListStrided2x8:
6154 case Match_InvalidSVEVectorListStrided2x16:
6155 case Match_InvalidSVEVectorListStrided2x32:
6156 case Match_InvalidSVEVectorListStrided2x64:
6159 "Invalid vector list, expected list with each SVE vector in the list "
6160 "8 registers apart, and the first register in the range [z0, z7] or "
6161 "[z16, z23] and with correct element type");
6162 case Match_InvalidSVEVectorListStrided4x8:
6163 case Match_InvalidSVEVectorListStrided4x16:
6164 case Match_InvalidSVEVectorListStrided4x32:
6165 case Match_InvalidSVEVectorListStrided4x64:
6168 "Invalid vector list, expected list with each SVE vector in the list "
6169 "4 registers apart, and the first register in the range [z0, z3] or "
6170 "[z16, z19] and with correct element type");
6171 case Match_AddSubLSLImm3ShiftLarge:
6173 "expected 'lsl' with optional integer in range [0, 7]");
6181bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6185 bool MatchingInlineAsm) {
6187 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6188 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6191 unsigned NumOperands =
Operands.size();
6193 if (NumOperands == 4 && Tok ==
"lsl") {
6194 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6195 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6196 if (Op2.isScalarReg() && Op3.isImm()) {
6197 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6202 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6204 NewOp3Val = (32 - Op3Val) & 0x1f;
6205 NewOp4Val = 31 - Op3Val;
6207 NewOp3Val = (64 - Op3Val) & 0x3f;
6208 NewOp4Val = 63 - Op3Val;
6215 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6216 Operands.push_back(AArch64Operand::CreateImm(
6217 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6218 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6219 Op3.getEndLoc(), getContext());
6222 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6224 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6225 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6226 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6228 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6229 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6230 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6232 if (LSBCE && WidthCE) {
6237 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6243 if (LSB >= RegWidth)
6244 return Error(LSBOp.getStartLoc(),
6245 "expected integer in range [0, 31]");
6246 if (Width < 1 || Width > RegWidth)
6247 return Error(WidthOp.getStartLoc(),
6248 "expected integer in range [1, 32]");
6252 ImmR = (32 - LSB) & 0x1f;
6254 ImmR = (64 - LSB) & 0x3f;
6258 if (ImmR != 0 && ImmS >= ImmR)
6259 return Error(WidthOp.getStartLoc(),
6260 "requested insert overflows register");
6265 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6266 Operands[2] = AArch64Operand::CreateReg(
6267 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6269 Operands[3] = AArch64Operand::CreateImm(
6270 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6272 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6273 WidthOp.getEndLoc(), getContext()));
6276 }
else if (NumOperands == 5) {
6279 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6280 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6281 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6282 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6284 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6285 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6286 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6288 if (Op3CE && Op4CE) {
6293 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6299 if (Op3Val >= RegWidth)
6300 return Error(Op3.getStartLoc(),
6301 "expected integer in range [0, 31]");
6302 if (Op4Val < 1 || Op4Val > RegWidth)
6303 return Error(Op4.getStartLoc(),
6304 "expected integer in range [1, 32]");
6308 NewOp3Val = (32 - Op3Val) & 0x1f;
6310 NewOp3Val = (64 - Op3Val) & 0x3f;
6314 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6315 return Error(Op4.getStartLoc(),
6316 "requested insert overflows register");
6322 Operands[3] = AArch64Operand::CreateImm(
6323 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6324 Operands[4] = AArch64Operand::CreateImm(
6325 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6327 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6329 else if (Tok ==
"sbfiz")
6330 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6332 else if (Tok ==
"ubfiz")
6333 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6342 }
else if (NumOperands == 5 &&
6343 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6344 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6345 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6346 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6348 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6349 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6350 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6352 if (Op3CE && Op4CE) {
6357 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6363 if (Op3Val >= RegWidth)
6364 return Error(Op3.getStartLoc(),
6365 "expected integer in range [0, 31]");
6366 if (Op4Val < 1 || Op4Val > RegWidth)
6367 return Error(Op4.getStartLoc(),
6368 "expected integer in range [1, 32]");
6370 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6372 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6373 return Error(Op4.getStartLoc(),
6374 "requested extract overflows register");
6378 Operands[4] = AArch64Operand::CreateImm(
6379 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6381 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6383 else if (Tok ==
"sbfx")
6384 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6386 else if (Tok ==
"ubfx")
6387 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6400 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6401 NumOperands == 4 && Tok ==
"movi") {
6402 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6403 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6404 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6405 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6406 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6407 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6408 if (Suffix.
lower() ==
".2d" &&
6409 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6410 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6411 " correctly on this CPU, converting to equivalent movi.16b");
6413 unsigned Idx = Op1.isToken() ? 1 : 2;
6415 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6423 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6426 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6427 if (
Op.isScalarReg()) {
6429 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6430 Op.getStartLoc(),
Op.getEndLoc(),
6435 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6436 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6437 if (
Op.isScalarReg() &&
6438 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6442 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6443 if (
Op.isScalarReg()) {
6445 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6447 Op.getEndLoc(), getContext());
6452 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6453 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6454 if (
Op.isScalarReg() &&
6455 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6459 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6460 if (
Op.isScalarReg()) {
6462 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6464 Op.getEndLoc(), getContext());
6473 unsigned MatchResult =
6475 MatchingInlineAsm, 1);
6479 if (MatchResult != Match_Success) {
6482 auto ShortFormNEONErrorInfo =
ErrorInfo;
6483 auto ShortFormNEONMatchResult = MatchResult;
6484 auto ShortFormNEONMissingFeatures = MissingFeatures;
6488 MatchingInlineAsm, 0);
6493 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6495 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6496 MatchResult = ShortFormNEONMatchResult;
6498 MissingFeatures = ShortFormNEONMissingFeatures;
6502 switch (MatchResult) {
6503 case Match_Success: {
6507 for (
unsigned i = 1; i < NumOperands; ++i)
6509 if (validateInstruction(Inst, IDLoc, OperandLocs))
6516 case Match_MissingFeature: {
6517 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6520 std::string
Msg =
"instruction requires:";
6521 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6522 if (MissingFeatures[i]) {
6527 return Error(IDLoc, Msg);
6529 case Match_MnemonicFail:
6531 case Match_InvalidOperand: {
6532 SMLoc ErrorLoc = IDLoc;
6536 return Error(IDLoc,
"too few operands for instruction",
6537 SMRange(IDLoc, getTok().getLoc()));
6540 if (ErrorLoc ==
SMLoc())
6547 MatchResult = Match_InvalidSuffix;
6551 case Match_InvalidTiedOperand:
6552 case Match_InvalidMemoryIndexed1:
6553 case Match_InvalidMemoryIndexed2:
6554 case Match_InvalidMemoryIndexed4:
6555 case Match_InvalidMemoryIndexed8:
6556 case Match_InvalidMemoryIndexed16:
6557 case Match_InvalidCondCode:
6558 case Match_AddSubLSLImm3ShiftLarge:
6559 case Match_AddSubRegExtendSmall:
6560 case Match_AddSubRegExtendLarge:
6561 case Match_AddSubSecondSource:
6562 case Match_LogicalSecondSource:
6563 case Match_AddSubRegShift32:
6564 case Match_AddSubRegShift64:
6565 case Match_InvalidMovImm32Shift:
6566 case Match_InvalidMovImm64Shift:
6567 case Match_InvalidFPImm:
6568 case Match_InvalidMemoryWExtend8:
6569 case Match_InvalidMemoryWExtend16:
6570 case Match_InvalidMemoryWExtend32:
6571 case Match_InvalidMemoryWExtend64:
6572 case Match_InvalidMemoryWExtend128:
6573 case Match_InvalidMemoryXExtend8:
6574 case Match_InvalidMemoryXExtend16:
6575 case Match_InvalidMemoryXExtend32:
6576 case Match_InvalidMemoryXExtend64:
6577 case Match_InvalidMemoryXExtend128:
6578 case Match_InvalidMemoryIndexed1SImm4:
6579 case Match_InvalidMemoryIndexed2SImm4:
6580 case Match_InvalidMemoryIndexed3SImm4:
6581 case Match_InvalidMemoryIndexed4SImm4:
6582 case Match_InvalidMemoryIndexed1SImm6:
6583 case Match_InvalidMemoryIndexed16SImm4:
6584 case Match_InvalidMemoryIndexed32SImm4:
6585 case Match_InvalidMemoryIndexed4SImm7:
6586 case Match_InvalidMemoryIndexed8SImm7:
6587 case Match_InvalidMemoryIndexed16SImm7:
6588 case Match_InvalidMemoryIndexed8UImm5:
6589 case Match_InvalidMemoryIndexed8UImm3:
6590 case Match_InvalidMemoryIndexed4UImm5:
6591 case Match_InvalidMemoryIndexed2UImm5:
6592 case Match_InvalidMemoryIndexed1UImm6:
6593 case Match_InvalidMemoryIndexed2UImm6:
6594 case Match_InvalidMemoryIndexed4UImm6:
6595 case Match_InvalidMemoryIndexed8UImm6:
6596 case Match_InvalidMemoryIndexed16UImm6:
6597 case Match_InvalidMemoryIndexedSImm6:
6598 case Match_InvalidMemoryIndexedSImm5:
6599 case Match_InvalidMemoryIndexedSImm8:
6600 case Match_InvalidMemoryIndexedSImm9:
6601 case Match_InvalidMemoryIndexed16SImm9:
6602 case Match_InvalidMemoryIndexed8SImm10:
6603 case Match_InvalidImm0_0:
6604 case Match_InvalidImm0_1:
6605 case Match_InvalidImm0_3:
6606 case Match_InvalidImm0_7:
6607 case Match_InvalidImm0_15:
6608 case Match_InvalidImm0_31:
6609 case Match_InvalidImm0_63:
6610 case Match_InvalidImm0_127:
6611 case Match_InvalidImm0_255:
6612 case Match_InvalidImm0_65535:
6613 case Match_InvalidImm1_8:
6614 case Match_InvalidImm1_16:
6615 case Match_InvalidImm1_32:
6616 case Match_InvalidImm1_64:
6617 case Match_InvalidMemoryIndexedRange2UImm0:
6618 case Match_InvalidMemoryIndexedRange2UImm1:
6619 case Match_InvalidMemoryIndexedRange2UImm2:
6620 case Match_InvalidMemoryIndexedRange2UImm3:
6621 case Match_InvalidMemoryIndexedRange4UImm0:
6622 case Match_InvalidMemoryIndexedRange4UImm1:
6623 case Match_InvalidMemoryIndexedRange4UImm2:
6624 case Match_InvalidSVEAddSubImm8:
6625 case Match_InvalidSVEAddSubImm16:
6626 case Match_InvalidSVEAddSubImm32:
6627 case Match_InvalidSVEAddSubImm64:
6628 case Match_InvalidSVECpyImm8:
6629 case Match_InvalidSVECpyImm16:
6630 case Match_InvalidSVECpyImm32:
6631 case Match_InvalidSVECpyImm64:
6632 case Match_InvalidIndexRange0_0:
6633 case Match_InvalidIndexRange1_1:
6634 case Match_InvalidIndexRange0_15:
6635 case Match_InvalidIndexRange0_7:
6636 case Match_InvalidIndexRange0_3:
6637 case Match_InvalidIndexRange0_1:
6638 case Match_InvalidSVEIndexRange0_63:
6639 case Match_InvalidSVEIndexRange0_31:
6640 case Match_InvalidSVEIndexRange0_15:
6641 case Match_InvalidSVEIndexRange0_7:
6642 case Match_InvalidSVEIndexRange0_3:
6643 case Match_InvalidLabel:
6644 case Match_InvalidComplexRotationEven:
6645 case Match_InvalidComplexRotationOdd:
6646 case Match_InvalidGPR64shifted8:
6647 case Match_InvalidGPR64shifted16:
6648 case Match_InvalidGPR64shifted32:
6649 case Match_InvalidGPR64shifted64:
6650 case Match_InvalidGPR64shifted128:
6651 case Match_InvalidGPR64NoXZRshifted8:
6652 case Match_InvalidGPR64NoXZRshifted16:
6653 case Match_InvalidGPR64NoXZRshifted32:
6654 case Match_InvalidGPR64NoXZRshifted64:
6655 case Match_InvalidGPR64NoXZRshifted128:
6656 case Match_InvalidZPR32UXTW8:
6657 case Match_InvalidZPR32UXTW16:
6658 case Match_InvalidZPR32UXTW32:
6659 case Match_InvalidZPR32UXTW64:
6660 case Match_InvalidZPR32SXTW8:
6661 case Match_InvalidZPR32SXTW16:
6662 case Match_InvalidZPR32SXTW32:
6663 case Match_InvalidZPR32SXTW64:
6664 case Match_InvalidZPR64UXTW8:
6665 case Match_InvalidZPR64SXTW8:
6666 case Match_InvalidZPR64UXTW16:
6667 case Match_InvalidZPR64SXTW16:
6668 case Match_InvalidZPR64UXTW32:
6669 case Match_InvalidZPR64SXTW32:
6670 case Match_InvalidZPR64UXTW64:
6671 case Match_InvalidZPR64SXTW64:
6672 case Match_InvalidZPR32LSL8:
6673 case Match_InvalidZPR32LSL16:
6674 case Match_InvalidZPR32LSL32:
6675 case Match_InvalidZPR32LSL64:
6676 case Match_InvalidZPR64LSL8:
6677 case Match_InvalidZPR64LSL16:
6678 case Match_InvalidZPR64LSL32:
6679 case Match_InvalidZPR64LSL64:
6680 case Match_InvalidZPR0:
6681 case Match_InvalidZPR8:
6682 case Match_InvalidZPR16:
6683 case Match_InvalidZPR32:
6684 case Match_InvalidZPR64:
6685 case Match_InvalidZPR128:
6686 case Match_InvalidZPR_3b8:
6687 case Match_InvalidZPR_3b16:
6688 case Match_InvalidZPR_3b32:
6689 case Match_InvalidZPR_4b8:
6690 case Match_InvalidZPR_4b16:
6691 case Match_InvalidZPR_4b32:
6692 case Match_InvalidZPR_4b64:
6693 case Match_InvalidSVEPPRorPNRAnyReg:
6694 case Match_InvalidSVEPPRorPNRBReg:
6695 case Match_InvalidSVEPredicateAnyReg:
6696 case Match_InvalidSVEPattern:
6697 case Match_InvalidSVEVecLenSpecifier:
6698 case Match_InvalidSVEPredicateBReg:
6699 case Match_InvalidSVEPredicateHReg:
6700 case Match_InvalidSVEPredicateSReg:
6701 case Match_InvalidSVEPredicateDReg:
6702 case Match_InvalidSVEPredicate3bAnyReg:
6703 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6704 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6705 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6706 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6707 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6708 case Match_InvalidSVEPNPredicateBReg:
6709 case Match_InvalidSVEPNPredicateHReg:
6710 case Match_InvalidSVEPNPredicateSReg:
6711 case Match_InvalidSVEPNPredicateDReg:
6712 case Match_InvalidSVEPredicateListMul2x8:
6713 case Match_InvalidSVEPredicateListMul2x16:
6714 case Match_InvalidSVEPredicateListMul2x32:
6715 case Match_InvalidSVEPredicateListMul2x64:
6716 case Match_InvalidSVEExactFPImmOperandHalfOne:
6717 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6718 case Match_InvalidSVEExactFPImmOperandZeroOne:
6719 case Match_InvalidMatrixTile32:
6720 case Match_InvalidMatrixTile64:
6721 case Match_InvalidMatrix:
6722 case Match_InvalidMatrix8:
6723 case Match_InvalidMatrix16:
6724 case Match_InvalidMatrix32:
6725 case Match_InvalidMatrix64:
6726 case Match_InvalidMatrixTileVectorH8:
6727 case Match_InvalidMatrixTileVectorH16:
6728 case Match_InvalidMatrixTileVectorH32:
6729 case Match_InvalidMatrixTileVectorH64:
6730 case Match_InvalidMatrixTileVectorH128:
6731 case Match_InvalidMatrixTileVectorV8:
6732 case Match_InvalidMatrixTileVectorV16:
6733 case Match_InvalidMatrixTileVectorV32:
6734 case Match_InvalidMatrixTileVectorV64:
6735 case Match_InvalidMatrixTileVectorV128:
6736 case Match_InvalidSVCR:
6737 case Match_InvalidMatrixIndexGPR32_12_15:
6738 case Match_InvalidMatrixIndexGPR32_8_11:
6739 case Match_InvalidLookupTable:
6740 case Match_InvalidSVEVectorListMul2x8:
6741 case Match_InvalidSVEVectorListMul2x16:
6742 case Match_InvalidSVEVectorListMul2x32:
6743 case Match_InvalidSVEVectorListMul2x64:
6744 case Match_InvalidSVEVectorListMul2x128:
6745 case Match_InvalidSVEVectorListMul4x8:
6746 case Match_InvalidSVEVectorListMul4x16:
6747 case Match_InvalidSVEVectorListMul4x32:
6748 case Match_InvalidSVEVectorListMul4x64:
6749 case Match_InvalidSVEVectorListMul4x128:
6750 case Match_InvalidSVEVectorListStrided2x8:
6751 case Match_InvalidSVEVectorListStrided2x16:
6752 case Match_InvalidSVEVectorListStrided2x32:
6753 case Match_InvalidSVEVectorListStrided2x64:
6754 case Match_InvalidSVEVectorListStrided4x8:
6755 case Match_InvalidSVEVectorListStrided4x16:
6756 case Match_InvalidSVEVectorListStrided4x32:
6757 case Match_InvalidSVEVectorListStrided4x64:
6761 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6765 if (ErrorLoc ==
SMLoc())
6775bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6782 if (IDVal ==
".arch")
6783 parseDirectiveArch(Loc);
6784 else if (IDVal ==
".cpu")
6785 parseDirectiveCPU(Loc);
6786 else if (IDVal ==
".tlsdesccall")
6787 parseDirectiveTLSDescCall(Loc);
6788 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6789 parseDirectiveLtorg(Loc);
6790 else if (IDVal ==
".unreq")
6791 parseDirectiveUnreq(Loc);
6792 else if (IDVal ==
".inst")
6793 parseDirectiveInst(Loc);
6794 else if (IDVal ==
".cfi_negate_ra_state")
6795 parseDirectiveCFINegateRAState();
6796 else if (IDVal ==
".cfi_b_key_frame")
6797 parseDirectiveCFIBKeyFrame();
6798 else if (IDVal ==
".cfi_mte_tagged_frame")
6799 parseDirectiveCFIMTETaggedFrame();
6800 else if (IDVal ==
".arch_extension")
6801 parseDirectiveArchExtension(Loc);
6802 else if (IDVal ==
".variant_pcs")
6803 parseDirectiveVariantPCS(Loc);
6806 parseDirectiveLOH(IDVal, Loc);
6809 }
else if (IsCOFF) {
6810 if (IDVal ==
".seh_stackalloc")
6811 parseDirectiveSEHAllocStack(Loc);
6812 else if (IDVal ==
".seh_endprologue")
6813 parseDirectiveSEHPrologEnd(Loc);
6814 else if (IDVal ==
".seh_save_r19r20_x")
6815 parseDirectiveSEHSaveR19R20X(Loc);
6816 else if (IDVal ==
".seh_save_fplr")
6817 parseDirectiveSEHSaveFPLR(Loc);
6818 else if (IDVal ==
".seh_save_fplr_x")
6819 parseDirectiveSEHSaveFPLRX(Loc);
6820 else if (IDVal ==
".seh_save_reg")
6821 parseDirectiveSEHSaveReg(Loc);
6822 else if (IDVal ==
".seh_save_reg_x")
6823 parseDirectiveSEHSaveRegX(Loc);
6824 else if (IDVal ==
".seh_save_regp")
6825 parseDirectiveSEHSaveRegP(Loc);
6826 else if (IDVal ==
".seh_save_regp_x")
6827 parseDirectiveSEHSaveRegPX(Loc);
6828 else if (IDVal ==
".seh_save_lrpair")
6829 parseDirectiveSEHSaveLRPair(Loc);
6830 else if (IDVal ==
".seh_save_freg")
6831 parseDirectiveSEHSaveFReg(Loc);
6832 else if (IDVal ==
".seh_save_freg_x")
6833 parseDirectiveSEHSaveFRegX(Loc);
6834 else if (IDVal ==
".seh_save_fregp")
6835 parseDirectiveSEHSaveFRegP(Loc);
6836 else if (IDVal ==
".seh_save_fregp_x")
6837 parseDirectiveSEHSaveFRegPX(Loc);
6838 else if (IDVal ==
".seh_set_fp")
6839 parseDirectiveSEHSetFP(Loc);
6840 else if (IDVal ==
".seh_add_fp")
6841 parseDirectiveSEHAddFP(Loc);
6842 else if (IDVal ==
".seh_nop")
6843 parseDirectiveSEHNop(Loc);
6844 else if (IDVal ==
".seh_save_next")
6845 parseDirectiveSEHSaveNext(Loc);
6846 else if (IDVal ==
".seh_startepilogue")
6847 parseDirectiveSEHEpilogStart(Loc);
6848 else if (IDVal ==
".seh_endepilogue")
6849 parseDirectiveSEHEpilogEnd(Loc);
6850 else if (IDVal ==
".seh_trap_frame")
6851 parseDirectiveSEHTrapFrame(Loc);
6852 else if (IDVal ==
".seh_pushframe")
6853 parseDirectiveSEHMachineFrame(Loc);
6854 else if (IDVal ==
".seh_context")
6855 parseDirectiveSEHContext(Loc);
6856 else if (IDVal ==
".seh_ec_context")
6857 parseDirectiveSEHECContext(Loc);
6858 else if (IDVal ==
".seh_clear_unwound_to_call")
6859 parseDirectiveSEHClearUnwoundToCall(Loc);
6860 else if (IDVal ==
".seh_pac_sign_lr")
6861 parseDirectiveSEHPACSignLR(Loc);
6862 else if (IDVal ==
".seh_save_any_reg")
6863 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
6864 else if (IDVal ==
".seh_save_any_reg_p")
6865 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
6866 else if (IDVal ==
".seh_save_any_reg_x")
6867 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
6868 else if (IDVal ==
".seh_save_any_reg_px")
6869 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
6882 if (!NoCrypto && Crypto) {
6901 }
else if (NoCrypto) {
6906 RequestedExtensions.
push_back(
"nosha2");
6916 RequestedExtensions.
push_back(
"nosha3");
6917 RequestedExtensions.
push_back(
"nosha2");
6925bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
6926 SMLoc ArchLoc = getLoc();
6929 std::tie(Arch, ExtensionString) =
6930 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6934 return Error(ArchLoc,
"unknown arch name");
6940 std::vector<StringRef> AArch64Features;
6945 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6947 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
6950 if (!ExtensionString.
empty())
6951 ExtensionString.
split(RequestedExtensions,
'+');
6956 setAvailableFeatures(ComputeAvailableFeatures(Features));
6957 for (
auto Name : RequestedExtensions) {
6958 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
6971 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
6980bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
6981 SMLoc ExtLoc = getLoc();
6983 StringRef Name = getParser().parseStringToEndOfStatement().trim();
6988 bool EnableFeature =
true;
6989 if (
Name.starts_with_insensitive(
"no")) {
6990 EnableFeature =
false;
7001 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
7007 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7011 return Error(ExtLoc,
"unknown architectural extension: " +
Name);
7020bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
7021 SMLoc CurLoc = getLoc();
7024 std::tie(CPU, ExtensionString) =
7025 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7031 if (!ExtensionString.
empty())
7032 ExtensionString.
split(RequestedExtensions,
'+');
7036 Error(CurLoc,
"unknown CPU name");
7045 for (
auto Name : RequestedExtensions) {
7049 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7051 bool FoundExtension =
false;
7064 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7065 FoundExtension =
true;
7070 if (!FoundExtension)
7071 Error(CurLoc,
"unsupported architectural extension");
7080bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7082 return Error(Loc,
"expected expression following '.inst' directive");
7084 auto parseOp = [&]() ->
bool {
7086 const MCExpr *Expr =
nullptr;
7087 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
7090 if (
check(!
Value, L,
"expected constant expression"))
7092 getTargetStreamer().emitInst(
Value->getValue());
7096 return parseMany(parseOp);
7101bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7103 if (
check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7115 getParser().getStreamer().emitInstruction(Inst, getSTI());
7121bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7125 return TokError(
"expected an identifier or a number in directive");
7128 int64_t
Id = getTok().getIntVal();
7130 return TokError(
"invalid numeric identifier in directive");
7139 return TokError(
"invalid identifier in directive");
7147 assert(NbArgs != -1 &&
"Invalid number of arguments");
7150 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7152 if (getParser().parseIdentifier(
Name))
7153 return TokError(
"expected identifier in directive");
7154 Args.push_back(getContext().getOrCreateSymbol(
Name));
7156 if (
Idx + 1 == NbArgs)
7164 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7170bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7173 getTargetStreamer().emitCurrentConstantPool();
7181 SMLoc SRegLoc = getLoc();
7182 RegKind RegisterKind = RegKind::Scalar;
7184 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7188 RegisterKind = RegKind::NeonVector;
7189 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7195 return Error(SRegLoc,
"vector register without type specifier expected");
7200 RegisterKind = RegKind::SVEDataVector;
7202 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7208 return Error(SRegLoc,
7209 "sve vector register without type specifier expected");
7214 RegisterKind = RegKind::SVEPredicateVector;
7215 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7221 return Error(SRegLoc,
7222 "sve predicate register without type specifier expected");
7226 return Error(SRegLoc,
"register name or alias expected");
7232 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7233 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7234 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7241bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7243 return TokError(
"unexpected input in .unreq directive.");
7244 RegisterReqs.
erase(getTok().getIdentifier().lower());
7249bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7252 getStreamer().emitCFINegateRAState();
7258bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7261 getStreamer().emitCFIBKeyFrame();
7267bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7270 getStreamer().emitCFIMTETaggedFrame();
7276bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7278 if (getParser().parseIdentifier(
Name))
7279 return TokError(
"expected symbol name");
7282 getTargetStreamer().emitDirectiveVariantPCS(
7283 getContext().getOrCreateSymbol(
Name));
7289bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7291 if (parseImmExpr(
Size))
7293 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7299bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7300 getTargetStreamer().emitARM64WinCFIPrologEnd();
7306bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7308 if (parseImmExpr(
Offset))
7310 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7316bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7318 if (parseImmExpr(
Offset))
7320 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7326bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7328 if (parseImmExpr(
Offset))
7330 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7336bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7339 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7340 parseComma() || parseImmExpr(
Offset))
7342 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7348bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7351 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7352 parseComma() || parseImmExpr(
Offset))
7354 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7360bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7363 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7364 parseComma() || parseImmExpr(
Offset))
7366 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7372bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7375 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7376 parseComma() || parseImmExpr(
Offset))
7378 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7384bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7388 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7389 parseComma() || parseImmExpr(
Offset))
7391 if (
check(((Reg - 19) % 2 != 0), L,
7392 "expected register with even offset from x19"))
7394 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7400bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7403 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7404 parseComma() || parseImmExpr(
Offset))
7406 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7412bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7415 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7416 parseComma() || parseImmExpr(
Offset))
7418 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7424bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7427 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7428 parseComma() || parseImmExpr(
Offset))
7430 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7436bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7439 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7440 parseComma() || parseImmExpr(
Offset))
7442 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7448bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7449 getTargetStreamer().emitARM64WinCFISetFP();
7455bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7457 if (parseImmExpr(
Size))
7459 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7465bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7466 getTargetStreamer().emitARM64WinCFINop();
7472bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7473 getTargetStreamer().emitARM64WinCFISaveNext();
7479bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7480 getTargetStreamer().emitARM64WinCFIEpilogStart();
7486bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7487 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7493bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7494 getTargetStreamer().emitARM64WinCFITrapFrame();
7500bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7501 getTargetStreamer().emitARM64WinCFIMachineFrame();
7507bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7508 getTargetStreamer().emitARM64WinCFIContext();
7514bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7515 getTargetStreamer().emitARM64WinCFIECContext();
7521bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7522 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7528bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7529 getTargetStreamer().emitARM64WinCFIPACSignLR();
7538bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7543 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7544 parseComma() || parseImmExpr(
Offset))
7547 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7548 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7549 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7550 return Error(L,
"invalid save_any_reg offset");
7551 unsigned EncodedReg;
7552 if (Reg == AArch64::FP)
7554 else if (Reg == AArch64::LR)
7557 EncodedReg =
Reg - AArch64::X0;
7559 if (Reg == AArch64::LR)
7560 return Error(Start,
"lr cannot be paired with another register");
7562 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7564 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7567 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7569 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7571 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7572 unsigned EncodedReg =
Reg - AArch64::D0;
7573 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7574 return Error(L,
"invalid save_any_reg offset");
7576 if (Reg == AArch64::D31)
7577 return Error(Start,
"d31 cannot be paired with another register");
7579 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7581 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7584 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7586 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7588 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7589 unsigned EncodedReg =
Reg - AArch64::Q0;
7591 return Error(L,
"invalid save_any_reg offset");
7593 if (Reg == AArch64::Q31)
7594 return Error(Start,
"q31 cannot be paired with another register");
7596 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7598 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7601 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7603 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7606 return Error(Start,
"save_any_reg register must be x, q or d register");
7611bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7613 if (!parseAuthExpr(Res, EndLoc))
7615 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7622bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7633 "combination of @AUTH with other modifiers not supported");
7656 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7678 return TokError(
"expected key name");
7683 return TokError(
"invalid key '" + KeyStr +
"'");
7690 return TokError(
"expected integer discriminator");
7693 if (!isUInt<16>(Discriminator))
7694 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7695 " out of range [0, 0xFFFF]");
7698 bool UseAddressDiversity =
false;
7703 return TokError(
"expected 'addr'");
7704 UseAddressDiversity =
true;
7713 UseAddressDiversity, Ctx);
7718AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7726 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7727 ELFRefKind = AE->getKind();
7728 Expr = AE->getSubExpr();
7734 DarwinRefKind = SE->
getKind();
7741 if (!Relocatable || Res.
getSymB())
7768#define GET_REGISTER_MATCHER
7769#define GET_SUBTARGET_FEATURE_NAME
7770#define GET_MATCHER_IMPLEMENTATION
7771#define GET_MNEMONIC_SPELL_CHECKER
7772#include "AArch64GenAsmMatcher.inc"
7778 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7780 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7782 return Match_InvalidOperand;
7785 return Match_InvalidOperand;
7786 if (CE->getValue() == ExpectedVal)
7787 return Match_Success;
7788 return Match_InvalidOperand;
7793 return Match_InvalidOperand;
7799 if (
Op.isTokenEqual(
"za"))
7800 return Match_Success;
7801 return Match_InvalidOperand;
7807#define MATCH_HASH(N) \
7808 case MCK__HASH_##N: \
7809 return MatchesOpImmediate(N);
7835#define MATCH_HASH_MINUS(N) \
7836 case MCK__HASH__MINUS_##N: \
7837 return MatchesOpImmediate(-N);
7841#undef MATCH_HASH_MINUS
7850 return Error(S,
"expected register");
7853 ParseStatus Res = tryParseScalarRegister(FirstReg);
7855 return Error(S,
"expected first even register of a consecutive same-size "
7856 "even/odd register pair");
7859 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
7861 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
7863 bool isXReg = XRegClass.
contains(FirstReg),
7864 isWReg = WRegClass.
contains(FirstReg);
7865 if (!isXReg && !isWReg)
7866 return Error(S,
"expected first even register of a consecutive same-size "
7867 "even/odd register pair");
7872 if (FirstEncoding & 0x1)
7873 return Error(S,
"expected first even register of a consecutive same-size "
7874 "even/odd register pair");
7877 return Error(getLoc(),
"expected comma");
7883 Res = tryParseScalarRegister(SecondReg);
7885 return Error(E,
"expected second odd register of a consecutive same-size "
7886 "even/odd register pair");
7889 (isXReg && !XRegClass.
contains(SecondReg)) ||
7890 (isWReg && !WRegClass.
contains(SecondReg)))
7891 return Error(E,
"expected second odd register of a consecutive same-size "
7892 "even/odd register pair");
7897 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
7900 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
7903 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
7904 getLoc(), getContext()));
7909template <
bool ParseShiftExtend,
bool ParseSuffix>
7911 const SMLoc S = getLoc();
7917 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7922 if (ParseSuffix &&
Kind.empty())
7929 unsigned ElementWidth = KindRes->second;
7933 Operands.push_back(AArch64Operand::CreateVectorReg(
7934 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
7947 Res = tryParseOptionalShiftExtend(ExtOpnd);
7951 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
7952 Operands.push_back(AArch64Operand::CreateVectorReg(
7953 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
7954 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
7955 Ext->hasShiftExtendAmount()));
7980 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
7982 return TokError(
"invalid operand for instruction");
7987 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
7998 SS, getLoc(), getContext()));
8009 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8020 SS, getLoc(), getContext()));
8029 if (!tryParseScalarRegister(XReg).isSuccess())
8035 XReg, AArch64::x8sub_0,
8036 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8039 "expected an even-numbered x-register in the range [x0,x22]");
8042 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8056 if (getParser().parseExpression(ImmF))
8066 SMLoc E = getTok().getLoc();
8068 if (getParser().parseExpression(ImmL))
8071 unsigned ImmFVal = dyn_cast<MCConstantExpr>(ImmF)->getValue();
8072 unsigned ImmLVal = dyn_cast<MCConstantExpr>(ImmL)->getValue();
8075 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