73 SVEPredicateAsCounter,
79enum class MatrixKind { Array, Tile, Row, Col };
81enum RegConstraintEqualityTy {
92 StringMap<std::pair<RegKind, MCRegister>> RegisterReqs;
96 static PrefixInfo CreateFromInst(
const MCInst &Inst, uint64_t TSFlags) {
99 case AArch64::MOVPRFX_ZZ:
103 case AArch64::MOVPRFX_ZPmZ_B:
104 case AArch64::MOVPRFX_ZPmZ_H:
105 case AArch64::MOVPRFX_ZPmZ_S:
106 case AArch64::MOVPRFX_ZPmZ_D:
111 "No destructive element size set for movprfx");
115 case AArch64::MOVPRFX_ZPzZ_B:
116 case AArch64::MOVPRFX_ZPzZ_H:
117 case AArch64::MOVPRFX_ZPzZ_S:
118 case AArch64::MOVPRFX_ZPzZ_D:
123 "No destructive element size set for movprfx");
134 PrefixInfo() =
default;
135 bool isActive()
const {
return Active; }
137 unsigned getElementSize()
const {
141 MCRegister getDstReg()
const {
return Dst; }
142 MCRegister getPgReg()
const {
149 bool Predicated =
false;
150 unsigned ElementSize;
155 AArch64TargetStreamer &getTargetStreamer() {
156 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
157 return static_cast<AArch64TargetStreamer &
>(TS);
160 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
162 bool parseSysAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
163 bool parseSyslAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
164 bool parseSyspAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
165 void createSysAlias(uint16_t Encoding,
OperandVector &Operands, SMLoc S);
167 std::string &Suggestion);
169 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
171 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
174 bool parseOptionalVGOperand(
OperandVector &Operands, StringRef &VecGroup);
177 bool invertCondCode);
178 bool parseImmExpr(int64_t &Out);
180 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool showMatchError(SMLoc Loc,
unsigned ErrCode, uint64_t ErrorInfo,
186 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
187 bool parseDataExpr(
const MCExpr *&Res)
override;
188 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
190 bool parseDirectiveArch(SMLoc L);
191 bool parseDirectiveArchExtension(SMLoc L);
192 bool parseDirectiveCPU(SMLoc L);
193 bool parseDirectiveInst(SMLoc L);
195 bool parseDirectiveTLSDescCall(SMLoc L);
197 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
198 bool parseDirectiveLtorg(SMLoc L);
200 bool parseDirectiveReq(StringRef Name, SMLoc L);
201 bool parseDirectiveUnreq(SMLoc L);
202 bool parseDirectiveCFINegateRAState();
203 bool parseDirectiveCFINegateRAStateWithPC();
204 bool parseDirectiveCFIBKeyFrame();
205 bool parseDirectiveCFIMTETaggedFrame();
207 bool parseDirectiveVariantPCS(SMLoc L);
209 bool parseDirectiveSEHAllocStack(SMLoc L);
210 bool parseDirectiveSEHPrologEnd(SMLoc L);
211 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
212 bool parseDirectiveSEHSaveFPLR(SMLoc L);
213 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
214 bool parseDirectiveSEHSaveReg(SMLoc L);
215 bool parseDirectiveSEHSaveRegX(SMLoc L);
216 bool parseDirectiveSEHSaveRegP(SMLoc L);
217 bool parseDirectiveSEHSaveRegPX(SMLoc L);
218 bool parseDirectiveSEHSaveLRPair(SMLoc L);
219 bool parseDirectiveSEHSaveFReg(SMLoc L);
220 bool parseDirectiveSEHSaveFRegX(SMLoc L);
221 bool parseDirectiveSEHSaveFRegP(SMLoc L);
222 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
223 bool parseDirectiveSEHSetFP(SMLoc L);
224 bool parseDirectiveSEHAddFP(SMLoc L);
225 bool parseDirectiveSEHNop(SMLoc L);
226 bool parseDirectiveSEHSaveNext(SMLoc L);
227 bool parseDirectiveSEHEpilogStart(SMLoc L);
228 bool parseDirectiveSEHEpilogEnd(SMLoc L);
229 bool parseDirectiveSEHTrapFrame(SMLoc L);
230 bool parseDirectiveSEHMachineFrame(SMLoc L);
231 bool parseDirectiveSEHContext(SMLoc L);
232 bool parseDirectiveSEHECContext(SMLoc L);
233 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
234 bool parseDirectiveSEHPACSignLR(SMLoc L);
235 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
236 bool parseDirectiveSEHAllocZ(SMLoc L);
237 bool parseDirectiveSEHSaveZReg(SMLoc L);
238 bool parseDirectiveSEHSavePReg(SMLoc L);
239 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
240 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
242 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
243 SmallVectorImpl<SMLoc> &Loc);
244 unsigned getNumRegsForRegKind(RegKind K);
245 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
248 bool MatchingInlineAsm)
override;
252#define GET_ASSEMBLER_HEADER
253#include "AArch64GenAsmMatcher.inc"
267 template <
bool IsSVEPrefetch = false>
276 template <
bool AddFPZeroAsLiteral>
284 template <
bool ParseShiftExtend,
285 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
288 template <
bool ParseShiftExtend,
bool ParseSuffix>
290 template <RegKind RK>
293 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
294 template <RegKind VectorKind>
296 bool ExpectMatch =
false);
306 enum AArch64MatchResultTy {
307 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
308#define GET_OPERAND_DIAGNOSTIC_TYPES
309#include "AArch64GenAsmMatcher.inc"
312 bool IsWindowsArm64EC;
314 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
315 const MCInstrInfo &MII)
316 : MCTargetAsmParser(STI, MII) {
320 MCStreamer &S = getParser().getStreamer();
322 new AArch64TargetStreamer(S);
334 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
337 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
338 const MCParsedAsmOperand &Op2)
const override;
339 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
341 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
342 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
343 SMLoc &EndLoc)
override;
344 bool ParseDirective(AsmToken DirectiveID)
override;
345 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
346 unsigned Kind)
override;
382 SMLoc StartLoc, EndLoc;
391 struct ShiftExtendOp {
394 bool HasExplicitAmount;
404 RegConstraintEqualityTy EqualityTy;
420 ShiftExtendOp ShiftExtend;
425 unsigned ElementWidth;
429 struct MatrixTileListOp {
430 unsigned RegMask = 0;
433 struct VectorListOp {
437 unsigned NumElements;
438 unsigned ElementWidth;
439 RegKind RegisterKind;
442 struct VectorIndexOp {
450 struct ShiftedImmOp {
452 unsigned ShiftAmount;
481 uint32_t PStateField;
509 struct CMHPriorityHintOp {
514 struct TIndexHintOp {
523 unsigned PStateField;
529 struct MatrixRegOp MatrixReg;
530 struct MatrixTileListOp MatrixTileList;
531 struct VectorListOp VectorList;
532 struct VectorIndexOp VectorIndex;
534 struct ShiftedImmOp ShiftedImm;
535 struct ImmRangeOp ImmRange;
537 struct FPImmOp FPImm;
539 struct SysRegOp SysReg;
540 struct SysCRImmOp SysCRImm;
542 struct PSBHintOp PSBHint;
543 struct PHintOp PHint;
544 struct BTIHintOp BTIHint;
545 struct CMHPriorityHintOp CMHPriorityHint;
546 struct TIndexHintOp TIndexHint;
547 struct ShiftExtendOp ShiftExtend;
556 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
558 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
560 StartLoc =
o.StartLoc;
570 ShiftedImm =
o.ShiftedImm;
573 ImmRange =
o.ImmRange;
587 case k_MatrixRegister:
588 MatrixReg =
o.MatrixReg;
590 case k_MatrixTileList:
591 MatrixTileList =
o.MatrixTileList;
594 VectorList =
o.VectorList;
597 VectorIndex =
o.VectorIndex;
603 SysCRImm =
o.SysCRImm;
617 case k_CMHPriorityHint:
618 CMHPriorityHint =
o.CMHPriorityHint;
621 TIndexHint =
o.TIndexHint;
624 ShiftExtend =
o.ShiftExtend;
633 SMLoc getStartLoc()
const override {
return StartLoc; }
635 SMLoc getEndLoc()
const override {
return EndLoc; }
638 assert(Kind == k_Token &&
"Invalid access!");
639 return StringRef(Tok.Data, Tok.Length);
642 bool isTokenSuffix()
const {
643 assert(Kind == k_Token &&
"Invalid access!");
647 const MCExpr *
getImm()
const {
648 assert(Kind == k_Immediate &&
"Invalid access!");
652 const MCExpr *getShiftedImmVal()
const {
653 assert(Kind == k_ShiftedImm &&
"Invalid access!");
654 return ShiftedImm.Val;
657 unsigned getShiftedImmShift()
const {
658 assert(Kind == k_ShiftedImm &&
"Invalid access!");
659 return ShiftedImm.ShiftAmount;
662 unsigned getFirstImmVal()
const {
663 assert(Kind == k_ImmRange &&
"Invalid access!");
664 return ImmRange.First;
667 unsigned getLastImmVal()
const {
668 assert(Kind == k_ImmRange &&
"Invalid access!");
669 return ImmRange.Last;
673 assert(Kind == k_CondCode &&
"Invalid access!");
678 assert (Kind == k_FPImm &&
"Invalid access!");
679 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
682 bool getFPImmIsExact()
const {
683 assert (Kind == k_FPImm &&
"Invalid access!");
684 return FPImm.IsExact;
687 unsigned getBarrier()
const {
688 assert(Kind == k_Barrier &&
"Invalid access!");
692 StringRef getBarrierName()
const {
693 assert(Kind == k_Barrier &&
"Invalid access!");
697 bool getBarriernXSModifier()
const {
698 assert(Kind == k_Barrier &&
"Invalid access!");
702 MCRegister
getReg()
const override {
703 assert(Kind == k_Register &&
"Invalid access!");
707 MCRegister getMatrixReg()
const {
708 assert(Kind == k_MatrixRegister &&
"Invalid access!");
709 return MatrixReg.Reg;
712 unsigned getMatrixElementWidth()
const {
713 assert(Kind == k_MatrixRegister &&
"Invalid access!");
714 return MatrixReg.ElementWidth;
717 MatrixKind getMatrixKind()
const {
718 assert(Kind == k_MatrixRegister &&
"Invalid access!");
719 return MatrixReg.Kind;
722 unsigned getMatrixTileListRegMask()
const {
723 assert(isMatrixTileList() &&
"Invalid access!");
724 return MatrixTileList.RegMask;
727 RegConstraintEqualityTy getRegEqualityTy()
const {
728 assert(Kind == k_Register &&
"Invalid access!");
729 return Reg.EqualityTy;
732 MCRegister getVectorListStart()
const {
733 assert(Kind == k_VectorList &&
"Invalid access!");
734 return VectorList.Reg;
737 unsigned getVectorListCount()
const {
738 assert(Kind == k_VectorList &&
"Invalid access!");
739 return VectorList.Count;
742 unsigned getVectorListStride()
const {
743 assert(Kind == k_VectorList &&
"Invalid access!");
744 return VectorList.Stride;
747 int getVectorIndex()
const {
748 assert(Kind == k_VectorIndex &&
"Invalid access!");
749 return VectorIndex.Val;
752 StringRef getSysReg()
const {
753 assert(Kind == k_SysReg &&
"Invalid access!");
754 return StringRef(SysReg.Data, SysReg.Length);
757 unsigned getSysCR()
const {
758 assert(Kind == k_SysCR &&
"Invalid access!");
762 unsigned getPrefetch()
const {
763 assert(Kind == k_Prefetch &&
"Invalid access!");
767 unsigned getPSBHint()
const {
768 assert(Kind == k_PSBHint &&
"Invalid access!");
772 unsigned getPHint()
const {
773 assert(Kind == k_PHint &&
"Invalid access!");
777 StringRef getPSBHintName()
const {
778 assert(Kind == k_PSBHint &&
"Invalid access!");
779 return StringRef(PSBHint.Data, PSBHint.Length);
782 StringRef getPHintName()
const {
783 assert(Kind == k_PHint &&
"Invalid access!");
784 return StringRef(PHint.Data, PHint.Length);
787 unsigned getBTIHint()
const {
788 assert(Kind == k_BTIHint &&
"Invalid access!");
792 StringRef getBTIHintName()
const {
793 assert(Kind == k_BTIHint &&
"Invalid access!");
794 return StringRef(BTIHint.Data, BTIHint.Length);
797 unsigned getCMHPriorityHint()
const {
798 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
799 return CMHPriorityHint.Val;
802 StringRef getCMHPriorityHintName()
const {
803 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
804 return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
807 unsigned getTIndexHint()
const {
808 assert(Kind == k_TIndexHint &&
"Invalid access!");
809 return TIndexHint.Val;
812 StringRef getTIndexHintName()
const {
813 assert(Kind == k_TIndexHint &&
"Invalid access!");
814 return StringRef(TIndexHint.Data, TIndexHint.Length);
817 StringRef getSVCR()
const {
818 assert(Kind == k_SVCR &&
"Invalid access!");
819 return StringRef(SVCR.Data, SVCR.Length);
822 StringRef getPrefetchName()
const {
823 assert(Kind == k_Prefetch &&
"Invalid access!");
828 if (Kind == k_ShiftExtend)
829 return ShiftExtend.Type;
830 if (Kind == k_Register)
831 return Reg.ShiftExtend.Type;
835 unsigned getShiftExtendAmount()
const {
836 if (Kind == k_ShiftExtend)
837 return ShiftExtend.Amount;
838 if (Kind == k_Register)
839 return Reg.ShiftExtend.Amount;
843 bool hasShiftExtendAmount()
const {
844 if (Kind == k_ShiftExtend)
845 return ShiftExtend.HasExplicitAmount;
846 if (Kind == k_Register)
847 return Reg.ShiftExtend.HasExplicitAmount;
851 bool isImm()
const override {
return Kind == k_Immediate; }
852 bool isMem()
const override {
return false; }
854 bool isUImm6()
const {
861 return (Val >= 0 && Val < 64);
864 template <
int W
idth>
bool isSImm()
const {
865 return bool(isSImmScaled<Width, 1>());
868 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
869 return isImmScaled<Bits, Scale>(
true);
872 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
873 DiagnosticPredicate isUImmScaled()
const {
874 if (IsRange && isImmRange() &&
875 (getLastImmVal() != getFirstImmVal() +
Offset))
878 return isImmScaled<Bits, Scale, IsRange>(
false);
881 template <
int Bits,
int Scale,
bool IsRange = false>
882 DiagnosticPredicate isImmScaled(
bool Signed)
const {
883 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
884 (isImmRange() && !IsRange))
889 Val = getFirstImmVal();
897 int64_t MinVal, MaxVal;
899 int64_t Shift =
Bits - 1;
900 MinVal = (int64_t(1) << Shift) * -Scale;
901 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
904 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
907 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
913 DiagnosticPredicate isSVEPattern()
const {
920 if (Val >= 0 && Val < 32)
925 DiagnosticPredicate isSVEVecLenSpecifier()
const {
932 if (Val >= 0 && Val <= 1)
937 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
941 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
970 template <
int Scale>
bool isUImm12Offset()
const {
976 return isSymbolicUImm12Offset(
getImm());
979 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
982 template <
int N,
int M>
983 bool isImmInRange()
const {
990 return (Val >=
N && Val <= M);
995 template <
typename T>
996 bool isLogicalImm()
const {
1005 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
1013 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
1015 bool isImmRange()
const {
return Kind == k_ImmRange; }
1020 template <
unsigned W
idth>
1021 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
1022 if (isShiftedImm() && Width == getShiftedImmShift())
1024 return std::make_pair(
CE->getValue(), Width);
1028 int64_t Val =
CE->getValue();
1029 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
1030 return std::make_pair(Val >> Width, Width);
1032 return std::make_pair(Val, 0u);
1038 bool isAddSubImm()
const {
1039 if (!isShiftedImm() && !isImm())
1045 if (isShiftedImm()) {
1046 unsigned Shift = ShiftedImm.ShiftAmount;
1047 Expr = ShiftedImm.Val;
1048 if (Shift != 0 && Shift != 12)
1057 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1073 if (
auto ShiftedVal = getShiftedVal<12>())
1074 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1081 bool isAddSubImmNeg()
const {
1082 if (!isShiftedImm() && !isImm())
1086 if (
auto ShiftedVal = getShiftedVal<12>())
1087 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1097 template <
typename T>
1098 DiagnosticPredicate isSVECpyImm()
const {
1102 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1103 std::is_same<int8_t, T>::value;
1104 if (
auto ShiftedImm = getShiftedVal<8>())
1105 if (!(IsByte && ShiftedImm->second) &&
1107 << ShiftedImm->second))
1116 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1120 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1121 std::is_same<int8_t, T>::value;
1122 if (
auto ShiftedImm = getShiftedVal<8>())
1123 if (!(IsByte && ShiftedImm->second) &&
1125 << ShiftedImm->second))
1131 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1132 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1137 bool isCondCode()
const {
return Kind == k_CondCode; }
1139 bool isSIMDImmType10()
const {
1149 bool isBranchTarget()
const {
1158 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1159 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1169 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1179 bool isMovWSymbolG3()
const {
1183 bool isMovWSymbolG2()
const {
1190 bool isMovWSymbolG1()
const {
1198 bool isMovWSymbolG0()
const {
1206 template<
int RegW
idth,
int Shift>
1207 bool isMOVZMovAlias()
const {
1208 if (!isImm())
return false;
1212 uint64_t
Value =
CE->getValue();
1221 template<
int RegW
idth,
int Shift>
1222 bool isMOVNMovAlias()
const {
1223 if (!isImm())
return false;
1226 if (!CE)
return false;
1227 uint64_t
Value =
CE->getValue();
1232 bool isFPImm()
const {
1233 return Kind == k_FPImm &&
1237 bool isBarrier()
const {
1238 return Kind == k_Barrier && !getBarriernXSModifier();
1240 bool isBarriernXS()
const {
1241 return Kind == k_Barrier && getBarriernXSModifier();
1243 bool isSysReg()
const {
return Kind == k_SysReg; }
1245 bool isMRSSystemRegister()
const {
1246 if (!isSysReg())
return false;
1248 return SysReg.MRSReg != -1U;
1251 bool isMSRSystemRegister()
const {
1252 if (!isSysReg())
return false;
1253 return SysReg.MSRReg != -1U;
1256 bool isSystemPStateFieldWithImm0_1()
const {
1257 if (!isSysReg())
return false;
1258 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1261 bool isSystemPStateFieldWithImm0_15()
const {
1264 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1267 bool isSVCR()
const {
1270 return SVCR.PStateField != -1U;
1273 bool isReg()
const override {
1274 return Kind == k_Register;
1277 bool isVectorList()
const {
return Kind == k_VectorList; }
1279 bool isScalarReg()
const {
1280 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1283 bool isNeonVectorReg()
const {
1284 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1287 bool isNeonVectorRegLo()
const {
1288 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1289 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1290 .contains(
Reg.Reg) ||
1291 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1292 .contains(
Reg.Reg));
1295 bool isNeonVectorReg0to7()
const {
1296 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1297 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1298 .contains(
Reg.Reg));
1301 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1302 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1304 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1307 case AArch64::PPRRegClassID:
1308 case AArch64::PPR_3bRegClassID:
1309 case AArch64::PPR_p8to15RegClassID:
1310 case AArch64::PNRRegClassID:
1311 case AArch64::PNR_p8to15RegClassID:
1312 case AArch64::PPRorPNRRegClassID:
1313 RK = RegKind::SVEPredicateAsCounter;
1319 return (Kind == k_Register &&
Reg.Kind == RK) &&
1320 getAArch64MCRegisterClass(Class).contains(
getReg());
1323 template <
unsigned Class>
bool isSVEVectorReg()
const {
1326 case AArch64::ZPRRegClassID:
1327 case AArch64::ZPR_3bRegClassID:
1328 case AArch64::ZPR_4bRegClassID:
1329 case AArch64::ZPRMul2_LoRegClassID:
1330 case AArch64::ZPRMul2_HiRegClassID:
1331 case AArch64::ZPR_KRegClassID:
1332 RK = RegKind::SVEDataVector;
1334 case AArch64::PPRRegClassID:
1335 case AArch64::PPR_3bRegClassID:
1336 case AArch64::PPR_p8to15RegClassID:
1337 case AArch64::PNRRegClassID:
1338 case AArch64::PNR_p8to15RegClassID:
1339 case AArch64::PPRorPNRRegClassID:
1340 RK = RegKind::SVEPredicateVector;
1346 return (Kind == k_Register &&
Reg.Kind == RK) &&
1347 getAArch64MCRegisterClass(Class).contains(
getReg());
1350 template <
unsigned Class>
bool isFPRasZPR()
const {
1351 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1352 getAArch64MCRegisterClass(Class).contains(
getReg());
1355 template <
int ElementW
idth,
unsigned Class>
1356 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1357 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1360 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1366 template <
int ElementW
idth,
unsigned Class>
1367 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1368 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1369 Reg.Kind != RegKind::SVEPredicateVector))
1372 if ((isSVEPredicateAsCounterReg<Class>() ||
1373 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1374 Reg.ElementWidth == ElementWidth)
1380 template <
int ElementW
idth,
unsigned Class>
1381 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1382 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1385 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1391 template <
int ElementW
idth,
unsigned Class>
1392 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1393 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1396 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1402 template <
int ElementWidth,
unsigned Class,
1404 bool ShiftWidthAlwaysSame>
1405 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1406 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1407 if (!VectorMatch.isMatch())
1413 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1416 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1419 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1425 bool isGPR32as64()
const {
1426 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1427 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1431 bool isGPR64as32()
const {
1432 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1433 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1437 bool isGPR64x8()
const {
1438 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1439 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1443 bool isWSeqPair()
const {
1444 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1445 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1449 bool isXSeqPair()
const {
1450 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1451 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1455 bool isSyspXzrPair()
const {
1459 template<
int64_t Angle,
int64_t Remainder>
1460 DiagnosticPredicate isComplexRotation()
const {
1467 uint64_t
Value =
CE->getValue();
1469 if (
Value % Angle == Remainder &&
Value <= 270)
1474 template <
unsigned RegClassID>
bool isGPR64()
const {
1475 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1476 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1479 template <
unsigned RegClassID,
int ExtW
idth>
1480 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1481 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1485 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1492 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1493 bool isImplicitlyTypedVectorList()
const {
1494 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1495 VectorList.NumElements == 0 &&
1496 VectorList.RegisterKind == VectorKind &&
1497 (!IsConsecutive || (VectorList.Stride == 1));
1500 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1501 unsigned ElementWidth,
unsigned Stride = 1>
1502 bool isTypedVectorList()
const {
1503 if (Kind != k_VectorList)
1505 if (VectorList.Count != NumRegs)
1507 if (VectorList.RegisterKind != VectorKind)
1509 if (VectorList.ElementWidth != ElementWidth)
1511 if (VectorList.Stride != Stride)
1513 return VectorList.NumElements == NumElements;
1516 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1517 unsigned ElementWidth,
unsigned RegClass>
1518 DiagnosticPredicate isTypedVectorListMultiple()
const {
1520 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1523 if (!getAArch64MCRegisterClass(RegClass).
contains(VectorList.Reg))
1528 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1529 unsigned ElementWidth>
1530 DiagnosticPredicate isTypedVectorListStrided()
const {
1531 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1532 ElementWidth, Stride>();
1535 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1536 ((VectorList.Reg >= AArch64::Z16) &&
1537 (VectorList.Reg < (AArch64::Z16 + Stride))))
1542 template <
int Min,
int Max>
1543 DiagnosticPredicate isVectorIndex()
const {
1544 if (Kind != k_VectorIndex)
1546 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1551 bool isToken()
const override {
return Kind == k_Token; }
1553 bool isTokenEqual(StringRef Str)
const {
1554 return Kind == k_Token &&
getToken() == Str;
1556 bool isSysCR()
const {
return Kind == k_SysCR; }
1557 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1558 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1559 bool isPHint()
const {
return Kind == k_PHint; }
1560 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1561 bool isCMHPriorityHint()
const {
return Kind == k_CMHPriorityHint; }
1562 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1563 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1564 bool isShifter()
const {
1565 if (!isShiftExtend())
1574 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1575 if (Kind != k_FPImm)
1578 if (getFPImmIsExact()) {
1580 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1582 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1585 APFloat RealVal(APFloat::IEEEdouble());
1587 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1588 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1591 if (
getFPImm().bitwiseIsEqual(RealVal))
1598 template <
unsigned ImmA,
unsigned ImmB>
1599 DiagnosticPredicate isExactFPImm()
const {
1601 if ((Res = isExactFPImm<ImmA>()))
1603 if ((Res = isExactFPImm<ImmB>()))
1608 bool isExtend()
const {
1609 if (!isShiftExtend())
1618 getShiftExtendAmount() <= 4;
1621 bool isExtend64()
const {
1631 bool isExtendLSL64()
const {
1637 getShiftExtendAmount() <= 4;
1640 bool isLSLImm3Shift()
const {
1641 if (!isShiftExtend())
1647 template<
int W
idth>
bool isMemXExtend()
const {
1652 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1653 getShiftExtendAmount() == 0);
1656 template<
int W
idth>
bool isMemWExtend()
const {
1661 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1662 getShiftExtendAmount() == 0);
1665 template <
unsigned w
idth>
1666 bool isArithmeticShifter()
const {
1676 template <
unsigned w
idth>
1677 bool isLogicalShifter()
const {
1685 getShiftExtendAmount() < width;
1688 bool isMovImm32Shifter()
const {
1696 uint64_t Val = getShiftExtendAmount();
1697 return (Val == 0 || Val == 16);
1700 bool isMovImm64Shifter()
const {
1708 uint64_t Val = getShiftExtendAmount();
1709 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1712 bool isLogicalVecShifter()
const {
1717 unsigned Shift = getShiftExtendAmount();
1719 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1722 bool isLogicalVecHalfWordShifter()
const {
1723 if (!isLogicalVecShifter())
1727 unsigned Shift = getShiftExtendAmount();
1729 (Shift == 0 || Shift == 8);
1732 bool isMoveVecShifter()
const {
1733 if (!isShiftExtend())
1737 unsigned Shift = getShiftExtendAmount();
1739 (Shift == 8 || Shift == 16);
1748 bool isSImm9OffsetFB()
const {
1749 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1752 bool isAdrpLabel()
const {
1759 int64_t Val =
CE->getValue();
1760 int64_t Min = - (4096 * (1LL << (21 - 1)));
1761 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1762 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1768 bool isAdrLabel()
const {
1775 int64_t Val =
CE->getValue();
1776 int64_t Min = - (1LL << (21 - 1));
1777 int64_t
Max = ((1LL << (21 - 1)) - 1);
1778 return Val >= Min && Val <=
Max;
1784 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1785 DiagnosticPredicate isMatrixRegOperand()
const {
1788 if (getMatrixKind() != Kind ||
1789 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1790 EltSize != getMatrixElementWidth())
1795 bool isPAuthPCRelLabel16Operand()
const {
1807 return (Val <= 0) && (Val > -(1 << 18));
1810 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1820 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1821 assert(
N == 1 &&
"Invalid number of operands!");
1825 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1826 assert(
N == 1 &&
"Invalid number of operands!");
1830 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1831 assert(
N == 1 &&
"Invalid number of operands!");
1833 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1835 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1842 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1843 assert(
N == 1 &&
"Invalid number of operands!");
1845 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1847 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1854 template <
int W
idth>
1855 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1858 case 8:
Base = AArch64::B0;
break;
1859 case 16:
Base = AArch64::H0;
break;
1860 case 32:
Base = AArch64::S0;
break;
1861 case 64:
Base = AArch64::D0;
break;
1862 case 128:
Base = AArch64::Q0;
break;
1869 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1870 assert(
N == 1 &&
"Invalid number of operands!");
1873 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1874 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1878 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1879 assert(
N == 1 &&
"Invalid number of operands!");
1884 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1885 assert(
N == 1 &&
"Invalid number of operands!");
1886 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1891 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1892 assert(
N == 1 &&
"Invalid number of operands!");
1893 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1898 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1899 assert(
N == 1 &&
"Invalid number of operands!");
1903 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1904 assert(
N == 1 &&
"Invalid number of operands!");
1908 enum VecListIndexType {
1909 VecListIdx_DReg = 0,
1910 VecListIdx_QReg = 1,
1911 VecListIdx_ZReg = 2,
1912 VecListIdx_PReg = 3,
1915 template <VecListIndexType RegTy,
unsigned NumRegs,
1916 bool IsConsecutive =
false>
1917 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1918 assert(
N == 1 &&
"Invalid number of operands!");
1919 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1920 "Expected consecutive registers");
1921 static const unsigned FirstRegs[][5] = {
1923 AArch64::D0, AArch64::D0_D1,
1924 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1926 AArch64::Q0, AArch64::Q0_Q1,
1927 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1929 AArch64::Z0, AArch64::Z0_Z1,
1930 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1932 AArch64::P0, AArch64::P0_P1 }
1935 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1936 " NumRegs must be <= 4 for ZRegs");
1938 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1939 " NumRegs must be <= 2 for PRegs");
1941 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1943 FirstRegs[(
unsigned)RegTy][0]));
1946 template <
unsigned NumRegs>
1947 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1948 assert(
N == 1 &&
"Invalid number of operands!");
1949 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1953 if (getVectorListStart() < AArch64::Z16) {
1954 assert((getVectorListStart() < AArch64::Z8) &&
1955 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1957 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1959 assert((getVectorListStart() < AArch64::Z24) &&
1960 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1962 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1966 if (getVectorListStart() < AArch64::Z16) {
1967 assert((getVectorListStart() < AArch64::Z4) &&
1968 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1970 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1972 assert((getVectorListStart() < AArch64::Z20) &&
1973 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1975 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1983 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1984 assert(
N == 1 &&
"Invalid number of operands!");
1985 unsigned RegMask = getMatrixTileListRegMask();
1986 assert(RegMask <= 0xFF &&
"Invalid mask!");
1990 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1991 assert(
N == 1 &&
"Invalid number of operands!");
1995 template <
unsigned ImmIs0,
unsigned ImmIs1>
1996 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1997 assert(
N == 1 &&
"Invalid number of operands!");
1998 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
2002 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2003 assert(
N == 1 &&
"Invalid number of operands!");
2010 template <
int Shift>
2011 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2012 assert(
N == 2 &&
"Invalid number of operands!");
2013 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2016 }
else if (isShiftedImm()) {
2017 addExpr(Inst, getShiftedImmVal());
2025 template <
int Shift>
2026 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2027 assert(
N == 2 &&
"Invalid number of operands!");
2028 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2035 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2036 assert(
N == 1 &&
"Invalid number of operands!");
2040 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
2041 assert(
N == 1 &&
"Invalid number of operands!");
2049 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2050 addImmOperands(Inst,
N);
2054 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
2055 assert(
N == 1 &&
"Invalid number of operands!");
2065 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2066 assert(
N == 1 &&
"Invalid number of operands!");
2071 template <
int Scale>
2072 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2073 assert(
N == 1 &&
"Invalid number of operands!");
2078 template <
int Scale>
2079 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2080 assert(
N == 1 &&
"Invalid number of operands!");
2084 template <
typename T>
2085 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2086 assert(
N == 1 &&
"Invalid number of operands!");
2088 std::make_unsigned_t<T> Val = MCE->
getValue();
2093 template <
typename T>
2094 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2095 assert(
N == 1 &&
"Invalid number of operands!");
2097 std::make_unsigned_t<T> Val = ~MCE->getValue();
2102 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2103 assert(
N == 1 &&
"Invalid number of operands!");
2109 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2113 assert(
N == 1 &&
"Invalid number of operands!");
2119 assert(MCE &&
"Invalid constant immediate operand!");
2123 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2127 assert(
N == 1 &&
"Invalid number of operands!");
2136 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2140 assert(
N == 1 &&
"Invalid number of operands!");
2146 assert(MCE &&
"Invalid constant immediate operand!");
2150 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2154 assert(
N == 1 &&
"Invalid number of operands!");
2160 assert(MCE &&
"Invalid constant immediate operand!");
2164 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2168 assert(
N == 1 &&
"Invalid number of operands!");
2174 assert(MCE &&
"Invalid constant immediate operand!");
2178 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2179 assert(
N == 1 &&
"Invalid number of operands!");
2184 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2185 assert(
N == 1 &&
"Invalid number of operands!");
2189 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2190 assert(
N == 1 &&
"Invalid number of operands!");
2194 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2195 assert(
N == 1 &&
"Invalid number of operands!");
2200 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2201 assert(
N == 1 &&
"Invalid number of operands!");
2206 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2207 assert(
N == 1 &&
"Invalid number of operands!");
2212 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2213 assert(
N == 1 &&
"Invalid number of operands!");
2218 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2219 assert(
N == 1 &&
"Invalid number of operands!");
2224 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2225 assert(
N == 1 &&
"Invalid number of operands!");
2229 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2230 assert(
N == 1 &&
"Invalid number of operands!");
2234 void addPSBHintOperands(MCInst &Inst,
unsigned N)
const {
2235 assert(
N == 1 &&
"Invalid number of operands!");
2239 void addPHintOperands(MCInst &Inst,
unsigned N)
const {
2240 assert(
N == 1 &&
"Invalid number of operands!");
2244 void addBTIHintOperands(MCInst &Inst,
unsigned N)
const {
2245 assert(
N == 1 &&
"Invalid number of operands!");
2249 void addCMHPriorityHintOperands(MCInst &Inst,
unsigned N)
const {
2250 assert(
N == 1 &&
"Invalid number of operands!");
2254 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2255 assert(
N == 1 &&
"Invalid number of operands!");
2259 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2260 assert(
N == 1 &&
"Invalid number of operands!");
2266 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2267 assert(
N == 1 &&
"Invalid number of operands!");
2268 unsigned Imm = getShiftExtendAmount();
2272 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2273 assert(
N == 1 &&
"Invalid number of operands!");
2278 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2281 if (
Reg != AArch64::XZR)
2287 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2288 assert(
N == 1 &&
"Invalid number of operands!");
2295 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2296 assert(
N == 1 &&
"Invalid number of operands!");
2303 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2304 assert(
N == 2 &&
"Invalid number of operands!");
2315 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2316 assert(
N == 2 &&
"Invalid number of operands!");
2324 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2325 assert(
N == 1 &&
"Invalid number of operands!");
2329 uint64_t
Value =
CE->getValue();
2337 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2338 assert(
N == 1 &&
"Invalid number of operands!");
2341 uint64_t
Value =
CE->getValue();
2345 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2346 assert(
N == 1 &&
"Invalid number of operands!");
2351 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2352 assert(
N == 1 &&
"Invalid number of operands!");
2357 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2359 static std::unique_ptr<AArch64Operand>
2360 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2361 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2362 Op->Tok.Data = Str.data();
2363 Op->Tok.Length = Str.size();
2364 Op->Tok.IsSuffix = IsSuffix;
2370 static std::unique_ptr<AArch64Operand>
2371 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2372 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2374 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2375 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2377 Op->Reg.Kind = Kind;
2378 Op->Reg.ElementWidth = 0;
2379 Op->Reg.EqualityTy = EqTy;
2380 Op->Reg.ShiftExtend.Type = ExtTy;
2381 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2382 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2388 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2389 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2391 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2392 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2393 Kind == RegKind::SVEPredicateVector ||
2394 Kind == RegKind::SVEPredicateAsCounter) &&
2395 "Invalid vector kind");
2396 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2398 Op->Reg.ElementWidth = ElementWidth;
2402 static std::unique_ptr<AArch64Operand>
2403 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2404 unsigned NumElements,
unsigned ElementWidth,
2405 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2406 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2407 Op->VectorList.Reg =
Reg;
2409 Op->VectorList.Stride = Stride;
2410 Op->VectorList.NumElements = NumElements;
2411 Op->VectorList.ElementWidth = ElementWidth;
2412 Op->VectorList.RegisterKind = RegisterKind;
2418 static std::unique_ptr<AArch64Operand>
2419 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2420 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2421 Op->VectorIndex.Val = Idx;
2427 static std::unique_ptr<AArch64Operand>
2428 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2429 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2430 Op->MatrixTileList.RegMask = RegMask;
2436 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2437 const unsigned ElementWidth) {
2438 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2440 {{0, AArch64::ZAB0},
2441 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2442 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2443 {{8, AArch64::ZAB0},
2444 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2445 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2446 {{16, AArch64::ZAH0},
2447 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2448 {{16, AArch64::ZAH1},
2449 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2450 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2451 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2452 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2453 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2456 if (ElementWidth == 64)
2459 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2460 assert(!Regs.empty() &&
"Invalid tile or element width!");
2465 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2466 SMLoc
E, MCContext &Ctx) {
2467 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2474 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2475 unsigned ShiftAmount,
2478 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2479 Op->ShiftedImm .Val = Val;
2480 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2486 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2487 unsigned Last, SMLoc S,
2490 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2492 Op->ImmRange.Last =
Last;
2497 static std::unique_ptr<AArch64Operand>
2499 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2500 Op->CondCode.Code =
Code;
2506 static std::unique_ptr<AArch64Operand>
2507 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2508 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2510 Op->FPImm.IsExact = IsExact;
2516 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2520 bool HasnXSModifier) {
2521 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2522 Op->Barrier.Val = Val;
2523 Op->Barrier.Data = Str.data();
2524 Op->Barrier.Length = Str.size();
2525 Op->Barrier.HasnXSModifier = HasnXSModifier;
2531 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2534 uint32_t PStateField,
2536 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2537 Op->SysReg.Data = Str.data();
2538 Op->SysReg.Length = Str.size();
2539 Op->SysReg.MRSReg = MRSReg;
2540 Op->SysReg.MSRReg = MSRReg;
2541 Op->SysReg.PStateField = PStateField;
2547 static std::unique_ptr<AArch64Operand>
2548 CreatePHintInst(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2549 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2550 Op->PHint.Val = Val;
2551 Op->PHint.Data = Str.data();
2552 Op->PHint.Length = Str.size();
2558 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2559 SMLoc
E, MCContext &Ctx) {
2560 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2561 Op->SysCRImm.Val = Val;
2567 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2571 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2572 Op->Prefetch.Val = Val;
2573 Op->Barrier.Data = Str.data();
2574 Op->Barrier.Length = Str.size();
2580 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2584 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2585 Op->PSBHint.Val = Val;
2586 Op->PSBHint.Data = Str.data();
2587 Op->PSBHint.Length = Str.size();
2593 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2597 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2598 Op->BTIHint.Val = Val | 32;
2599 Op->BTIHint.Data = Str.data();
2600 Op->BTIHint.Length = Str.size();
2606 static std::unique_ptr<AArch64Operand>
2607 CreateCMHPriorityHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2608 auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
2609 Op->CMHPriorityHint.Val = Val;
2610 Op->CMHPriorityHint.Data = Str.data();
2611 Op->CMHPriorityHint.Length = Str.size();
2617 static std::unique_ptr<AArch64Operand>
2618 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2619 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2620 Op->TIndexHint.Val = Val;
2621 Op->TIndexHint.Data = Str.data();
2622 Op->TIndexHint.Length = Str.size();
2628 static std::unique_ptr<AArch64Operand>
2629 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2630 SMLoc S, SMLoc
E, MCContext &Ctx) {
2631 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2632 Op->MatrixReg.Reg =
Reg;
2633 Op->MatrixReg.ElementWidth = ElementWidth;
2634 Op->MatrixReg.Kind = Kind;
2640 static std::unique_ptr<AArch64Operand>
2641 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2642 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2643 Op->SVCR.PStateField = PStateField;
2644 Op->SVCR.Data = Str.data();
2645 Op->SVCR.Length = Str.size();
2651 static std::unique_ptr<AArch64Operand>
2653 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2654 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2655 Op->ShiftExtend.Type = ShOp;
2656 Op->ShiftExtend.Amount = Val;
2657 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2669 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2670 if (!getFPImmIsExact())
2675 StringRef
Name = getBarrierName();
2677 OS <<
"<barrier " <<
Name <<
">";
2679 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2685 case k_ShiftedImm: {
2686 unsigned Shift = getShiftedImmShift();
2687 OS <<
"<shiftedimm ";
2694 OS << getFirstImmVal();
2695 OS <<
":" << getLastImmVal() <<
">";
2701 case k_VectorList: {
2702 OS <<
"<vectorlist ";
2703 MCRegister
Reg = getVectorListStart();
2704 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2705 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2710 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2713 OS <<
"<sysreg: " << getSysReg() <<
'>';
2719 OS <<
"c" << getSysCR();
2722 StringRef
Name = getPrefetchName();
2724 OS <<
"<prfop " <<
Name <<
">";
2726 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2730 OS << getPSBHintName();
2733 OS << getPHintName();
2736 OS << getBTIHintName();
2738 case k_CMHPriorityHint:
2739 OS << getCMHPriorityHintName();
2742 OS << getTIndexHintName();
2744 case k_MatrixRegister:
2745 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2747 case k_MatrixTileList: {
2748 OS <<
"<matrixlist ";
2749 unsigned RegMask = getMatrixTileListRegMask();
2750 unsigned MaxBits = 8;
2751 for (
unsigned I = MaxBits;
I > 0; --
I)
2752 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2761 OS <<
"<register " <<
getReg().
id() <<
">";
2762 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2767 << getShiftExtendAmount();
2768 if (!hasShiftExtendAmount())
2784 .
Case(
"v0", AArch64::Q0)
2785 .
Case(
"v1", AArch64::Q1)
2786 .
Case(
"v2", AArch64::Q2)
2787 .
Case(
"v3", AArch64::Q3)
2788 .
Case(
"v4", AArch64::Q4)
2789 .
Case(
"v5", AArch64::Q5)
2790 .
Case(
"v6", AArch64::Q6)
2791 .
Case(
"v7", AArch64::Q7)
2792 .
Case(
"v8", AArch64::Q8)
2793 .
Case(
"v9", AArch64::Q9)
2794 .
Case(
"v10", AArch64::Q10)
2795 .
Case(
"v11", AArch64::Q11)
2796 .
Case(
"v12", AArch64::Q12)
2797 .
Case(
"v13", AArch64::Q13)
2798 .
Case(
"v14", AArch64::Q14)
2799 .
Case(
"v15", AArch64::Q15)
2800 .
Case(
"v16", AArch64::Q16)
2801 .
Case(
"v17", AArch64::Q17)
2802 .
Case(
"v18", AArch64::Q18)
2803 .
Case(
"v19", AArch64::Q19)
2804 .
Case(
"v20", AArch64::Q20)
2805 .
Case(
"v21", AArch64::Q21)
2806 .
Case(
"v22", AArch64::Q22)
2807 .
Case(
"v23", AArch64::Q23)
2808 .
Case(
"v24", AArch64::Q24)
2809 .
Case(
"v25", AArch64::Q25)
2810 .
Case(
"v26", AArch64::Q26)
2811 .
Case(
"v27", AArch64::Q27)
2812 .
Case(
"v28", AArch64::Q28)
2813 .
Case(
"v29", AArch64::Q29)
2814 .
Case(
"v30", AArch64::Q30)
2815 .
Case(
"v31", AArch64::Q31)
2824 RegKind VectorKind) {
2825 std::pair<int, int> Res = {-1, -1};
2827 switch (VectorKind) {
2828 case RegKind::NeonVector:
2831 .Case(
".1d", {1, 64})
2832 .Case(
".1q", {1, 128})
2834 .Case(
".2h", {2, 16})
2835 .Case(
".2b", {2, 8})
2836 .Case(
".2s", {2, 32})
2837 .Case(
".2d", {2, 64})
2840 .Case(
".4b", {4, 8})
2841 .Case(
".4h", {4, 16})
2842 .Case(
".4s", {4, 32})
2843 .Case(
".8b", {8, 8})
2844 .Case(
".8h", {8, 16})
2845 .Case(
".16b", {16, 8})
2850 .Case(
".h", {0, 16})
2851 .Case(
".s", {0, 32})
2852 .Case(
".d", {0, 64})
2855 case RegKind::SVEPredicateAsCounter:
2856 case RegKind::SVEPredicateVector:
2857 case RegKind::SVEDataVector:
2858 case RegKind::Matrix:
2862 .Case(
".h", {0, 16})
2863 .Case(
".s", {0, 32})
2864 .Case(
".d", {0, 64})
2865 .Case(
".q", {0, 128})
2872 if (Res == std::make_pair(-1, -1))
2873 return std::nullopt;
2875 return std::optional<std::pair<int, int>>(Res);
2884 .
Case(
"z0", AArch64::Z0)
2885 .
Case(
"z1", AArch64::Z1)
2886 .
Case(
"z2", AArch64::Z2)
2887 .
Case(
"z3", AArch64::Z3)
2888 .
Case(
"z4", AArch64::Z4)
2889 .
Case(
"z5", AArch64::Z5)
2890 .
Case(
"z6", AArch64::Z6)
2891 .
Case(
"z7", AArch64::Z7)
2892 .
Case(
"z8", AArch64::Z8)
2893 .
Case(
"z9", AArch64::Z9)
2894 .
Case(
"z10", AArch64::Z10)
2895 .
Case(
"z11", AArch64::Z11)
2896 .
Case(
"z12", AArch64::Z12)
2897 .
Case(
"z13", AArch64::Z13)
2898 .
Case(
"z14", AArch64::Z14)
2899 .
Case(
"z15", AArch64::Z15)
2900 .
Case(
"z16", AArch64::Z16)
2901 .
Case(
"z17", AArch64::Z17)
2902 .
Case(
"z18", AArch64::Z18)
2903 .
Case(
"z19", AArch64::Z19)
2904 .
Case(
"z20", AArch64::Z20)
2905 .
Case(
"z21", AArch64::Z21)
2906 .
Case(
"z22", AArch64::Z22)
2907 .
Case(
"z23", AArch64::Z23)
2908 .
Case(
"z24", AArch64::Z24)
2909 .
Case(
"z25", AArch64::Z25)
2910 .
Case(
"z26", AArch64::Z26)
2911 .
Case(
"z27", AArch64::Z27)
2912 .
Case(
"z28", AArch64::Z28)
2913 .
Case(
"z29", AArch64::Z29)
2914 .
Case(
"z30", AArch64::Z30)
2915 .
Case(
"z31", AArch64::Z31)
2921 .
Case(
"p0", AArch64::P0)
2922 .
Case(
"p1", AArch64::P1)
2923 .
Case(
"p2", AArch64::P2)
2924 .
Case(
"p3", AArch64::P3)
2925 .
Case(
"p4", AArch64::P4)
2926 .
Case(
"p5", AArch64::P5)
2927 .
Case(
"p6", AArch64::P6)
2928 .
Case(
"p7", AArch64::P7)
2929 .
Case(
"p8", AArch64::P8)
2930 .
Case(
"p9", AArch64::P9)
2931 .
Case(
"p10", AArch64::P10)
2932 .
Case(
"p11", AArch64::P11)
2933 .
Case(
"p12", AArch64::P12)
2934 .
Case(
"p13", AArch64::P13)
2935 .
Case(
"p14", AArch64::P14)
2936 .
Case(
"p15", AArch64::P15)
2942 .
Case(
"pn0", AArch64::PN0)
2943 .
Case(
"pn1", AArch64::PN1)
2944 .
Case(
"pn2", AArch64::PN2)
2945 .
Case(
"pn3", AArch64::PN3)
2946 .
Case(
"pn4", AArch64::PN4)
2947 .
Case(
"pn5", AArch64::PN5)
2948 .
Case(
"pn6", AArch64::PN6)
2949 .
Case(
"pn7", AArch64::PN7)
2950 .
Case(
"pn8", AArch64::PN8)
2951 .
Case(
"pn9", AArch64::PN9)
2952 .
Case(
"pn10", AArch64::PN10)
2953 .
Case(
"pn11", AArch64::PN11)
2954 .
Case(
"pn12", AArch64::PN12)
2955 .
Case(
"pn13", AArch64::PN13)
2956 .
Case(
"pn14", AArch64::PN14)
2957 .
Case(
"pn15", AArch64::PN15)
2963 .
Case(
"za0.d", AArch64::ZAD0)
2964 .
Case(
"za1.d", AArch64::ZAD1)
2965 .
Case(
"za2.d", AArch64::ZAD2)
2966 .
Case(
"za3.d", AArch64::ZAD3)
2967 .
Case(
"za4.d", AArch64::ZAD4)
2968 .
Case(
"za5.d", AArch64::ZAD5)
2969 .
Case(
"za6.d", AArch64::ZAD6)
2970 .
Case(
"za7.d", AArch64::ZAD7)
2971 .
Case(
"za0.s", AArch64::ZAS0)
2972 .
Case(
"za1.s", AArch64::ZAS1)
2973 .
Case(
"za2.s", AArch64::ZAS2)
2974 .
Case(
"za3.s", AArch64::ZAS3)
2975 .
Case(
"za0.h", AArch64::ZAH0)
2976 .
Case(
"za1.h", AArch64::ZAH1)
2977 .
Case(
"za0.b", AArch64::ZAB0)
2983 .
Case(
"za", AArch64::ZA)
2984 .
Case(
"za0.q", AArch64::ZAQ0)
2985 .
Case(
"za1.q", AArch64::ZAQ1)
2986 .
Case(
"za2.q", AArch64::ZAQ2)
2987 .
Case(
"za3.q", AArch64::ZAQ3)
2988 .
Case(
"za4.q", AArch64::ZAQ4)
2989 .
Case(
"za5.q", AArch64::ZAQ5)
2990 .
Case(
"za6.q", AArch64::ZAQ6)
2991 .
Case(
"za7.q", AArch64::ZAQ7)
2992 .
Case(
"za8.q", AArch64::ZAQ8)
2993 .
Case(
"za9.q", AArch64::ZAQ9)
2994 .
Case(
"za10.q", AArch64::ZAQ10)
2995 .
Case(
"za11.q", AArch64::ZAQ11)
2996 .
Case(
"za12.q", AArch64::ZAQ12)
2997 .
Case(
"za13.q", AArch64::ZAQ13)
2998 .
Case(
"za14.q", AArch64::ZAQ14)
2999 .
Case(
"za15.q", AArch64::ZAQ15)
3000 .
Case(
"za0.d", AArch64::ZAD0)
3001 .
Case(
"za1.d", AArch64::ZAD1)
3002 .
Case(
"za2.d", AArch64::ZAD2)
3003 .
Case(
"za3.d", AArch64::ZAD3)
3004 .
Case(
"za4.d", AArch64::ZAD4)
3005 .
Case(
"za5.d", AArch64::ZAD5)
3006 .
Case(
"za6.d", AArch64::ZAD6)
3007 .
Case(
"za7.d", AArch64::ZAD7)
3008 .
Case(
"za0.s", AArch64::ZAS0)
3009 .
Case(
"za1.s", AArch64::ZAS1)
3010 .
Case(
"za2.s", AArch64::ZAS2)
3011 .
Case(
"za3.s", AArch64::ZAS3)
3012 .
Case(
"za0.h", AArch64::ZAH0)
3013 .
Case(
"za1.h", AArch64::ZAH1)
3014 .
Case(
"za0.b", AArch64::ZAB0)
3015 .
Case(
"za0h.q", AArch64::ZAQ0)
3016 .
Case(
"za1h.q", AArch64::ZAQ1)
3017 .
Case(
"za2h.q", AArch64::ZAQ2)
3018 .
Case(
"za3h.q", AArch64::ZAQ3)
3019 .
Case(
"za4h.q", AArch64::ZAQ4)
3020 .
Case(
"za5h.q", AArch64::ZAQ5)
3021 .
Case(
"za6h.q", AArch64::ZAQ6)
3022 .
Case(
"za7h.q", AArch64::ZAQ7)
3023 .
Case(
"za8h.q", AArch64::ZAQ8)
3024 .
Case(
"za9h.q", AArch64::ZAQ9)
3025 .
Case(
"za10h.q", AArch64::ZAQ10)
3026 .
Case(
"za11h.q", AArch64::ZAQ11)
3027 .
Case(
"za12h.q", AArch64::ZAQ12)
3028 .
Case(
"za13h.q", AArch64::ZAQ13)
3029 .
Case(
"za14h.q", AArch64::ZAQ14)
3030 .
Case(
"za15h.q", AArch64::ZAQ15)
3031 .
Case(
"za0h.d", AArch64::ZAD0)
3032 .
Case(
"za1h.d", AArch64::ZAD1)
3033 .
Case(
"za2h.d", AArch64::ZAD2)
3034 .
Case(
"za3h.d", AArch64::ZAD3)
3035 .
Case(
"za4h.d", AArch64::ZAD4)
3036 .
Case(
"za5h.d", AArch64::ZAD5)
3037 .
Case(
"za6h.d", AArch64::ZAD6)
3038 .
Case(
"za7h.d", AArch64::ZAD7)
3039 .
Case(
"za0h.s", AArch64::ZAS0)
3040 .
Case(
"za1h.s", AArch64::ZAS1)
3041 .
Case(
"za2h.s", AArch64::ZAS2)
3042 .
Case(
"za3h.s", AArch64::ZAS3)
3043 .
Case(
"za0h.h", AArch64::ZAH0)
3044 .
Case(
"za1h.h", AArch64::ZAH1)
3045 .
Case(
"za0h.b", AArch64::ZAB0)
3046 .
Case(
"za0v.q", AArch64::ZAQ0)
3047 .
Case(
"za1v.q", AArch64::ZAQ1)
3048 .
Case(
"za2v.q", AArch64::ZAQ2)
3049 .
Case(
"za3v.q", AArch64::ZAQ3)
3050 .
Case(
"za4v.q", AArch64::ZAQ4)
3051 .
Case(
"za5v.q", AArch64::ZAQ5)
3052 .
Case(
"za6v.q", AArch64::ZAQ6)
3053 .
Case(
"za7v.q", AArch64::ZAQ7)
3054 .
Case(
"za8v.q", AArch64::ZAQ8)
3055 .
Case(
"za9v.q", AArch64::ZAQ9)
3056 .
Case(
"za10v.q", AArch64::ZAQ10)
3057 .
Case(
"za11v.q", AArch64::ZAQ11)
3058 .
Case(
"za12v.q", AArch64::ZAQ12)
3059 .
Case(
"za13v.q", AArch64::ZAQ13)
3060 .
Case(
"za14v.q", AArch64::ZAQ14)
3061 .
Case(
"za15v.q", AArch64::ZAQ15)
3062 .
Case(
"za0v.d", AArch64::ZAD0)
3063 .
Case(
"za1v.d", AArch64::ZAD1)
3064 .
Case(
"za2v.d", AArch64::ZAD2)
3065 .
Case(
"za3v.d", AArch64::ZAD3)
3066 .
Case(
"za4v.d", AArch64::ZAD4)
3067 .
Case(
"za5v.d", AArch64::ZAD5)
3068 .
Case(
"za6v.d", AArch64::ZAD6)
3069 .
Case(
"za7v.d", AArch64::ZAD7)
3070 .
Case(
"za0v.s", AArch64::ZAS0)
3071 .
Case(
"za1v.s", AArch64::ZAS1)
3072 .
Case(
"za2v.s", AArch64::ZAS2)
3073 .
Case(
"za3v.s", AArch64::ZAS3)
3074 .
Case(
"za0v.h", AArch64::ZAH0)
3075 .
Case(
"za1v.h", AArch64::ZAH1)
3076 .
Case(
"za0v.b", AArch64::ZAB0)
3080bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3082 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3085ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3087 StartLoc = getLoc();
3088 ParseStatus Res = tryParseScalarRegister(
Reg);
3094MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
3096 MCRegister
Reg = MCRegister();
3098 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
3101 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
3104 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
3107 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
3110 return Kind == RegKind::Matrix ?
Reg : MCRegister();
3112 if (
Name.equals_insensitive(
"zt0"))
3113 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
3117 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
3121 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
3122 .Case(
"fp", AArch64::FP)
3123 .Case(
"lr", AArch64::LR)
3124 .Case(
"x31", AArch64::XZR)
3125 .Case(
"w31", AArch64::WZR)
3127 return Kind == RegKind::Scalar ?
Reg : MCRegister();
3133 if (Entry == RegisterReqs.
end())
3134 return MCRegister();
3137 if (Kind ==
Entry->getValue().first)
3143unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3145 case RegKind::Scalar:
3146 case RegKind::NeonVector:
3147 case RegKind::SVEDataVector:
3149 case RegKind::Matrix:
3150 case RegKind::SVEPredicateVector:
3151 case RegKind::SVEPredicateAsCounter:
3153 case RegKind::LookupTable:
3162ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3163 const AsmToken &Tok = getTok();
3168 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3178ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3182 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3185 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3186 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3190 if (BadNum || CRNum > 15)
3191 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3195 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3200ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3202 const AsmToken &Tok = getTok();
3204 unsigned MaxVal = 63;
3209 const MCExpr *ImmVal;
3210 if (getParser().parseExpression(ImmVal))
3215 return TokError(
"immediate value expected for prefetch operand");
3218 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3221 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3222 Operands.
push_back(AArch64Operand::CreatePrefetch(
3223 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3229 return TokError(
"prefetch hint expected");
3231 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3233 return TokError(
"prefetch hint expected");
3235 Operands.
push_back(AArch64Operand::CreatePrefetch(
3242template <
bool IsSVEPrefetch>
3243ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3245 const AsmToken &Tok = getTok();
3247 auto LookupByName = [](StringRef
N) {
3248 if (IsSVEPrefetch) {
3249 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3250 return std::optional<unsigned>(Res->Encoding);
3251 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3252 return std::optional<unsigned>(Res->Encoding);
3253 return std::optional<unsigned>();
3256 auto LookupByEncoding = [](
unsigned E) {
3257 if (IsSVEPrefetch) {
3258 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3259 return std::optional<StringRef>(
3260 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3261 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3262 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3263 return std::optional<StringRef>();
3265 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3271 const MCExpr *ImmVal;
3272 if (getParser().parseExpression(ImmVal))
3277 return TokError(
"immediate value expected for prefetch operand");
3280 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3283 auto PRFM = LookupByEncoding(MCE->
getValue());
3284 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3290 return TokError(
"prefetch hint expected");
3292 auto PRFM = LookupByName(Tok.
getString());
3294 return TokError(
"prefetch hint expected");
3296 Operands.
push_back(AArch64Operand::CreatePrefetch(
3303ParseStatus AArch64AsmParser::tryParsePSBHint(
OperandVector &Operands) {
3305 const AsmToken &Tok = getTok();
3307 return TokError(
"invalid operand for instruction");
3309 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3311 return TokError(
"invalid operand for instruction");
3313 Operands.
push_back(AArch64Operand::CreatePSBHint(
3319ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3320 SMLoc StartLoc = getLoc();
3326 auto RegTok = getTok();
3327 if (!tryParseScalarRegister(RegNum).isSuccess())
3330 if (RegNum != AArch64::XZR) {
3331 getLexer().UnLex(RegTok);
3338 if (!tryParseScalarRegister(RegNum).isSuccess())
3339 return TokError(
"expected register operand");
3341 if (RegNum != AArch64::XZR)
3342 return TokError(
"xzr must be followed by xzr");
3346 Operands.
push_back(AArch64Operand::CreateReg(
3347 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3353ParseStatus AArch64AsmParser::tryParseBTIHint(
OperandVector &Operands) {
3355 const AsmToken &Tok = getTok();
3357 return TokError(
"invalid operand for instruction");
3359 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3361 return TokError(
"invalid operand for instruction");
3363 Operands.
push_back(AArch64Operand::CreateBTIHint(
3370ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(
OperandVector &Operands) {
3372 const AsmToken &Tok = getTok();
3374 return TokError(
"invalid operand for instruction");
3377 AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.
getString());
3379 return TokError(
"invalid operand for instruction");
3381 Operands.
push_back(AArch64Operand::CreateCMHPriorityHint(
3388ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3390 const AsmToken &Tok = getTok();
3392 return TokError(
"invalid operand for instruction");
3394 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3396 return TokError(
"invalid operand for instruction");
3398 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3406ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3408 const MCExpr *Expr =
nullptr;
3414 if (parseSymbolicImmVal(Expr))
3420 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3429 return Error(S,
"gotpage label reference not allowed an addend");
3441 return Error(S,
"page or gotpage label reference expected");
3456ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3458 const MCExpr *Expr =
nullptr;
3467 if (parseSymbolicImmVal(Expr))
3473 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3485 return Error(S,
"unexpected adr label");
3495template <
bool AddFPZeroAsLiteral>
3496ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3504 const AsmToken &Tok = getTok();
3508 return TokError(
"invalid floating point immediate");
3513 if (Tok.
getIntVal() > 255 || isNegative)
3514 return TokError(
"encoded floating point value out of range");
3518 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3521 APFloat RealVal(APFloat::IEEEdouble());
3523 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3525 return TokError(
"invalid floating point representation");
3528 RealVal.changeSign();
3530 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3534 Operands.
push_back(AArch64Operand::CreateFPImm(
3535 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3546AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3557 return tryParseImmRange(Operands);
3559 const MCExpr *
Imm =
nullptr;
3560 if (parseSymbolicImmVal(Imm))
3564 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3571 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3573 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3575 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3581 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3582 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3590 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3592 int64_t ShiftAmount = getTok().getIntVal();
3594 if (ShiftAmount < 0)
3595 return Error(getLoc(),
"positive shift amount required");
3599 if (ShiftAmount == 0 && Imm !=
nullptr) {
3601 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3605 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3613AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3647 Suggestion =
"nfrst";
3653bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3654 bool invertCondCode) {
3656 const AsmToken &Tok = getTok();
3660 std::string Suggestion;
3663 std::string Msg =
"invalid condition code";
3664 if (!Suggestion.empty())
3665 Msg +=
", did you mean " + Suggestion +
"?";
3666 return TokError(Msg);
3670 if (invertCondCode) {
3672 return TokError(
"condition codes AL and NV are invalid for this instruction");
3677 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3681ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3682 const AsmToken &Tok = getTok();
3686 return TokError(
"invalid operand for instruction");
3688 unsigned PStateImm = -1;
3689 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3692 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3693 PStateImm = SVCR->Encoding;
3701ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3702 const AsmToken &Tok = getTok();
3707 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3709 unsigned ElementWidth = 0;
3710 auto DotPosition =
Name.find(
'.');
3712 const auto &KindRes =
3716 "Expected the register to be followed by element width suffix");
3717 ElementWidth = KindRes->second;
3719 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3720 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3725 if (parseOperand(Operands,
false,
false))
3732 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3736 size_t DotPosition =
Name.find(
'.');
3739 StringRef Head =
Name.take_front(DotPosition);
3740 StringRef
Tail =
Name.drop_front(DotPosition);
3741 StringRef RowOrColumn = Head.
take_back();
3743 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3744 .Case(
"h", MatrixKind::Row)
3745 .Case(
"v", MatrixKind::Col)
3746 .Default(MatrixKind::Tile);
3752 "Expected the register to be followed by element width suffix");
3753 unsigned ElementWidth = KindRes->second;
3757 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3763 if (parseOperand(Operands,
false,
false))
3772AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3773 const AsmToken &Tok = getTok();
3776 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3805 return TokError(
"expected #imm after shift specifier");
3811 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3820 return Error(
E,
"expected integer shift amount");
3822 const MCExpr *ImmVal;
3823 if (getParser().parseExpression(ImmVal))
3828 return Error(
E,
"expected constant '#imm' after shift specifier");
3831 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3837 {{
"crc"}, {AArch64::FeatureCRC}},
3838 {{
"sm4"}, {AArch64::FeatureSM4}},
3839 {{
"sha3"}, {AArch64::FeatureSHA3}},
3840 {{
"sha2"}, {AArch64::FeatureSHA2}},
3841 {{
"aes"}, {AArch64::FeatureAES}},
3842 {{
"crypto"}, {AArch64::FeatureCrypto}},
3843 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3844 {{
"simd"}, {AArch64::FeatureNEON}},
3845 {{
"ras"}, {AArch64::FeatureRAS}},
3846 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3847 {{
"lse"}, {AArch64::FeatureLSE}},
3848 {{
"predres"}, {AArch64::FeaturePredRes}},
3849 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3850 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3851 {{
"mte"}, {AArch64::FeatureMTE}},
3852 {{
"memtag"}, {AArch64::FeatureMTE}},
3853 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3854 {{
"pan"}, {AArch64::FeaturePAN}},
3855 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3856 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3857 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3858 {{
"rng"}, {AArch64::FeatureRandGen}},
3859 {{
"sve"}, {AArch64::FeatureSVE}},
3860 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3861 {{
"sve2"}, {AArch64::FeatureSVE2}},
3862 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3863 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3864 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3865 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3866 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3867 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3868 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3870 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3871 AArch64::FeatureSVE2}},
3872 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3873 {{
"ls64"}, {AArch64::FeatureLS64}},
3874 {{
"xs"}, {AArch64::FeatureXS}},
3875 {{
"pauth"}, {AArch64::FeaturePAuth}},
3876 {{
"flagm"}, {AArch64::FeatureFlagM}},
3877 {{
"rme"}, {AArch64::FeatureRME}},
3878 {{
"sme"}, {AArch64::FeatureSME}},
3879 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3880 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3881 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3882 {{
"sme2"}, {AArch64::FeatureSME2}},
3883 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3884 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3885 {{
"hbc"}, {AArch64::FeatureHBC}},
3886 {{
"mops"}, {AArch64::FeatureMOPS}},
3887 {{
"mec"}, {AArch64::FeatureMEC}},
3888 {{
"the"}, {AArch64::FeatureTHE}},
3889 {{
"d128"}, {AArch64::FeatureD128}},
3890 {{
"lse128"}, {AArch64::FeatureLSE128}},
3891 {{
"ite"}, {AArch64::FeatureITE}},
3892 {{
"cssc"}, {AArch64::FeatureCSSC}},
3893 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3894 {{
"gcs"}, {AArch64::FeatureGCS}},
3895 {{
"bf16"}, {AArch64::FeatureBF16}},
3896 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3897 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3898 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3899 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3900 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3901 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3902 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3903 {{
"lor"}, {AArch64::FeatureLOR}},
3904 {{
"profile"}, {AArch64::FeatureSPE}},
3908 {{
"rdm"}, {AArch64::FeatureRDM}},
3909 {{
"rdma"}, {AArch64::FeatureRDM}},
3910 {{
"sb"}, {AArch64::FeatureSB}},
3911 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3912 {{
"fp8"}, {AArch64::FeatureFP8}},
3913 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3914 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3915 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3916 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3917 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3918 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3919 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3920 {{
"lut"}, {AArch64::FeatureLUT}},
3921 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3922 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3923 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3924 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3925 {{
"cpa"}, {AArch64::FeatureCPA}},
3926 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3927 {{
"pops"}, {AArch64::FeaturePoPS}},
3928 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3929 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3930 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3931 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3932 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3933 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3934 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3935 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3936 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3937 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3938 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3939 {{
"lsui"}, {AArch64::FeatureLSUI}},
3940 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3941 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3942 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3943 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3944 {{
"lscp"}, {AArch64::FeatureLSCP}},
3945 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3946 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3947 {{
"gcie"}, {AArch64::FeatureGCIE}},
3948 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3949 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3950 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3951 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3952 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3953 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3954 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3955 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3956 {{
"tev"}, {AArch64::FeatureTEV}},
3957 {{
"btie"}, {AArch64::FeatureBTIE}},
3958 {{
"dit"}, {AArch64::FeatureDIT}},
3959 {{
"brbe"}, {AArch64::FeatureBRBE}},
3960 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3961 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3962 {{
"jscvt"}, {AArch64::FeatureJS}},
3963 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3964 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3965 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3970 if (FBS[AArch64::HasV8_0aOps])
3972 if (FBS[AArch64::HasV8_1aOps])
3974 else if (FBS[AArch64::HasV8_2aOps])
3976 else if (FBS[AArch64::HasV8_3aOps])
3978 else if (FBS[AArch64::HasV8_4aOps])
3980 else if (FBS[AArch64::HasV8_5aOps])
3982 else if (FBS[AArch64::HasV8_6aOps])
3984 else if (FBS[AArch64::HasV8_7aOps])
3986 else if (FBS[AArch64::HasV8_8aOps])
3988 else if (FBS[AArch64::HasV8_9aOps])
3990 else if (FBS[AArch64::HasV9_0aOps])
3992 else if (FBS[AArch64::HasV9_1aOps])
3994 else if (FBS[AArch64::HasV9_2aOps])
3996 else if (FBS[AArch64::HasV9_3aOps])
3998 else if (FBS[AArch64::HasV9_4aOps])
4000 else if (FBS[AArch64::HasV9_5aOps])
4002 else if (FBS[AArch64::HasV9_6aOps])
4004 else if (FBS[AArch64::HasV9_7aOps])
4006 else if (FBS[AArch64::HasV8_0rOps])
4015 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
4019void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
4021 const uint16_t Op2 = Encoding & 7;
4022 const uint16_t Cm = (Encoding & 0x78) >> 3;
4023 const uint16_t Cn = (Encoding & 0x780) >> 7;
4024 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
4029 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4031 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
4033 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
4036 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4042bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
4044 if (
Name.contains(
'.'))
4045 return TokError(
"invalid operand");
4050 const AsmToken &Tok = getTok();
4053 bool ExpectRegister =
true;
4054 bool OptionalRegister =
false;
4055 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
4056 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4058 if (Mnemonic ==
"ic") {
4059 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
4061 return TokError(
"invalid operand for IC instruction");
4062 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
4063 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
4066 return TokError(Str);
4069 createSysAlias(IC->
Encoding, Operands, S);
4070 }
else if (Mnemonic ==
"dc") {
4071 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
4073 return TokError(
"invalid operand for DC instruction");
4074 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
4075 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
4078 return TokError(Str);
4080 createSysAlias(DC->
Encoding, Operands, S);
4081 }
else if (Mnemonic ==
"at") {
4082 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
4084 return TokError(
"invalid operand for AT instruction");
4085 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
4086 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
4089 return TokError(Str);
4091 createSysAlias(AT->
Encoding, Operands, S);
4092 }
else if (Mnemonic ==
"tlbi") {
4093 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
4095 return TokError(
"invalid operand for TLBI instruction");
4096 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
4097 std::string Str(
"TLBI " +
4098 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
4101 return TokError(Str);
4103 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
4104 if (hasAll || hasTLBID)
4105 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
4106 createSysAlias(TLBI->
Encoding, Operands, S);
4107 }
else if (Mnemonic ==
"gic") {
4108 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
4110 return TokError(
"invalid operand for GIC instruction");
4111 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
4112 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
4115 return TokError(Str);
4118 createSysAlias(GIC->
Encoding, Operands, S);
4119 }
else if (Mnemonic ==
"gsb") {
4120 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
4122 return TokError(
"invalid operand for GSB instruction");
4123 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
4124 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
4127 return TokError(Str);
4129 ExpectRegister =
false;
4130 createSysAlias(GSB->
Encoding, Operands, S);
4131 }
else if (Mnemonic ==
"plbi") {
4132 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
4134 return TokError(
"invalid operand for PLBI instruction");
4135 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
4136 std::string Str(
"PLBI " +
4137 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
4140 return TokError(Str);
4142 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
4143 if (hasAll || hasTLBID)
4144 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
4145 createSysAlias(PLBI->
Encoding, Operands, S);
4146 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
4147 Mnemonic ==
"cosp") {
4149 if (
Op.lower() !=
"rctx")
4150 return TokError(
"invalid operand for prediction restriction instruction");
4152 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
4153 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
4155 if (Mnemonic ==
"cosp" && !hasSpecres2)
4156 return TokError(
"COSP requires: predres2");
4158 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
4160 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
4161 : Mnemonic ==
"dvp" ? 0b101
4162 : Mnemonic ==
"cosp" ? 0b110
4163 : Mnemonic ==
"cpp" ? 0b111
4166 "Invalid mnemonic for prediction restriction instruction");
4167 const auto SYS_3_7_3 = 0b01101110011;
4168 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
4170 createSysAlias(Encoding, Operands, S);
4175 bool HasRegister =
false;
4180 return TokError(
"expected register operand");
4184 if (!OptionalRegister) {
4185 if (ExpectRegister && !HasRegister)
4186 return TokError(
"specified " + Mnemonic +
" op requires a register");
4187 else if (!ExpectRegister && HasRegister)
4188 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4200bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4205 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4208 SMLoc startLoc = getLoc();
4209 const AsmToken ®Tok = getTok();
4211 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4213 return TokError(
"expected register operand");
4215 Operands.
push_back(AArch64Operand::CreateReg(
4216 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4223 const AsmToken &operandTok = getTok();
4225 SMLoc S2 = operandTok.
getLoc();
4228 if (Mnemonic ==
"gicr") {
4229 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4231 return Error(S2,
"invalid operand for GICR instruction");
4232 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4233 std::string Str(
"GICR " +
4234 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4237 return Error(S2, Str);
4239 createSysAlias(GICR->
Encoding, Operands, S2);
4250bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4252 if (
Name.contains(
'.'))
4253 return TokError(
"invalid operand");
4257 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4259 const AsmToken &Tok = getTok();
4263 if (Mnemonic ==
"tlbip") {
4264 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4266 return TokError(
"invalid operand for TLBIP instruction");
4269 std::string Str(
"instruction requires: ");
4271 return TokError(Str);
4273 createSysAlias(TLBIP->
Encoding, Operands, S);
4282 return TokError(
"expected register identifier");
4283 auto Result = tryParseSyspXzrPair(Operands);
4285 Result = tryParseGPRSeqPair(Operands);
4287 return TokError(
"specified " + Mnemonic +
4288 " op requires a pair of registers");
4296ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4297 MCAsmParser &Parser = getParser();
4298 const AsmToken &Tok = getTok();
4301 return TokError(
"'csync' operand expected");
4304 const MCExpr *ImmVal;
4305 SMLoc ExprLoc = getLoc();
4306 AsmToken IntTok = Tok;
4307 if (getParser().parseExpression(ImmVal))
4311 return Error(ExprLoc,
"immediate value expected for barrier operand");
4313 if (Mnemonic ==
"dsb" &&
Value > 15) {
4321 return Error(ExprLoc,
"barrier operand out of range");
4322 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4323 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4324 Operands.
push_back(AArch64Operand::CreateBarrier(
4330 return TokError(
"invalid operand for instruction");
4333 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4334 auto DB = AArch64DB::lookupDBByName(Operand);
4336 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4337 return TokError(
"'sy' or #imm operand expected");
4339 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4340 return TokError(
"'csync' operand expected");
4342 if (Mnemonic ==
"dsb") {
4347 return TokError(
"invalid barrier option name");
4350 Operands.
push_back(AArch64Operand::CreateBarrier(
4351 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4359AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4360 const AsmToken &Tok = getTok();
4362 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4363 if (Mnemonic !=
"dsb")
4368 const MCExpr *ImmVal;
4369 SMLoc ExprLoc = getLoc();
4370 if (getParser().parseExpression(ImmVal))
4374 return Error(ExprLoc,
"immediate value expected for barrier operand");
4379 return Error(ExprLoc,
"barrier operand out of range");
4380 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4381 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4382 Operands.
push_back(AArch64Operand::CreateBarrier(
4388 return TokError(
"invalid operand for instruction");
4391 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4394 return TokError(
"invalid barrier option name");
4397 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4404ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4405 const AsmToken &Tok = getTok();
4410 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4414 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4415 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4416 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4417 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4421 unsigned PStateImm = -1;
4422 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4423 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4424 PStateImm = PState15->Encoding;
4426 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4427 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4428 PStateImm = PState1->Encoding;
4432 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4440AArch64AsmParser::tryParsePHintInstOperand(
OperandVector &Operands) {
4442 const AsmToken &Tok = getTok();
4444 return TokError(
"invalid operand for instruction");
4448 return TokError(
"invalid operand for instruction");
4450 Operands.
push_back(AArch64Operand::CreatePHintInst(
4457bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4465 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4473 unsigned ElementWidth = KindRes->second;
4475 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4483 return tryParseVectorIndex(Operands).isFailure();
4486ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4487 SMLoc SIdx = getLoc();
4489 const MCExpr *ImmVal;
4490 if (getParser().parseExpression(ImmVal))
4494 return TokError(
"immediate value expected for vector index");
4512ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4514 RegKind MatchKind) {
4515 const AsmToken &Tok = getTok();
4524 StringRef Head =
Name.slice(Start,
Next);
4525 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4531 return TokError(
"invalid vector kind qualifier");
4542ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4544 ParseStatus Status =
4545 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4547 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4552template <RegKind RK>
4554AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4556 const SMLoc S = getLoc();
4559 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4567 unsigned ElementWidth = KindRes->second;
4568 Operands.
push_back(AArch64Operand::CreateVectorReg(
4569 RegNum, RK, ElementWidth, S,
4573 if (RK == RegKind::SVEPredicateAsCounter) {
4574 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4580 if (parseOperand(Operands,
false,
false))
4591 return Error(S,
"not expecting size suffix");
4599 auto Pred = getTok().getString().lower();
4600 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4601 return Error(getLoc(),
"expecting 'z' predication");
4603 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4604 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4607 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4615bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4617 if (!tryParseNeonVectorRegister(Operands))
4620 if (tryParseZTOperand(Operands).isSuccess())
4624 if (tryParseGPROperand<false>(Operands).isSuccess())
4630bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4631 bool HasELFModifier =
false;
4633 SMLoc Loc = getLexer().getLoc();
4635 HasELFModifier =
true;
4638 return TokError(
"expect relocation specifier in operand after ':'");
4640 std::string LowerCase = getTok().getIdentifier().lower();
4641 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4696 return TokError(
"expect relocation specifier in operand after ':'");
4700 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4704 if (getParser().parseExpression(ImmVal))
4711 if (
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4712 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4722 if (getParser().parsePrimaryExpr(Term, EndLoc))
4730ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4734 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4735 unsigned &ElementWidth) -> ParseStatus {
4736 StringRef
Name = getTok().getString();
4737 size_t DotPosition =
Name.find(
'.');
4745 StringRef
Tail =
Name.drop_front(DotPosition);
4746 const std::optional<std::pair<int, int>> &KindRes =
4750 "Expected the register to be followed by element width suffix");
4751 ElementWidth = KindRes->second;
4758 auto LCurly = getTok();
4763 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4769 if (getTok().getString().equals_insensitive(
"za")) {
4775 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4780 SMLoc TileLoc = getLoc();
4782 unsigned FirstReg, ElementWidth;
4783 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4784 if (!ParseRes.isSuccess()) {
4785 getLexer().UnLex(LCurly);
4789 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4791 unsigned PrevReg = FirstReg;
4793 SmallSet<unsigned, 8> DRegs;
4794 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4796 SmallSet<unsigned, 8> SeenRegs;
4797 SeenRegs.
insert(FirstReg);
4801 unsigned Reg, NextElementWidth;
4802 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4803 if (!ParseRes.isSuccess())
4807 if (ElementWidth != NextElementWidth)
4808 return Error(TileLoc,
"mismatched register size suffix");
4811 Warning(TileLoc,
"tile list not in ascending order");
4814 Warning(TileLoc,
"duplicate tile in list");
4817 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4826 unsigned RegMask = 0;
4827 for (
auto Reg : DRegs)
4831 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4836template <RegKind VectorKind>
4837ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4839 MCAsmParser &Parser = getParser();
4844 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4845 bool NoMatchIsError) -> ParseStatus {
4846 auto RegTok = getTok();
4847 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4848 if (ParseRes.isSuccess()) {
4855 RegTok.getString().equals_insensitive(
"zt0"))
4859 (ParseRes.isNoMatch() && NoMatchIsError &&
4860 !RegTok.getString().starts_with_insensitive(
"za")))
4861 return Error(Loc,
"vector register expected");
4866 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4868 auto LCurly = getTok();
4872 MCRegister FirstReg;
4873 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4877 if (ParseRes.isNoMatch())
4880 if (!ParseRes.isSuccess())
4883 MCRegister PrevReg = FirstReg;
4886 unsigned Stride = 1;
4888 SMLoc Loc = getLoc();
4892 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4893 if (!ParseRes.isSuccess())
4897 if (Kind != NextKind)
4898 return Error(Loc,
"mismatched register size suffix");
4901 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4903 if (Space == 0 || Space > 3)
4904 return Error(Loc,
"invalid number of vectors");
4909 bool HasCalculatedStride =
false;
4911 SMLoc Loc = getLoc();
4914 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4915 if (!ParseRes.isSuccess())
4919 if (Kind != NextKind)
4920 return Error(Loc,
"mismatched register size suffix");
4922 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4923 unsigned PrevRegVal =
4924 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4925 if (!HasCalculatedStride) {
4926 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4927 : (NumRegs - (PrevRegVal - RegVal));
4928 HasCalculatedStride =
true;
4932 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4933 return Error(Loc,
"registers must have the same sequential stride");
4944 return Error(S,
"invalid number of vectors");
4946 unsigned NumElements = 0;
4947 unsigned ElementWidth = 0;
4948 if (!
Kind.empty()) {
4950 std::tie(NumElements, ElementWidth) = *VK;
4953 Operands.
push_back(AArch64Operand::CreateVectorList(
4954 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4958 ParseStatus Res = tryParseVectorIndex(Operands);
4968bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4969 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4970 if (!ParseRes.isSuccess())
4973 return tryParseVectorIndex(Operands).isFailure();
4976ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4977 SMLoc StartLoc = getLoc();
4980 ParseStatus Res = tryParseScalarRegister(RegNum);
4985 Operands.
push_back(AArch64Operand::CreateReg(
4986 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4993 return Error(getLoc(),
"index must be absent or #0");
4995 const MCExpr *ImmVal;
4998 return Error(getLoc(),
"index must be absent or #0");
5000 Operands.
push_back(AArch64Operand::CreateReg(
5001 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
5005ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
5006 SMLoc StartLoc = getLoc();
5007 const AsmToken &Tok = getTok();
5010 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
5015 Operands.
push_back(AArch64Operand::CreateReg(
5016 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
5022 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5023 const MCExpr *ImmVal;
5024 if (getParser().parseExpression(ImmVal))
5028 return TokError(
"immediate value expected for vector index");
5029 Operands.
push_back(AArch64Operand::CreateImm(
5033 if (parseOptionalMulOperand(Operands))
5038 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5043template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
5044ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
5045 SMLoc StartLoc = getLoc();
5048 ParseStatus Res = tryParseScalarRegister(RegNum);
5054 Operands.
push_back(AArch64Operand::CreateReg(
5055 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
5064 Res = tryParseOptionalShiftExtend(ExtOpnd);
5068 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
5069 Operands.
push_back(AArch64Operand::CreateReg(
5070 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
5071 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
5072 Ext->hasShiftExtendAmount()));
5077bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
5078 MCAsmParser &Parser = getParser();
5086 if (!getTok().getString().equals_insensitive(
"mul") ||
5087 !(NextIsVL || NextIsHash))
5091 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
5096 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
5106 const MCExpr *ImmVal;
5109 Operands.
push_back(AArch64Operand::CreateImm(
5116 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
5119bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
5120 StringRef &VecGroup) {
5121 MCAsmParser &Parser = getParser();
5122 auto Tok = Parser.
getTok();
5127 .Case(
"vgx2",
"vgx2")
5128 .Case(
"vgx4",
"vgx4")
5139bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
5140 auto Tok = getTok();
5158bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
5159 bool invertCondCode) {
5160 MCAsmParser &Parser = getParser();
5163 MatchOperandParserImpl(Operands, Mnemonic,
true);
5177 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
5179 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
5182 getLexer().UnLex(SavedTok);
5186 switch (getLexer().getKind()) {
5190 if (parseSymbolicImmVal(Expr))
5191 return Error(S,
"invalid operand");
5195 return parseOptionalShiftExtend(getTok());
5199 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5204 return parseOperand(Operands,
false,
false);
5207 if (!parseNeonVectorList(Operands))
5211 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5216 return parseOperand(Operands,
false,
false);
5221 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5223 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5231 if (!parseRegister(Operands)) {
5233 AsmToken SavedTok = getTok();
5238 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5242 Res = tryParseOptionalShiftExtend(Operands);
5245 getLexer().UnLex(SavedTok);
5252 if (!parseOptionalMulOperand(Operands))
5257 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5259 return parseKeywordOperand(Operands);
5263 const MCExpr *IdVal, *
Term;
5265 if (getParser().parseExpression(IdVal))
5267 if (getParser().parseAtSpecifier(IdVal,
E))
5269 std::optional<MCBinaryExpr::Opcode> Opcode;
5275 if (getParser().parsePrimaryExpr(Term,
E))
5282 return parseOptionalShiftExtend(getTok());
5293 bool isNegative =
false;
5305 const AsmToken &Tok = getTok();
5308 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5309 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5310 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5311 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5312 return TokError(
"unexpected floating point literal");
5313 else if (IntVal != 0 || isNegative)
5314 return TokError(
"expected floating-point constant #0.0");
5322 const MCExpr *ImmVal;
5323 if (parseSymbolicImmVal(ImmVal))
5330 return parseOptionalShiftExtend(Tok);
5333 SMLoc Loc = getLoc();
5334 if (Mnemonic !=
"ldr")
5335 return TokError(
"unexpected token in operand");
5337 const MCExpr *SubExprVal;
5338 if (getParser().parseExpression(SubExprVal))
5341 if (Operands.
size() < 2 ||
5342 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5343 return Error(Loc,
"Only valid when first operand is register");
5345 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5346 .contains(Operands[1]->
getReg());
5353 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5358 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5359 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5360 Operands.
push_back(AArch64Operand::CreateImm(
5364 ShiftAmt,
true, S,
E, Ctx));
5367 APInt Simm = APInt(64, Imm << ShiftAmt);
5370 return Error(Loc,
"Immediate too large for register");
5373 const MCExpr *CPLoc =
5374 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5375 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5381bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5382 const MCExpr *Expr =
nullptr;
5384 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5387 if (check(!
Value, L,
"expected constant expression"))
5389 Out =
Value->getValue();
5393bool AArch64AsmParser::parseComma() {
5401bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5405 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5410 unsigned RangeEnd =
Last;
5411 if (
Base == AArch64::X0) {
5412 if (
Last == AArch64::FP) {
5413 RangeEnd = AArch64::X28;
5414 if (
Reg == AArch64::FP) {
5419 if (
Last == AArch64::LR) {
5420 RangeEnd = AArch64::X28;
5421 if (
Reg == AArch64::FP) {
5424 }
else if (
Reg == AArch64::LR) {
5432 Twine(
"expected register in range ") +
5440bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5441 const MCParsedAsmOperand &Op2)
const {
5442 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5443 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5445 if (AOp1.isVectorList() && AOp2.isVectorList())
5446 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5447 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5448 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5450 if (!AOp1.isReg() || !AOp2.isReg())
5453 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5454 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5457 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5458 "Testing equality of non-scalar registers not supported");
5461 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5463 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5465 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5467 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5474bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5475 StringRef Name, SMLoc NameLoc,
5477 Name = StringSwitch<StringRef>(
Name.lower())
5478 .Case(
"beq",
"b.eq")
5479 .Case(
"bne",
"b.ne")
5480 .Case(
"bhs",
"b.hs")
5481 .Case(
"bcs",
"b.cs")
5482 .Case(
"blo",
"b.lo")
5483 .Case(
"bcc",
"b.cc")
5484 .Case(
"bmi",
"b.mi")
5485 .Case(
"bpl",
"b.pl")
5486 .Case(
"bvs",
"b.vs")
5487 .Case(
"bvc",
"b.vc")
5488 .Case(
"bhi",
"b.hi")
5489 .Case(
"bls",
"b.ls")
5490 .Case(
"bge",
"b.ge")
5491 .Case(
"blt",
"b.lt")
5492 .Case(
"bgt",
"b.gt")
5493 .Case(
"ble",
"b.le")
5494 .Case(
"bal",
"b.al")
5495 .Case(
"bnv",
"b.nv")
5500 getTok().getIdentifier().lower() ==
".req") {
5501 parseDirectiveReq(Name, NameLoc);
5509 StringRef Head =
Name.slice(Start,
Next);
5513 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5514 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5515 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5516 return parseSysAlias(Head, NameLoc, Operands);
5520 return parseSyslAlias(Head, NameLoc, Operands);
5523 if (Head ==
"tlbip")
5524 return parseSyspAlias(Head, NameLoc, Operands);
5533 Head =
Name.slice(Start + 1,
Next);
5537 std::string Suggestion;
5540 std::string Msg =
"invalid condition code";
5541 if (!Suggestion.empty())
5542 Msg +=
", did you mean " + Suggestion +
"?";
5543 return Error(SuffixLoc, Msg);
5548 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5558 Operands.
push_back(AArch64Operand::CreateToken(
5564 bool condCodeFourthOperand =
5565 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5566 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5567 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5575 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5576 bool condCodeThirdOperand =
5577 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5585 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5586 (
N == 3 && condCodeThirdOperand) ||
5587 (
N == 2 && condCodeSecondOperand),
5588 condCodeSecondOperand || condCodeThirdOperand)) {
5608 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5611 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5614 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5627 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5628 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5629 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5630 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5631 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5632 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5633 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5645bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5646 SmallVectorImpl<SMLoc> &Loc) {
5647 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5648 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5654 PrefixInfo
Prefix = NextPrefix;
5655 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5666 return Error(IDLoc,
"instruction is unpredictable when following a"
5667 " movprfx, suggest replacing movprfx with mov");
5671 return Error(Loc[0],
"instruction is unpredictable when following a"
5672 " movprfx writing to a different destination");
5679 return Error(Loc[0],
"instruction is unpredictable when following a"
5680 " movprfx and destination also used as non-destructive"
5684 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5685 if (
Prefix.isPredicated()) {
5699 return Error(IDLoc,
"instruction is unpredictable when following a"
5700 " predicated movprfx, suggest using unpredicated movprfx");
5704 return Error(IDLoc,
"instruction is unpredictable when following a"
5705 " predicated movprfx using a different general predicate");
5709 return Error(IDLoc,
"instruction is unpredictable when following a"
5710 " predicated movprfx with a different element size");
5716 if (IsWindowsArm64EC) {
5722 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5723 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5724 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5725 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5726 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5727 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5728 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5729 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5730 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5731 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5733 " is disallowed on ARM64EC.");
5743 case AArch64::LDPSWpre:
5744 case AArch64::LDPWpost:
5745 case AArch64::LDPWpre:
5746 case AArch64::LDPXpost:
5747 case AArch64::LDPXpre: {
5752 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5753 "is also a destination");
5755 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5756 "is also a destination");
5759 case AArch64::LDR_ZA:
5760 case AArch64::STR_ZA: {
5763 return Error(Loc[1],
5764 "unpredictable instruction, immediate and offset mismatch.");
5767 case AArch64::LDPDi:
5768 case AArch64::LDPQi:
5769 case AArch64::LDPSi:
5770 case AArch64::LDPSWi:
5771 case AArch64::LDPWi:
5772 case AArch64::LDPXi: {
5776 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5779 case AArch64::LDPDpost:
5780 case AArch64::LDPDpre:
5781 case AArch64::LDPQpost:
5782 case AArch64::LDPQpre:
5783 case AArch64::LDPSpost:
5784 case AArch64::LDPSpre:
5785 case AArch64::LDPSWpost: {
5789 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5792 case AArch64::STPDpost:
5793 case AArch64::STPDpre:
5794 case AArch64::STPQpost:
5795 case AArch64::STPQpre:
5796 case AArch64::STPSpost:
5797 case AArch64::STPSpre:
5798 case AArch64::STPWpost:
5799 case AArch64::STPWpre:
5800 case AArch64::STPXpost:
5801 case AArch64::STPXpre: {
5806 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5807 "is also a source");
5809 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5810 "is also a source");
5813 case AArch64::LDRBBpre:
5814 case AArch64::LDRBpre:
5815 case AArch64::LDRHHpre:
5816 case AArch64::LDRHpre:
5817 case AArch64::LDRSBWpre:
5818 case AArch64::LDRSBXpre:
5819 case AArch64::LDRSHWpre:
5820 case AArch64::LDRSHXpre:
5821 case AArch64::LDRSWpre:
5822 case AArch64::LDRWpre:
5823 case AArch64::LDRXpre:
5824 case AArch64::LDRBBpost:
5825 case AArch64::LDRBpost:
5826 case AArch64::LDRHHpost:
5827 case AArch64::LDRHpost:
5828 case AArch64::LDRSBWpost:
5829 case AArch64::LDRSBXpost:
5830 case AArch64::LDRSHWpost:
5831 case AArch64::LDRSHXpost:
5832 case AArch64::LDRSWpost:
5833 case AArch64::LDRWpost:
5834 case AArch64::LDRXpost: {
5838 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5839 "is also a source");
5842 case AArch64::STRBBpost:
5843 case AArch64::STRBpost:
5844 case AArch64::STRHHpost:
5845 case AArch64::STRHpost:
5846 case AArch64::STRWpost:
5847 case AArch64::STRXpost:
5848 case AArch64::STRBBpre:
5849 case AArch64::STRBpre:
5850 case AArch64::STRHHpre:
5851 case AArch64::STRHpre:
5852 case AArch64::STRWpre:
5853 case AArch64::STRXpre: {
5857 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5858 "is also a source");
5861 case AArch64::STXRB:
5862 case AArch64::STXRH:
5863 case AArch64::STXRW:
5864 case AArch64::STXRX:
5865 case AArch64::STLXRB:
5866 case AArch64::STLXRH:
5867 case AArch64::STLXRW:
5868 case AArch64::STLXRX: {
5874 return Error(Loc[0],
5875 "unpredictable STXR instruction, status is also a source");
5878 case AArch64::STXPW:
5879 case AArch64::STXPX:
5880 case AArch64::STLXPW:
5881 case AArch64::STLXPX: {
5888 return Error(Loc[0],
5889 "unpredictable STXP instruction, status is also a source");
5892 case AArch64::LDRABwriteback:
5893 case AArch64::LDRAAwriteback: {
5897 return Error(Loc[0],
5898 "unpredictable LDRA instruction, writeback base"
5899 " is also a destination");
5906 case AArch64::CPYFP:
5907 case AArch64::CPYFPWN:
5908 case AArch64::CPYFPRN:
5909 case AArch64::CPYFPN:
5910 case AArch64::CPYFPWT:
5911 case AArch64::CPYFPWTWN:
5912 case AArch64::CPYFPWTRN:
5913 case AArch64::CPYFPWTN:
5914 case AArch64::CPYFPRT:
5915 case AArch64::CPYFPRTWN:
5916 case AArch64::CPYFPRTRN:
5917 case AArch64::CPYFPRTN:
5918 case AArch64::CPYFPT:
5919 case AArch64::CPYFPTWN:
5920 case AArch64::CPYFPTRN:
5921 case AArch64::CPYFPTN:
5922 case AArch64::CPYFM:
5923 case AArch64::CPYFMWN:
5924 case AArch64::CPYFMRN:
5925 case AArch64::CPYFMN:
5926 case AArch64::CPYFMWT:
5927 case AArch64::CPYFMWTWN:
5928 case AArch64::CPYFMWTRN:
5929 case AArch64::CPYFMWTN:
5930 case AArch64::CPYFMRT:
5931 case AArch64::CPYFMRTWN:
5932 case AArch64::CPYFMRTRN:
5933 case AArch64::CPYFMRTN:
5934 case AArch64::CPYFMT:
5935 case AArch64::CPYFMTWN:
5936 case AArch64::CPYFMTRN:
5937 case AArch64::CPYFMTN:
5938 case AArch64::CPYFE:
5939 case AArch64::CPYFEWN:
5940 case AArch64::CPYFERN:
5941 case AArch64::CPYFEN:
5942 case AArch64::CPYFEWT:
5943 case AArch64::CPYFEWTWN:
5944 case AArch64::CPYFEWTRN:
5945 case AArch64::CPYFEWTN:
5946 case AArch64::CPYFERT:
5947 case AArch64::CPYFERTWN:
5948 case AArch64::CPYFERTRN:
5949 case AArch64::CPYFERTN:
5950 case AArch64::CPYFET:
5951 case AArch64::CPYFETWN:
5952 case AArch64::CPYFETRN:
5953 case AArch64::CPYFETN:
5955 case AArch64::CPYPWN:
5956 case AArch64::CPYPRN:
5957 case AArch64::CPYPN:
5958 case AArch64::CPYPWT:
5959 case AArch64::CPYPWTWN:
5960 case AArch64::CPYPWTRN:
5961 case AArch64::CPYPWTN:
5962 case AArch64::CPYPRT:
5963 case AArch64::CPYPRTWN:
5964 case AArch64::CPYPRTRN:
5965 case AArch64::CPYPRTN:
5966 case AArch64::CPYPT:
5967 case AArch64::CPYPTWN:
5968 case AArch64::CPYPTRN:
5969 case AArch64::CPYPTN:
5971 case AArch64::CPYMWN:
5972 case AArch64::CPYMRN:
5973 case AArch64::CPYMN:
5974 case AArch64::CPYMWT:
5975 case AArch64::CPYMWTWN:
5976 case AArch64::CPYMWTRN:
5977 case AArch64::CPYMWTN:
5978 case AArch64::CPYMRT:
5979 case AArch64::CPYMRTWN:
5980 case AArch64::CPYMRTRN:
5981 case AArch64::CPYMRTN:
5982 case AArch64::CPYMT:
5983 case AArch64::CPYMTWN:
5984 case AArch64::CPYMTRN:
5985 case AArch64::CPYMTN:
5987 case AArch64::CPYEWN:
5988 case AArch64::CPYERN:
5989 case AArch64::CPYEN:
5990 case AArch64::CPYEWT:
5991 case AArch64::CPYEWTWN:
5992 case AArch64::CPYEWTRN:
5993 case AArch64::CPYEWTN:
5994 case AArch64::CPYERT:
5995 case AArch64::CPYERTWN:
5996 case AArch64::CPYERTRN:
5997 case AArch64::CPYERTN:
5998 case AArch64::CPYET:
5999 case AArch64::CPYETWN:
6000 case AArch64::CPYETRN:
6001 case AArch64::CPYETN: {
6012 return Error(Loc[0],
"invalid CPY instruction, destination and source"
6013 " registers are the same");
6015 return Error(Loc[0],
"invalid CPY instruction, destination and size"
6016 " registers are the same");
6018 return Error(Loc[0],
"invalid CPY instruction, source and size"
6019 " registers are the same");
6023 case AArch64::SETPT:
6024 case AArch64::SETPN:
6025 case AArch64::SETPTN:
6027 case AArch64::SETMT:
6028 case AArch64::SETMN:
6029 case AArch64::SETMTN:
6031 case AArch64::SETET:
6032 case AArch64::SETEN:
6033 case AArch64::SETETN:
6034 case AArch64::SETGP:
6035 case AArch64::SETGPT:
6036 case AArch64::SETGPN:
6037 case AArch64::SETGPTN:
6038 case AArch64::SETGM:
6039 case AArch64::SETGMT:
6040 case AArch64::SETGMN:
6041 case AArch64::SETGMTN:
6042 case AArch64::MOPSSETGE:
6043 case AArch64::MOPSSETGET:
6044 case AArch64::MOPSSETGEN:
6045 case AArch64::MOPSSETGETN: {
6055 return Error(Loc[0],
"invalid SET instruction, destination and size"
6056 " registers are the same");
6058 return Error(Loc[0],
"invalid SET instruction, destination and source"
6059 " registers are the same");
6061 return Error(Loc[0],
"invalid SET instruction, source and size"
6062 " registers are the same");
6065 case AArch64::SETGOP:
6066 case AArch64::SETGOPT:
6067 case AArch64::SETGOPN:
6068 case AArch64::SETGOPTN:
6069 case AArch64::SETGOM:
6070 case AArch64::SETGOMT:
6071 case AArch64::SETGOMN:
6072 case AArch64::SETGOMTN:
6073 case AArch64::SETGOE:
6074 case AArch64::SETGOET:
6075 case AArch64::SETGOEN:
6076 case AArch64::SETGOETN: {
6085 return Error(Loc[0],
"invalid SET instruction, destination and size"
6086 " registers are the same");
6095 case AArch64::ADDSWri:
6096 case AArch64::ADDSXri:
6097 case AArch64::ADDWri:
6098 case AArch64::ADDXri:
6099 case AArch64::SUBSWri:
6100 case AArch64::SUBSXri:
6101 case AArch64::SUBWri:
6102 case AArch64::SUBXri: {
6110 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
6135 return Error(Loc.
back(),
"invalid immediate expression");
6148 unsigned VariantID = 0);
6150bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
6154 case Match_InvalidTiedOperand: {
6155 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
6156 if (
Op.isVectorList())
6157 return Error(
Loc,
"operand must match destination register list");
6159 assert(
Op.isReg() &&
"Unexpected operand type");
6160 switch (
Op.getRegEqualityTy()) {
6161 case RegConstraintEqualityTy::EqualsSubReg:
6162 return Error(
Loc,
"operand must be 64-bit form of destination register");
6163 case RegConstraintEqualityTy::EqualsSuperReg:
6164 return Error(
Loc,
"operand must be 32-bit form of destination register");
6165 case RegConstraintEqualityTy::EqualsReg:
6166 return Error(
Loc,
"operand must match destination register");
6170 case Match_MissingFeature:
6172 "instruction requires a CPU feature not currently enabled");
6173 case Match_InvalidOperand:
6174 return Error(Loc,
"invalid operand for instruction");
6175 case Match_InvalidSuffix:
6176 return Error(Loc,
"invalid type suffix for instruction");
6177 case Match_InvalidCondCode:
6178 return Error(Loc,
"expected AArch64 condition code");
6179 case Match_AddSubRegExtendSmall:
6181 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
6182 case Match_AddSubRegExtendLarge:
6184 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
6185 case Match_AddSubSecondSource:
6187 "expected compatible register, symbol or integer in range [0, 4095]");
6188 case Match_LogicalSecondSource:
6189 return Error(Loc,
"expected compatible register or logical immediate");
6190 case Match_InvalidMovImm32Shift:
6191 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
6192 case Match_InvalidMovImm64Shift:
6193 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
6194 case Match_AddSubRegShift32:
6196 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
6197 case Match_AddSubRegShift64:
6199 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
6200 case Match_InvalidFPImm:
6202 "expected compatible register or floating-point constant");
6203 case Match_InvalidMemoryIndexedSImm6:
6204 return Error(Loc,
"index must be an integer in range [-32, 31].");
6205 case Match_InvalidMemoryIndexedSImm5:
6206 return Error(Loc,
"index must be an integer in range [-16, 15].");
6207 case Match_InvalidMemoryIndexed1SImm4:
6208 return Error(Loc,
"index must be an integer in range [-8, 7].");
6209 case Match_InvalidMemoryIndexed2SImm4:
6210 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6211 case Match_InvalidMemoryIndexed3SImm4:
6212 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6213 case Match_InvalidMemoryIndexed4SImm4:
6214 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6215 case Match_InvalidMemoryIndexed16SImm4:
6216 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6217 case Match_InvalidMemoryIndexed32SImm4:
6218 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6219 case Match_InvalidMemoryIndexed1SImm6:
6220 return Error(Loc,
"index must be an integer in range [-32, 31].");
6221 case Match_InvalidMemoryIndexedSImm8:
6222 return Error(Loc,
"index must be an integer in range [-128, 127].");
6223 case Match_InvalidMemoryIndexedSImm9:
6224 return Error(Loc,
"index must be an integer in range [-256, 255].");
6225 case Match_InvalidMemoryIndexed16SImm9:
6226 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6227 case Match_InvalidMemoryIndexed8SImm10:
6228 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6229 case Match_InvalidMemoryIndexed4SImm7:
6230 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6231 case Match_InvalidMemoryIndexed8SImm7:
6232 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6233 case Match_InvalidMemoryIndexed16SImm7:
6234 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6235 case Match_InvalidMemoryIndexed8UImm5:
6236 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6237 case Match_InvalidMemoryIndexed8UImm3:
6238 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6239 case Match_InvalidMemoryIndexed4UImm5:
6240 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6241 case Match_InvalidMemoryIndexed2UImm5:
6242 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6243 case Match_InvalidMemoryIndexed8UImm6:
6244 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6245 case Match_InvalidMemoryIndexed16UImm6:
6246 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6247 case Match_InvalidMemoryIndexed4UImm6:
6248 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6249 case Match_InvalidMemoryIndexed2UImm6:
6250 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6251 case Match_InvalidMemoryIndexed1UImm6:
6252 return Error(Loc,
"index must be in range [0, 63].");
6253 case Match_InvalidMemoryWExtend8:
6255 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6256 case Match_InvalidMemoryWExtend16:
6258 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6259 case Match_InvalidMemoryWExtend32:
6261 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6262 case Match_InvalidMemoryWExtend64:
6264 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6265 case Match_InvalidMemoryWExtend128:
6267 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6268 case Match_InvalidMemoryXExtend8:
6270 "expected 'lsl' or 'sxtx' with optional shift of #0");
6271 case Match_InvalidMemoryXExtend16:
6273 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6274 case Match_InvalidMemoryXExtend32:
6276 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6277 case Match_InvalidMemoryXExtend64:
6279 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6280 case Match_InvalidMemoryXExtend128:
6282 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6283 case Match_InvalidMemoryIndexed1:
6284 return Error(Loc,
"index must be an integer in range [0, 4095].");
6285 case Match_InvalidMemoryIndexed2:
6286 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6287 case Match_InvalidMemoryIndexed4:
6288 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6289 case Match_InvalidMemoryIndexed8:
6290 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6291 case Match_InvalidMemoryIndexed16:
6292 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6293 case Match_InvalidImm0_0:
6294 return Error(Loc,
"immediate must be 0.");
6295 case Match_InvalidImm0_1:
6296 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6297 case Match_InvalidImm0_3:
6298 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6299 case Match_InvalidImm0_7:
6300 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6301 case Match_InvalidImm0_15:
6302 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6303 case Match_InvalidImm0_31:
6304 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6305 case Match_InvalidImm0_63:
6306 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6307 case Match_InvalidImm0_127:
6308 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6309 case Match_InvalidImm0_255:
6310 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6311 case Match_InvalidImm0_65535:
6312 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6313 case Match_InvalidImm1_8:
6314 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6315 case Match_InvalidImm1_16:
6316 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6317 case Match_InvalidImm1_32:
6318 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6319 case Match_InvalidImm1_64:
6320 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6321 case Match_InvalidImmM1_62:
6322 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6323 case Match_InvalidMemoryIndexedRange2UImm0:
6324 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6325 case Match_InvalidMemoryIndexedRange2UImm1:
6326 return Error(Loc,
"vector select offset must be an immediate range of the "
6327 "form <immf>:<imml>, where the first "
6328 "immediate is a multiple of 2 in the range [0, 2], and "
6329 "the second immediate is immf + 1.");
6330 case Match_InvalidMemoryIndexedRange2UImm2:
6331 case Match_InvalidMemoryIndexedRange2UImm3:
6334 "vector select offset must be an immediate range of the form "
6336 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6338 "depending on the instruction, and the second immediate is immf + 1.");
6339 case Match_InvalidMemoryIndexedRange4UImm0:
6340 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6341 case Match_InvalidMemoryIndexedRange4UImm1:
6342 case Match_InvalidMemoryIndexedRange4UImm2:
6345 "vector select offset must be an immediate range of the form "
6347 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6349 "depending on the instruction, and the second immediate is immf + 3.");
6350 case Match_InvalidSVEAddSubImm8:
6351 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6352 " with a shift amount of 0");
6353 case Match_InvalidSVEAddSubImm16:
6354 case Match_InvalidSVEAddSubImm32:
6355 case Match_InvalidSVEAddSubImm64:
6356 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6357 "multiple of 256 in range [256, 65280]");
6358 case Match_InvalidSVECpyImm8:
6359 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6360 " with a shift amount of 0");
6361 case Match_InvalidSVECpyImm16:
6362 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6363 "multiple of 256 in range [-32768, 65280]");
6364 case Match_InvalidSVECpyImm32:
6365 case Match_InvalidSVECpyImm64:
6366 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6367 "multiple of 256 in range [-32768, 32512]");
6368 case Match_InvalidIndexRange0_0:
6369 return Error(Loc,
"expected lane specifier '[0]'");
6370 case Match_InvalidIndexRange1_1:
6371 return Error(Loc,
"expected lane specifier '[1]'");
6372 case Match_InvalidIndexRange0_15:
6373 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6374 case Match_InvalidIndexRange0_7:
6375 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6376 case Match_InvalidIndexRange0_3:
6377 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6378 case Match_InvalidIndexRange0_1:
6379 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6380 case Match_InvalidSVEIndexRange0_63:
6381 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6382 case Match_InvalidSVEIndexRange0_31:
6383 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6384 case Match_InvalidSVEIndexRange0_15:
6385 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6386 case Match_InvalidSVEIndexRange0_7:
6387 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6388 case Match_InvalidSVEIndexRange0_3:
6389 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6390 case Match_InvalidLabel:
6391 return Error(Loc,
"expected label or encodable integer pc offset");
6393 return Error(Loc,
"expected readable system register");
6395 case Match_InvalidSVCR:
6396 return Error(Loc,
"expected writable system register or pstate");
6397 case Match_InvalidComplexRotationEven:
6398 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6399 case Match_InvalidComplexRotationOdd:
6400 return Error(Loc,
"complex rotation must be 90 or 270.");
6401 case Match_MnemonicFail: {
6403 ((AArch64Operand &)*Operands[0]).
getToken(),
6404 ComputeAvailableFeatures(STI->getFeatureBits()));
6405 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6407 case Match_InvalidGPR64shifted8:
6408 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6409 case Match_InvalidGPR64shifted16:
6410 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6411 case Match_InvalidGPR64shifted32:
6412 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6413 case Match_InvalidGPR64shifted64:
6414 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6415 case Match_InvalidGPR64shifted128:
6417 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6418 case Match_InvalidGPR64NoXZRshifted8:
6419 return Error(Loc,
"register must be x0..x30 without shift");
6420 case Match_InvalidGPR64NoXZRshifted16:
6421 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6422 case Match_InvalidGPR64NoXZRshifted32:
6423 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6424 case Match_InvalidGPR64NoXZRshifted64:
6425 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6426 case Match_InvalidGPR64NoXZRshifted128:
6427 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6428 case Match_InvalidZPR32UXTW8:
6429 case Match_InvalidZPR32SXTW8:
6430 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6431 case Match_InvalidZPR32UXTW16:
6432 case Match_InvalidZPR32SXTW16:
6433 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6434 case Match_InvalidZPR32UXTW32:
6435 case Match_InvalidZPR32SXTW32:
6436 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6437 case Match_InvalidZPR32UXTW64:
6438 case Match_InvalidZPR32SXTW64:
6439 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6440 case Match_InvalidZPR64UXTW8:
6441 case Match_InvalidZPR64SXTW8:
6442 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6443 case Match_InvalidZPR64UXTW16:
6444 case Match_InvalidZPR64SXTW16:
6445 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6446 case Match_InvalidZPR64UXTW32:
6447 case Match_InvalidZPR64SXTW32:
6448 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6449 case Match_InvalidZPR64UXTW64:
6450 case Match_InvalidZPR64SXTW64:
6451 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6452 case Match_InvalidZPR32LSL8:
6453 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6454 case Match_InvalidZPR32LSL16:
6455 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6456 case Match_InvalidZPR32LSL32:
6457 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6458 case Match_InvalidZPR32LSL64:
6459 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6460 case Match_InvalidZPR64LSL8:
6461 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6462 case Match_InvalidZPR64LSL16:
6463 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6464 case Match_InvalidZPR64LSL32:
6465 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6466 case Match_InvalidZPR64LSL64:
6467 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6468 case Match_InvalidZPR0:
6469 return Error(Loc,
"expected register without element width suffix");
6470 case Match_InvalidZPR8:
6471 case Match_InvalidZPR16:
6472 case Match_InvalidZPR32:
6473 case Match_InvalidZPR64:
6474 case Match_InvalidZPR128:
6475 return Error(Loc,
"invalid element width");
6476 case Match_InvalidZPR_3b8:
6477 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6478 case Match_InvalidZPR_3b16:
6479 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6480 case Match_InvalidZPR_3b32:
6481 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6482 case Match_InvalidZPR_4b8:
6484 "Invalid restricted vector register, expected z0.b..z15.b");
6485 case Match_InvalidZPR_4b16:
6486 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6487 case Match_InvalidZPR_4b32:
6488 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6489 case Match_InvalidZPR_4b64:
6490 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6491 case Match_InvalidZPRMul2_Lo8:
6492 return Error(Loc,
"Invalid restricted vector register, expected even "
6493 "register in z0.b..z14.b");
6494 case Match_InvalidZPRMul2_Hi8:
6495 return Error(Loc,
"Invalid restricted vector register, expected even "
6496 "register in z16.b..z30.b");
6497 case Match_InvalidZPRMul2_Lo16:
6498 return Error(Loc,
"Invalid restricted vector register, expected even "
6499 "register in z0.h..z14.h");
6500 case Match_InvalidZPRMul2_Hi16:
6501 return Error(Loc,
"Invalid restricted vector register, expected even "
6502 "register in z16.h..z30.h");
6503 case Match_InvalidZPRMul2_Lo32:
6504 return Error(Loc,
"Invalid restricted vector register, expected even "
6505 "register in z0.s..z14.s");
6506 case Match_InvalidZPRMul2_Hi32:
6507 return Error(Loc,
"Invalid restricted vector register, expected even "
6508 "register in z16.s..z30.s");
6509 case Match_InvalidZPRMul2_Lo64:
6510 return Error(Loc,
"Invalid restricted vector register, expected even "
6511 "register in z0.d..z14.d");
6512 case Match_InvalidZPRMul2_Hi64:
6513 return Error(Loc,
"Invalid restricted vector register, expected even "
6514 "register in z16.d..z30.d");
6515 case Match_InvalidZPR_K0:
6516 return Error(Loc,
"invalid restricted vector register, expected register "
6517 "in z20..z23 or z28..z31");
6518 case Match_InvalidSVEPattern:
6519 return Error(Loc,
"invalid predicate pattern");
6520 case Match_InvalidSVEPPRorPNRAnyReg:
6521 case Match_InvalidSVEPPRorPNRBReg:
6522 case Match_InvalidSVEPredicateAnyReg:
6523 case Match_InvalidSVEPredicateBReg:
6524 case Match_InvalidSVEPredicateHReg:
6525 case Match_InvalidSVEPredicateSReg:
6526 case Match_InvalidSVEPredicateDReg:
6527 return Error(Loc,
"invalid predicate register.");
6528 case Match_InvalidSVEPredicate3bAnyReg:
6529 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6530 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6531 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6532 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6533 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6534 return Error(Loc,
"Invalid predicate register, expected PN in range "
6535 "pn8..pn15 with element suffix.");
6536 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6537 return Error(Loc,
"invalid restricted predicate-as-counter register "
6538 "expected pn8..pn15");
6539 case Match_InvalidSVEPNPredicateBReg:
6540 case Match_InvalidSVEPNPredicateHReg:
6541 case Match_InvalidSVEPNPredicateSReg:
6542 case Match_InvalidSVEPNPredicateDReg:
6543 return Error(Loc,
"Invalid predicate register, expected PN in range "
6544 "pn0..pn15 with element suffix.");
6545 case Match_InvalidSVEVecLenSpecifier:
6546 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6547 case Match_InvalidSVEPredicateListMul2x8:
6548 case Match_InvalidSVEPredicateListMul2x16:
6549 case Match_InvalidSVEPredicateListMul2x32:
6550 case Match_InvalidSVEPredicateListMul2x64:
6551 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6552 "predicate registers, where the first vector is a multiple of 2 "
6553 "and with correct element type");
6554 case Match_InvalidSVEExactFPImmOperandHalfOne:
6555 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6556 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6557 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6558 case Match_InvalidSVEExactFPImmOperandZeroOne:
6559 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6560 case Match_InvalidMatrixTileVectorH8:
6561 case Match_InvalidMatrixTileVectorV8:
6562 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6563 case Match_InvalidMatrixTileVectorH16:
6564 case Match_InvalidMatrixTileVectorV16:
6566 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6567 case Match_InvalidMatrixTileVectorH32:
6568 case Match_InvalidMatrixTileVectorV32:
6570 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6571 case Match_InvalidMatrixTileVectorH64:
6572 case Match_InvalidMatrixTileVectorV64:
6574 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6575 case Match_InvalidMatrixTileVectorH128:
6576 case Match_InvalidMatrixTileVectorV128:
6578 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6579 case Match_InvalidMatrixTile16:
6580 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6581 case Match_InvalidMatrixTile32:
6582 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6583 case Match_InvalidMatrixTile64:
6584 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6585 case Match_InvalidMatrix:
6586 return Error(Loc,
"invalid matrix operand, expected za");
6587 case Match_InvalidMatrix8:
6588 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6589 case Match_InvalidMatrix16:
6590 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6591 case Match_InvalidMatrix32:
6592 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6593 case Match_InvalidMatrix64:
6594 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6595 case Match_InvalidMatrixIndexGPR32_12_15:
6596 return Error(Loc,
"operand must be a register in range [w12, w15]");
6597 case Match_InvalidMatrixIndexGPR32_8_11:
6598 return Error(Loc,
"operand must be a register in range [w8, w11]");
6599 case Match_InvalidSVEVectorList2x8Mul2:
6600 case Match_InvalidSVEVectorList2x16Mul2:
6601 case Match_InvalidSVEVectorList2x32Mul2:
6602 case Match_InvalidSVEVectorList2x64Mul2:
6603 case Match_InvalidSVEVectorList2x128Mul2:
6604 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6605 "SVE vectors, where the first vector is a multiple of 2 "
6606 "and with matching element types");
6607 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6608 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6609 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6610 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6611 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6612 "SVE vectors in the range z0-z14, where the first vector "
6613 "is a multiple of 2 "
6614 "and with matching element types");
6615 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6616 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6617 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6618 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6620 "Invalid vector list, expected list with 2 consecutive "
6621 "SVE vectors in the range z16-z30, where the first vector "
6622 "is a multiple of 2 "
6623 "and with matching element types");
6624 case Match_InvalidSVEVectorList4x8Mul4:
6625 case Match_InvalidSVEVectorList4x16Mul4:
6626 case Match_InvalidSVEVectorList4x32Mul4:
6627 case Match_InvalidSVEVectorList4x64Mul4:
6628 case Match_InvalidSVEVectorList4x128Mul4:
6629 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6630 "SVE vectors, where the first vector is a multiple of 4 "
6631 "and with matching element types");
6632 case Match_InvalidLookupTable:
6633 return Error(Loc,
"Invalid lookup table, expected zt0");
6634 case Match_InvalidSVEVectorListStrided2x8:
6635 case Match_InvalidSVEVectorListStrided2x16:
6636 case Match_InvalidSVEVectorListStrided2x32:
6637 case Match_InvalidSVEVectorListStrided2x64:
6640 "Invalid vector list, expected list with each SVE vector in the list "
6641 "8 registers apart, and the first register in the range [z0, z7] or "
6642 "[z16, z23] and with correct element type");
6643 case Match_InvalidSVEVectorListStrided4x8:
6644 case Match_InvalidSVEVectorListStrided4x16:
6645 case Match_InvalidSVEVectorListStrided4x32:
6646 case Match_InvalidSVEVectorListStrided4x64:
6649 "Invalid vector list, expected list with each SVE vector in the list "
6650 "4 registers apart, and the first register in the range [z0, z3] or "
6651 "[z16, z19] and with correct element type");
6652 case Match_AddSubLSLImm3ShiftLarge:
6654 "expected 'lsl' with optional integer in range [0, 7]");
6662bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6666 bool MatchingInlineAsm) {
6667 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6668 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6669 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6672 unsigned NumOperands = Operands.
size();
6674 if (NumOperands == 4 && Tok ==
"lsl") {
6675 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6676 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6677 if (Op2.isScalarReg() && Op3.isImm()) {
6683 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6685 NewOp3Val = (32 - Op3Val) & 0x1f;
6686 NewOp4Val = 31 - Op3Val;
6688 NewOp3Val = (64 - Op3Val) & 0x3f;
6689 NewOp4Val = 63 - Op3Val;
6696 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6697 Operands.
push_back(AArch64Operand::CreateImm(
6698 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6699 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6703 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6705 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6706 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6707 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6709 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6713 if (LSBCE && WidthCE) {
6715 uint64_t Width = WidthCE->
getValue();
6717 uint64_t RegWidth = 0;
6718 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6724 if (LSB >= RegWidth)
6725 return Error(LSBOp.getStartLoc(),
6726 "expected integer in range [0, 31]");
6727 if (Width < 1 || Width > RegWidth)
6728 return Error(WidthOp.getStartLoc(),
6729 "expected integer in range [1, 32]");
6733 ImmR = (32 - LSB) & 0x1f;
6735 ImmR = (64 - LSB) & 0x3f;
6737 uint64_t ImmS = Width - 1;
6739 if (ImmR != 0 && ImmS >= ImmR)
6740 return Error(WidthOp.getStartLoc(),
6741 "requested insert overflows register");
6746 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6747 Operands[2] = AArch64Operand::CreateReg(
6748 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6750 Operands[3] = AArch64Operand::CreateImm(
6751 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6753 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6757 }
else if (NumOperands == 5) {
6760 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6761 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6762 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6763 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6765 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6769 if (Op3CE && Op4CE) {
6770 uint64_t Op3Val = Op3CE->
getValue();
6771 uint64_t Op4Val = Op4CE->
getValue();
6773 uint64_t RegWidth = 0;
6774 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6780 if (Op3Val >= RegWidth)
6781 return Error(Op3.getStartLoc(),
6782 "expected integer in range [0, 31]");
6783 if (Op4Val < 1 || Op4Val > RegWidth)
6784 return Error(Op4.getStartLoc(),
6785 "expected integer in range [1, 32]");
6787 uint64_t NewOp3Val = 0;
6789 NewOp3Val = (32 - Op3Val) & 0x1f;
6791 NewOp3Val = (64 - Op3Val) & 0x3f;
6793 uint64_t NewOp4Val = Op4Val - 1;
6795 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6796 return Error(Op4.getStartLoc(),
6797 "requested insert overflows register");
6799 const MCExpr *NewOp3 =
6801 const MCExpr *NewOp4 =
6803 Operands[3] = AArch64Operand::CreateImm(
6804 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6805 Operands[4] = AArch64Operand::CreateImm(
6806 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6808 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6810 else if (Tok ==
"sbfiz")
6811 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6813 else if (Tok ==
"ubfiz")
6814 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6823 }
else if (NumOperands == 5 &&
6824 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6825 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6826 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6827 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6829 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6833 if (Op3CE && Op4CE) {
6834 uint64_t Op3Val = Op3CE->
getValue();
6835 uint64_t Op4Val = Op4CE->
getValue();
6837 uint64_t RegWidth = 0;
6838 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6844 if (Op3Val >= RegWidth)
6845 return Error(Op3.getStartLoc(),
6846 "expected integer in range [0, 31]");
6847 if (Op4Val < 1 || Op4Val > RegWidth)
6848 return Error(Op4.getStartLoc(),
6849 "expected integer in range [1, 32]");
6851 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6853 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6854 return Error(Op4.getStartLoc(),
6855 "requested extract overflows register");
6857 const MCExpr *NewOp4 =
6859 Operands[4] = AArch64Operand::CreateImm(
6860 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6862 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6864 else if (Tok ==
"sbfx")
6865 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6867 else if (Tok ==
"ubfx")
6868 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6881 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6882 NumOperands == 4 && Tok ==
"movi") {
6883 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6884 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6885 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6886 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6887 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6888 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6889 if (Suffix.
lower() ==
".2d" &&
6891 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6892 " correctly on this CPU, converting to equivalent movi.16b");
6894 unsigned Idx = Op1.isToken() ? 1 : 2;
6896 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6904 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6907 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6908 if (
Op.isScalarReg()) {
6910 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6911 Op.getStartLoc(),
Op.getEndLoc(),
6916 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6917 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6918 if (
Op.isScalarReg() &&
6919 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6923 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6924 if (
Op.isScalarReg()) {
6926 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6933 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6934 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6935 if (
Op.isScalarReg() &&
6936 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6940 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6941 if (
Op.isScalarReg()) {
6943 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6951 FeatureBitset MissingFeatures;
6954 unsigned MatchResult =
6955 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6956 MatchingInlineAsm, 1);
6960 if (MatchResult != Match_Success) {
6963 auto ShortFormNEONErrorInfo = ErrorInfo;
6964 auto ShortFormNEONMatchResult = MatchResult;
6965 auto ShortFormNEONMissingFeatures = MissingFeatures;
6968 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6969 MatchingInlineAsm, 0);
6974 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6975 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6976 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6977 MatchResult = ShortFormNEONMatchResult;
6978 ErrorInfo = ShortFormNEONErrorInfo;
6979 MissingFeatures = ShortFormNEONMissingFeatures;
6983 switch (MatchResult) {
6984 case Match_Success: {
6987 NumOperands = Operands.
size();
6988 for (
unsigned i = 1; i < NumOperands; ++i)
6989 OperandLocs.
push_back(Operands[i]->getStartLoc());
6990 if (validateInstruction(Inst, IDLoc, OperandLocs))
6997 case Match_MissingFeature: {
6998 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
7001 std::string Msg =
"instruction requires:";
7002 for (
unsigned Feature : MissingFeatures) {
7006 return Error(IDLoc, Msg);
7008 case Match_MnemonicFail:
7009 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
7010 case Match_InvalidOperand: {
7011 SMLoc ErrorLoc = IDLoc;
7013 if (ErrorInfo != ~0ULL) {
7014 if (ErrorInfo >= Operands.
size())
7015 return Error(IDLoc,
"too few operands for instruction",
7016 SMRange(IDLoc, getTok().getLoc()));
7018 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7019 if (ErrorLoc == SMLoc())
7024 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
7025 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
7026 MatchResult = Match_InvalidSuffix;
7028 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7030 case Match_InvalidTiedOperand:
7031 case Match_InvalidMemoryIndexed1:
7032 case Match_InvalidMemoryIndexed2:
7033 case Match_InvalidMemoryIndexed4:
7034 case Match_InvalidMemoryIndexed8:
7035 case Match_InvalidMemoryIndexed16:
7036 case Match_InvalidCondCode:
7037 case Match_AddSubLSLImm3ShiftLarge:
7038 case Match_AddSubRegExtendSmall:
7039 case Match_AddSubRegExtendLarge:
7040 case Match_AddSubSecondSource:
7041 case Match_LogicalSecondSource:
7042 case Match_AddSubRegShift32:
7043 case Match_AddSubRegShift64:
7044 case Match_InvalidMovImm32Shift:
7045 case Match_InvalidMovImm64Shift:
7046 case Match_InvalidFPImm:
7047 case Match_InvalidMemoryWExtend8:
7048 case Match_InvalidMemoryWExtend16:
7049 case Match_InvalidMemoryWExtend32:
7050 case Match_InvalidMemoryWExtend64:
7051 case Match_InvalidMemoryWExtend128:
7052 case Match_InvalidMemoryXExtend8:
7053 case Match_InvalidMemoryXExtend16:
7054 case Match_InvalidMemoryXExtend32:
7055 case Match_InvalidMemoryXExtend64:
7056 case Match_InvalidMemoryXExtend128:
7057 case Match_InvalidMemoryIndexed1SImm4:
7058 case Match_InvalidMemoryIndexed2SImm4:
7059 case Match_InvalidMemoryIndexed3SImm4:
7060 case Match_InvalidMemoryIndexed4SImm4:
7061 case Match_InvalidMemoryIndexed1SImm6:
7062 case Match_InvalidMemoryIndexed16SImm4:
7063 case Match_InvalidMemoryIndexed32SImm4:
7064 case Match_InvalidMemoryIndexed4SImm7:
7065 case Match_InvalidMemoryIndexed8SImm7:
7066 case Match_InvalidMemoryIndexed16SImm7:
7067 case Match_InvalidMemoryIndexed8UImm5:
7068 case Match_InvalidMemoryIndexed8UImm3:
7069 case Match_InvalidMemoryIndexed4UImm5:
7070 case Match_InvalidMemoryIndexed2UImm5:
7071 case Match_InvalidMemoryIndexed1UImm6:
7072 case Match_InvalidMemoryIndexed2UImm6:
7073 case Match_InvalidMemoryIndexed4UImm6:
7074 case Match_InvalidMemoryIndexed8UImm6:
7075 case Match_InvalidMemoryIndexed16UImm6:
7076 case Match_InvalidMemoryIndexedSImm6:
7077 case Match_InvalidMemoryIndexedSImm5:
7078 case Match_InvalidMemoryIndexedSImm8:
7079 case Match_InvalidMemoryIndexedSImm9:
7080 case Match_InvalidMemoryIndexed16SImm9:
7081 case Match_InvalidMemoryIndexed8SImm10:
7082 case Match_InvalidImm0_0:
7083 case Match_InvalidImm0_1:
7084 case Match_InvalidImm0_3:
7085 case Match_InvalidImm0_7:
7086 case Match_InvalidImm0_15:
7087 case Match_InvalidImm0_31:
7088 case Match_InvalidImm0_63:
7089 case Match_InvalidImm0_127:
7090 case Match_InvalidImm0_255:
7091 case Match_InvalidImm0_65535:
7092 case Match_InvalidImm1_8:
7093 case Match_InvalidImm1_16:
7094 case Match_InvalidImm1_32:
7095 case Match_InvalidImm1_64:
7096 case Match_InvalidImmM1_62:
7097 case Match_InvalidMemoryIndexedRange2UImm0:
7098 case Match_InvalidMemoryIndexedRange2UImm1:
7099 case Match_InvalidMemoryIndexedRange2UImm2:
7100 case Match_InvalidMemoryIndexedRange2UImm3:
7101 case Match_InvalidMemoryIndexedRange4UImm0:
7102 case Match_InvalidMemoryIndexedRange4UImm1:
7103 case Match_InvalidMemoryIndexedRange4UImm2:
7104 case Match_InvalidSVEAddSubImm8:
7105 case Match_InvalidSVEAddSubImm16:
7106 case Match_InvalidSVEAddSubImm32:
7107 case Match_InvalidSVEAddSubImm64:
7108 case Match_InvalidSVECpyImm8:
7109 case Match_InvalidSVECpyImm16:
7110 case Match_InvalidSVECpyImm32:
7111 case Match_InvalidSVECpyImm64:
7112 case Match_InvalidIndexRange0_0:
7113 case Match_InvalidIndexRange1_1:
7114 case Match_InvalidIndexRange0_15:
7115 case Match_InvalidIndexRange0_7:
7116 case Match_InvalidIndexRange0_3:
7117 case Match_InvalidIndexRange0_1:
7118 case Match_InvalidSVEIndexRange0_63:
7119 case Match_InvalidSVEIndexRange0_31:
7120 case Match_InvalidSVEIndexRange0_15:
7121 case Match_InvalidSVEIndexRange0_7:
7122 case Match_InvalidSVEIndexRange0_3:
7123 case Match_InvalidLabel:
7124 case Match_InvalidComplexRotationEven:
7125 case Match_InvalidComplexRotationOdd:
7126 case Match_InvalidGPR64shifted8:
7127 case Match_InvalidGPR64shifted16:
7128 case Match_InvalidGPR64shifted32:
7129 case Match_InvalidGPR64shifted64:
7130 case Match_InvalidGPR64shifted128:
7131 case Match_InvalidGPR64NoXZRshifted8:
7132 case Match_InvalidGPR64NoXZRshifted16:
7133 case Match_InvalidGPR64NoXZRshifted32:
7134 case Match_InvalidGPR64NoXZRshifted64:
7135 case Match_InvalidGPR64NoXZRshifted128:
7136 case Match_InvalidZPR32UXTW8:
7137 case Match_InvalidZPR32UXTW16:
7138 case Match_InvalidZPR32UXTW32:
7139 case Match_InvalidZPR32UXTW64:
7140 case Match_InvalidZPR32SXTW8:
7141 case Match_InvalidZPR32SXTW16:
7142 case Match_InvalidZPR32SXTW32:
7143 case Match_InvalidZPR32SXTW64:
7144 case Match_InvalidZPR64UXTW8:
7145 case Match_InvalidZPR64SXTW8:
7146 case Match_InvalidZPR64UXTW16:
7147 case Match_InvalidZPR64SXTW16:
7148 case Match_InvalidZPR64UXTW32:
7149 case Match_InvalidZPR64SXTW32:
7150 case Match_InvalidZPR64UXTW64:
7151 case Match_InvalidZPR64SXTW64:
7152 case Match_InvalidZPR32LSL8:
7153 case Match_InvalidZPR32LSL16:
7154 case Match_InvalidZPR32LSL32:
7155 case Match_InvalidZPR32LSL64:
7156 case Match_InvalidZPR64LSL8:
7157 case Match_InvalidZPR64LSL16:
7158 case Match_InvalidZPR64LSL32:
7159 case Match_InvalidZPR64LSL64:
7160 case Match_InvalidZPR0:
7161 case Match_InvalidZPR8:
7162 case Match_InvalidZPR16:
7163 case Match_InvalidZPR32:
7164 case Match_InvalidZPR64:
7165 case Match_InvalidZPR128:
7166 case Match_InvalidZPR_3b8:
7167 case Match_InvalidZPR_3b16:
7168 case Match_InvalidZPR_3b32:
7169 case Match_InvalidZPR_4b8:
7170 case Match_InvalidZPR_4b16:
7171 case Match_InvalidZPR_4b32:
7172 case Match_InvalidZPR_4b64:
7173 case Match_InvalidSVEPPRorPNRAnyReg:
7174 case Match_InvalidSVEPPRorPNRBReg:
7175 case Match_InvalidSVEPredicateAnyReg:
7176 case Match_InvalidSVEPattern:
7177 case Match_InvalidSVEVecLenSpecifier:
7178 case Match_InvalidSVEPredicateBReg:
7179 case Match_InvalidSVEPredicateHReg:
7180 case Match_InvalidSVEPredicateSReg:
7181 case Match_InvalidSVEPredicateDReg:
7182 case Match_InvalidSVEPredicate3bAnyReg:
7183 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7184 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7185 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7186 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7187 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7188 case Match_InvalidSVEPNPredicateBReg:
7189 case Match_InvalidSVEPNPredicateHReg:
7190 case Match_InvalidSVEPNPredicateSReg:
7191 case Match_InvalidSVEPNPredicateDReg:
7192 case Match_InvalidSVEPredicateListMul2x8:
7193 case Match_InvalidSVEPredicateListMul2x16:
7194 case Match_InvalidSVEPredicateListMul2x32:
7195 case Match_InvalidSVEPredicateListMul2x64:
7196 case Match_InvalidSVEExactFPImmOperandHalfOne:
7197 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7198 case Match_InvalidSVEExactFPImmOperandZeroOne:
7199 case Match_InvalidMatrixTile16:
7200 case Match_InvalidMatrixTile32:
7201 case Match_InvalidMatrixTile64:
7202 case Match_InvalidMatrix:
7203 case Match_InvalidMatrix8:
7204 case Match_InvalidMatrix16:
7205 case Match_InvalidMatrix32:
7206 case Match_InvalidMatrix64:
7207 case Match_InvalidMatrixTileVectorH8:
7208 case Match_InvalidMatrixTileVectorH16:
7209 case Match_InvalidMatrixTileVectorH32:
7210 case Match_InvalidMatrixTileVectorH64:
7211 case Match_InvalidMatrixTileVectorH128:
7212 case Match_InvalidMatrixTileVectorV8:
7213 case Match_InvalidMatrixTileVectorV16:
7214 case Match_InvalidMatrixTileVectorV32:
7215 case Match_InvalidMatrixTileVectorV64:
7216 case Match_InvalidMatrixTileVectorV128:
7217 case Match_InvalidSVCR:
7218 case Match_InvalidMatrixIndexGPR32_12_15:
7219 case Match_InvalidMatrixIndexGPR32_8_11:
7220 case Match_InvalidLookupTable:
7221 case Match_InvalidZPRMul2_Lo8:
7222 case Match_InvalidZPRMul2_Hi8:
7223 case Match_InvalidZPRMul2_Lo16:
7224 case Match_InvalidZPRMul2_Hi16:
7225 case Match_InvalidZPRMul2_Lo32:
7226 case Match_InvalidZPRMul2_Hi32:
7227 case Match_InvalidZPRMul2_Lo64:
7228 case Match_InvalidZPRMul2_Hi64:
7229 case Match_InvalidZPR_K0:
7230 case Match_InvalidSVEVectorList2x8Mul2:
7231 case Match_InvalidSVEVectorList2x16Mul2:
7232 case Match_InvalidSVEVectorList2x32Mul2:
7233 case Match_InvalidSVEVectorList2x64Mul2:
7234 case Match_InvalidSVEVectorList2x128Mul2:
7235 case Match_InvalidSVEVectorList4x8Mul4:
7236 case Match_InvalidSVEVectorList4x16Mul4:
7237 case Match_InvalidSVEVectorList4x32Mul4:
7238 case Match_InvalidSVEVectorList4x64Mul4:
7239 case Match_InvalidSVEVectorList4x128Mul4:
7240 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7241 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7242 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7243 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7244 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7245 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7246 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7247 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7248 case Match_InvalidSVEVectorListStrided2x8:
7249 case Match_InvalidSVEVectorListStrided2x16:
7250 case Match_InvalidSVEVectorListStrided2x32:
7251 case Match_InvalidSVEVectorListStrided2x64:
7252 case Match_InvalidSVEVectorListStrided4x8:
7253 case Match_InvalidSVEVectorListStrided4x16:
7254 case Match_InvalidSVEVectorListStrided4x32:
7255 case Match_InvalidSVEVectorListStrided4x64:
7258 if (ErrorInfo >= Operands.
size())
7259 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7262 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7263 if (ErrorLoc == SMLoc())
7265 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7273bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7280 SMLoc Loc = DirectiveID.
getLoc();
7281 if (IDVal ==
".arch")
7282 parseDirectiveArch(Loc);
7283 else if (IDVal ==
".cpu")
7284 parseDirectiveCPU(Loc);
7285 else if (IDVal ==
".tlsdesccall")
7286 parseDirectiveTLSDescCall(Loc);
7287 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7288 parseDirectiveLtorg(Loc);
7289 else if (IDVal ==
".unreq")
7290 parseDirectiveUnreq(Loc);
7291 else if (IDVal ==
".inst")
7292 parseDirectiveInst(Loc);
7293 else if (IDVal ==
".cfi_negate_ra_state")
7294 parseDirectiveCFINegateRAState();
7295 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7296 parseDirectiveCFINegateRAStateWithPC();
7297 else if (IDVal ==
".cfi_b_key_frame")
7298 parseDirectiveCFIBKeyFrame();
7299 else if (IDVal ==
".cfi_mte_tagged_frame")
7300 parseDirectiveCFIMTETaggedFrame();
7301 else if (IDVal ==
".arch_extension")
7302 parseDirectiveArchExtension(Loc);
7303 else if (IDVal ==
".variant_pcs")
7304 parseDirectiveVariantPCS(Loc);
7307 parseDirectiveLOH(IDVal, Loc);
7310 }
else if (IsCOFF) {
7311 if (IDVal ==
".seh_stackalloc")
7312 parseDirectiveSEHAllocStack(Loc);
7313 else if (IDVal ==
".seh_endprologue")
7314 parseDirectiveSEHPrologEnd(Loc);
7315 else if (IDVal ==
".seh_save_r19r20_x")
7316 parseDirectiveSEHSaveR19R20X(Loc);
7317 else if (IDVal ==
".seh_save_fplr")
7318 parseDirectiveSEHSaveFPLR(Loc);
7319 else if (IDVal ==
".seh_save_fplr_x")
7320 parseDirectiveSEHSaveFPLRX(Loc);
7321 else if (IDVal ==
".seh_save_reg")
7322 parseDirectiveSEHSaveReg(Loc);
7323 else if (IDVal ==
".seh_save_reg_x")
7324 parseDirectiveSEHSaveRegX(Loc);
7325 else if (IDVal ==
".seh_save_regp")
7326 parseDirectiveSEHSaveRegP(Loc);
7327 else if (IDVal ==
".seh_save_regp_x")
7328 parseDirectiveSEHSaveRegPX(Loc);
7329 else if (IDVal ==
".seh_save_lrpair")
7330 parseDirectiveSEHSaveLRPair(Loc);
7331 else if (IDVal ==
".seh_save_freg")
7332 parseDirectiveSEHSaveFReg(Loc);
7333 else if (IDVal ==
".seh_save_freg_x")
7334 parseDirectiveSEHSaveFRegX(Loc);
7335 else if (IDVal ==
".seh_save_fregp")
7336 parseDirectiveSEHSaveFRegP(Loc);
7337 else if (IDVal ==
".seh_save_fregp_x")
7338 parseDirectiveSEHSaveFRegPX(Loc);
7339 else if (IDVal ==
".seh_set_fp")
7340 parseDirectiveSEHSetFP(Loc);
7341 else if (IDVal ==
".seh_add_fp")
7342 parseDirectiveSEHAddFP(Loc);
7343 else if (IDVal ==
".seh_nop")
7344 parseDirectiveSEHNop(Loc);
7345 else if (IDVal ==
".seh_save_next")
7346 parseDirectiveSEHSaveNext(Loc);
7347 else if (IDVal ==
".seh_startepilogue")
7348 parseDirectiveSEHEpilogStart(Loc);
7349 else if (IDVal ==
".seh_endepilogue")
7350 parseDirectiveSEHEpilogEnd(Loc);
7351 else if (IDVal ==
".seh_trap_frame")
7352 parseDirectiveSEHTrapFrame(Loc);
7353 else if (IDVal ==
".seh_pushframe")
7354 parseDirectiveSEHMachineFrame(Loc);
7355 else if (IDVal ==
".seh_context")
7356 parseDirectiveSEHContext(Loc);
7357 else if (IDVal ==
".seh_ec_context")
7358 parseDirectiveSEHECContext(Loc);
7359 else if (IDVal ==
".seh_clear_unwound_to_call")
7360 parseDirectiveSEHClearUnwoundToCall(Loc);
7361 else if (IDVal ==
".seh_pac_sign_lr")
7362 parseDirectiveSEHPACSignLR(Loc);
7363 else if (IDVal ==
".seh_save_any_reg")
7364 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7365 else if (IDVal ==
".seh_save_any_reg_p")
7366 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7367 else if (IDVal ==
".seh_save_any_reg_x")
7368 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7369 else if (IDVal ==
".seh_save_any_reg_px")
7370 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7371 else if (IDVal ==
".seh_allocz")
7372 parseDirectiveSEHAllocZ(Loc);
7373 else if (IDVal ==
".seh_save_zreg")
7374 parseDirectiveSEHSaveZReg(Loc);
7375 else if (IDVal ==
".seh_save_preg")
7376 parseDirectiveSEHSavePReg(Loc);
7380 if (IDVal ==
".aeabi_subsection")
7381 parseDirectiveAeabiSubSectionHeader(Loc);
7382 else if (IDVal ==
".aeabi_attribute")
7383 parseDirectiveAeabiAArch64Attr(Loc);
7396 if (!NoCrypto && Crypto) {
7399 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7400 ArchInfo == AArch64::ARMV8_3A) {
7404 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7405 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7406 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7407 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7408 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7409 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7415 }
else if (NoCrypto) {
7418 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7419 ArchInfo == AArch64::ARMV8_3A) {
7420 RequestedExtensions.
push_back(
"nosha2");
7423 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7424 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7425 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7426 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7427 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7428 ArchInfo == AArch64::ARMV9_4A) {
7430 RequestedExtensions.
push_back(
"nosha3");
7431 RequestedExtensions.
push_back(
"nosha2");
7443bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7444 SMLoc CurLoc = getLoc();
7446 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7447 StringRef Arch, ExtensionString;
7448 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7452 return Error(CurLoc,
"unknown arch name");
7458 std::vector<StringRef> AArch64Features;
7459 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7462 MCSubtargetInfo &STI = copySTI();
7463 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7465 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7468 if (!ExtensionString.
empty())
7469 ExtensionString.
split(RequestedExtensions,
'+');
7474 for (
auto Name : RequestedExtensions) {
7478 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7485 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7493 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7494 setAvailableFeatures(Features);
7496 getTargetStreamer().emitDirectiveArch(Name);
7502bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7503 SMLoc ExtLoc = getLoc();
7505 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7510 bool EnableFeature =
true;
7511 StringRef
Name = FullName;
7512 if (
Name.starts_with_insensitive(
"no")) {
7513 EnableFeature =
false;
7522 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7524 MCSubtargetInfo &STI = copySTI();
7529 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7530 setAvailableFeatures(Features);
7532 getTargetStreamer().emitDirectiveArchExtension(FullName);
7538bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7539 SMLoc CurLoc = getLoc();
7541 StringRef CPU, ExtensionString;
7542 std::tie(CPU, ExtensionString) =
7543 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7549 if (!ExtensionString.
empty())
7550 ExtensionString.
split(RequestedExtensions,
'+');
7554 Error(CurLoc,
"unknown CPU name");
7559 MCSubtargetInfo &STI = copySTI();
7563 for (
auto Name : RequestedExtensions) {
7567 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7574 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7582 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7583 setAvailableFeatures(Features);
7589bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7591 return Error(Loc,
"expected expression following '.inst' directive");
7593 auto parseOp = [&]() ->
bool {
7595 const MCExpr *Expr =
nullptr;
7596 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7599 if (check(!
Value, L,
"expected constant expression"))
7601 getTargetStreamer().emitInst(
Value->getValue());
7605 return parseMany(parseOp);
7610bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7612 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7624 getParser().getStreamer().emitInstruction(Inst, getSTI());
7630bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7634 return TokError(
"expected an identifier or a number in directive");
7637 int64_t
Id = getTok().getIntVal();
7639 return TokError(
"invalid numeric identifier in directive");
7642 StringRef
Name = getTok().getIdentifier();
7648 return TokError(
"invalid identifier in directive");
7656 assert(NbArgs != -1 &&
"Invalid number of arguments");
7659 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7661 if (getParser().parseIdentifier(Name))
7662 return TokError(
"expected identifier in directive");
7665 if (Idx + 1 == NbArgs)
7673 getStreamer().emitLOHDirective(Kind, Args);
7679bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7682 getTargetStreamer().emitCurrentConstantPool();
7688bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7690 SMLoc SRegLoc = getLoc();
7691 RegKind RegisterKind = RegKind::Scalar;
7693 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7697 RegisterKind = RegKind::NeonVector;
7698 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7704 return Error(SRegLoc,
"vector register without type specifier expected");
7709 RegisterKind = RegKind::SVEDataVector;
7711 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7717 return Error(SRegLoc,
7718 "sve vector register without type specifier expected");
7723 RegisterKind = RegKind::SVEPredicateVector;
7724 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7730 return Error(SRegLoc,
7731 "sve predicate register without type specifier expected");
7735 return Error(SRegLoc,
"register name or alias expected");
7741 auto pair = std::make_pair(RegisterKind, RegNum);
7742 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7743 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7750bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7752 return TokError(
"unexpected input in .unreq directive.");
7753 RegisterReqs.
erase(getTok().getIdentifier().lower());
7758bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7761 getStreamer().emitCFINegateRAState();
7765bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7768 getStreamer().emitCFINegateRAStateWithPC();
7774bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7777 getStreamer().emitCFIBKeyFrame();
7783bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7786 getStreamer().emitCFIMTETaggedFrame();
7792bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7794 if (getParser().parseIdentifier(Name))
7795 return TokError(
"expected symbol name");
7798 getTargetStreamer().emitDirectiveVariantPCS(
7805bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7807 if (parseImmExpr(
Size))
7809 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7815bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7816 getTargetStreamer().emitARM64WinCFIPrologEnd();
7822bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7824 if (parseImmExpr(
Offset))
7826 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7832bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7834 if (parseImmExpr(
Offset))
7836 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7842bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7844 if (parseImmExpr(
Offset))
7846 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7852bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7855 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7856 parseComma() || parseImmExpr(
Offset))
7858 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7864bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7867 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7868 parseComma() || parseImmExpr(
Offset))
7870 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7876bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7879 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7880 parseComma() || parseImmExpr(
Offset))
7882 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7888bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7891 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7892 parseComma() || parseImmExpr(
Offset))
7894 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7900bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7904 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7905 parseComma() || parseImmExpr(
Offset))
7907 if (check(((
Reg - 19) % 2 != 0), L,
7908 "expected register with even offset from x19"))
7910 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7916bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7919 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7920 parseComma() || parseImmExpr(
Offset))
7922 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7928bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7931 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7932 parseComma() || parseImmExpr(
Offset))
7934 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7940bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7943 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7944 parseComma() || parseImmExpr(
Offset))
7946 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7952bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7955 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7956 parseComma() || parseImmExpr(
Offset))
7958 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7964bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7965 getTargetStreamer().emitARM64WinCFISetFP();
7971bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7973 if (parseImmExpr(
Size))
7975 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7981bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7982 getTargetStreamer().emitARM64WinCFINop();
7988bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7989 getTargetStreamer().emitARM64WinCFISaveNext();
7995bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7996 getTargetStreamer().emitARM64WinCFIEpilogStart();
8002bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
8003 getTargetStreamer().emitARM64WinCFIEpilogEnd();
8009bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
8010 getTargetStreamer().emitARM64WinCFITrapFrame();
8016bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
8017 getTargetStreamer().emitARM64WinCFIMachineFrame();
8023bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
8024 getTargetStreamer().emitARM64WinCFIContext();
8030bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
8031 getTargetStreamer().emitARM64WinCFIECContext();
8037bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
8038 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
8044bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
8045 getTargetStreamer().emitARM64WinCFIPACSignLR();
8054bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
8059 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
8060 parseComma() || parseImmExpr(
Offset))
8063 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
8064 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
8065 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8066 return Error(L,
"invalid save_any_reg offset");
8067 unsigned EncodedReg;
8068 if (
Reg == AArch64::FP)
8070 else if (
Reg == AArch64::LR)
8073 EncodedReg =
Reg - AArch64::X0;
8075 if (
Reg == AArch64::LR)
8076 return Error(Start,
"lr cannot be paired with another register");
8078 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
8080 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
8083 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
8085 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
8087 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
8088 unsigned EncodedReg =
Reg - AArch64::D0;
8089 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8090 return Error(L,
"invalid save_any_reg offset");
8092 if (
Reg == AArch64::D31)
8093 return Error(Start,
"d31 cannot be paired with another register");
8095 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
8097 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
8100 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
8102 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
8104 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
8105 unsigned EncodedReg =
Reg - AArch64::Q0;
8107 return Error(L,
"invalid save_any_reg offset");
8109 if (
Reg == AArch64::Q31)
8110 return Error(Start,
"q31 cannot be paired with another register");
8112 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
8114 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
8117 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
8119 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
8122 return Error(Start,
"save_any_reg register must be x, q or d register");
8129bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8131 if (parseImmExpr(
Offset))
8133 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8139bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8144 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8147 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8148 "expected register in range z8 to z23"))
8150 if (parseComma() || parseImmExpr(
Offset))
8152 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8158bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8163 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8166 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8167 "expected register in range p4 to p15"))
8169 if (parseComma() || parseImmExpr(
Offset))
8171 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8175bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8181 MCAsmParser &Parser = getParser();
8184 StringRef SubsectionName;
8195 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8196 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8201 if (SubsectionExists) {
8202 getTargetStreamer().emitAttributesSubsection(
8205 SubsectionExists->IsOptional),
8207 SubsectionExists->ParameterType));
8213 "Could not switch to subsection '" + SubsectionName +
8214 "' using subsection name, subsection has not been defined");
8237 if (SubsectionExists) {
8238 if (IsOptional != SubsectionExists->IsOptional) {
8240 "optionality mismatch! subsection '" + SubsectionName +
8241 "' already exists with optionality defined as '" +
8243 SubsectionExists->IsOptional) +
8251 "optionality parameter not found, expected required|optional");
8258 "aeabi_feature_and_bits must be marked as optional");
8265 "aeabi_pauthabi must be marked as required");
8285 if (SubsectionExists) {
8286 if (
Type != SubsectionExists->ParameterType) {
8288 "type mismatch! subsection '" + SubsectionName +
8289 "' already exists with type defined as '" +
8291 SubsectionExists->ParameterType) +
8299 "type parameter not found, expected uleb128|ntbs");
8307 SubsectionName +
" must be marked as ULEB128");
8316 "attributes subsection header directive");
8320 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8325bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8329 MCAsmParser &Parser = getParser();
8331 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8332 getTargetStreamer().getActiveAttributesSubsection();
8333 if (
nullptr == ActiveSubsection) {
8335 "no active subsection, build attribute can not be added");
8338 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8339 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8347 ActiveSubsectionName)
8350 StringRef TagStr =
"";
8353 Tag = getTok().getIntVal();
8356 switch (ActiveSubsectionID) {
8361 "' \nExcept for public subsections, "
8362 "tags have to be an unsigned int.");
8369 TagStr +
"' for subsection '" +
8370 ActiveSubsectionName +
"'");
8378 TagStr +
"' for subsection '" +
8379 ActiveSubsectionName +
"'");
8397 unsigned ValueInt = unsigned(-1);
8398 std::string ValueStr =
"";
8403 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8406 ValueInt = getTok().getIntVal();
8411 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8419 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8430 if (0 != ValueInt && 1 != ValueInt) {
8432 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8433 "' options are 0|1");
8442 "unexpected token for AArch64 build attributes tag and value "
8443 "attribute directive");
8447 if (
unsigned(-1) != ValueInt) {
8448 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8450 if (
"" != ValueStr) {
8451 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8457bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8458 SMLoc Loc = getLoc();
8460 return TokError(
"expected '%' relocation specifier");
8461 StringRef
Identifier = getParser().getTok().getIdentifier();
8464 return TokError(
"invalid relocation specifier");
8470 const MCExpr *SubExpr;
8471 if (getParser().parseParenExpression(SubExpr,
E))
8478bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8481 return parseExprWithSpecifier(Res, EndLoc);
8483 if (getParser().parseExpression(Res))
8485 MCAsmParser &Parser = getParser();
8489 return Error(getLoc(),
"expected relocation specifier");
8492 SMLoc Loc = getLoc();
8494 if (Identifier ==
"auth")
8495 return parseAuthExpr(Res, EndLoc);
8499 if (Identifier ==
"got")
8503 return Error(Loc,
"invalid relocation specifier");
8508 return Error(Loc,
"@ specifier only allowed after a symbol");
8511 std::optional<MCBinaryExpr::Opcode> Opcode;
8519 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8530bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8531 MCAsmParser &Parser = getParser();
8533 AsmToken Tok = Parser.
getTok();
8540 return TokError(
"expected key name");
8545 return TokError(
"invalid key '" + KeyStr +
"'");
8552 return TokError(
"expected integer discriminator");
8556 return TokError(
"integer discriminator " + Twine(Discriminator) +
8557 " out of range [0, 0xFFFF]");
8560 bool UseAddressDiversity =
false;
8565 return TokError(
"expected 'addr'");
8566 UseAddressDiversity =
true;
8575 UseAddressDiversity, Ctx, Res->
getLoc());
8579bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8588 ELFSpec = AE->getSpecifier();
8589 Expr = AE->getSubExpr();
8629#define GET_REGISTER_MATCHER
8630#define GET_SUBTARGET_FEATURE_NAME
8631#define GET_MATCHER_IMPLEMENTATION
8632#define GET_MNEMONIC_SPELL_CHECKER
8633#include "AArch64GenAsmMatcher.inc"
8639 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8641 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8643 return Match_InvalidOperand;
8646 return Match_InvalidOperand;
8647 if (CE->getValue() == ExpectedVal)
8648 return Match_Success;
8649 return Match_InvalidOperand;
8654 return Match_InvalidOperand;
8660 if (
Op.isTokenEqual(
"za"))
8661 return Match_Success;
8662 return Match_InvalidOperand;
8668#define MATCH_HASH(N) \
8669 case MCK__HASH_##N: \
8670 return MatchesOpImmediate(N);
8696#define MATCH_HASH_MINUS(N) \
8697 case MCK__HASH__MINUS_##N: \
8698 return MatchesOpImmediate(-N);
8702#undef MATCH_HASH_MINUS
8706ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8711 return Error(S,
"expected register");
8713 MCRegister FirstReg;
8714 ParseStatus Res = tryParseScalarRegister(FirstReg);
8716 return Error(S,
"expected first even register of a consecutive same-size "
8717 "even/odd register pair");
8719 const MCRegisterClass &WRegClass =
8720 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8721 const MCRegisterClass &XRegClass =
8722 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8724 bool isXReg = XRegClass.
contains(FirstReg),
8725 isWReg = WRegClass.
contains(FirstReg);
8726 if (!isXReg && !isWReg)
8727 return Error(S,
"expected first even register of a consecutive same-size "
8728 "even/odd register pair");
8730 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8733 if (FirstEncoding & 0x1)
8734 return Error(S,
"expected first even register of a consecutive same-size "
8735 "even/odd register pair");
8738 return Error(getLoc(),
"expected comma");
8743 MCRegister SecondReg;
8744 Res = tryParseScalarRegister(SecondReg);
8746 return Error(
E,
"expected second odd register of a consecutive same-size "
8747 "even/odd register pair");
8750 (isXReg && !XRegClass.
contains(SecondReg)) ||
8751 (isWReg && !WRegClass.
contains(SecondReg)))
8752 return Error(
E,
"expected second odd register of a consecutive same-size "
8753 "even/odd register pair");
8758 FirstReg, AArch64::sube64,
8759 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8762 FirstReg, AArch64::sube32,
8763 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8766 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8772template <
bool ParseShiftExtend,
bool ParseSuffix>
8773ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8774 const SMLoc S = getLoc();
8780 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8785 if (ParseSuffix &&
Kind.empty())
8792 unsigned ElementWidth = KindRes->second;
8796 Operands.
push_back(AArch64Operand::CreateVectorReg(
8797 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8799 ParseStatus Res = tryParseVectorIndex(Operands);
8810 Res = tryParseOptionalShiftExtend(ExtOpnd);
8814 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8815 Operands.
push_back(AArch64Operand::CreateVectorReg(
8816 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8817 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8818 Ext->hasShiftExtendAmount()));
8823ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8824 MCAsmParser &Parser = getParser();
8826 SMLoc
SS = getLoc();
8827 const AsmToken &TokE = getTok();
8838 const MCExpr *ImmVal;
8845 return TokError(
"invalid operand for instruction");
8850 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8855 Pattern = Pat->Encoding;
8856 assert(Pattern >= 0 && Pattern < 32);
8867AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8869 SMLoc
SS = getLoc();
8870 const AsmToken &TokE = getTok();
8872 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8878 Pattern = Pat->Encoding;
8879 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8888ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8889 SMLoc
SS = getLoc();
8892 if (!tryParseScalarRegister(XReg).isSuccess())
8898 XReg, AArch64::x8sub_0,
8899 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8902 "expected an even-numbered x-register in the range [x0,x22]");
8905 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8909ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8919 if (getParser().parseExpression(ImmF))
8929 SMLoc
E = getTok().getLoc();
8931 if (getParser().parseExpression(ImmL))
8938 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8943ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8953 if (getParser().parseExpression(Ex))
8963 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8970 Operands.
push_back(AArch64Operand::CreateImm(
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
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.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
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 void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
APInt bitcastToAPInt() const
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.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void UnLex(AsmToken const &Token)
LLVM_ABI SMLoc getLoc() const
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
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister getReg() const =0
MCRegister 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.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
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.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() 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
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
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.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
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.
static constexpr size_t npos
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
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.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
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.
LLVM_ABI std::string lower() const
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)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
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.
LLVM_ABI SubsectionType getTypeID(StringRef Type)
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
LLVM_ABI StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
LLVM_ABI StringRef getSubsectionTypeUnknownError()
LLVM_ABI SubsectionOptional getOptionalID(StringRef Optional)
LLVM_ABI StringRef getSubsectionOptionalUnknownError()
LLVM_ABI FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
LLVM_ABI VendorID getVendorID(StringRef const Vendor)
LLVM_ABI PauthABITags getPauthABITagsID(StringRef PauthABITag)
LLVM_ABI StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
const PHint * lookupPHintByName(StringRef)
uint32_t parseGenericRegister(StringRef Name)
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 bool isSVEAddSubImm(int64_t Imm)
Returns true if Imm is valid for ADD/SUB.
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 bool isSVECpyImm(int64_t Imm)
Returns true if Imm is valid for CPY/DUP.
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 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
Context & getContext() const
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)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
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()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
StringTable::Offset ArchFeature
AArch64::ExtensionBitset DefaultExts
Compile-time data representation of enum entries.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
bool haveFeatures(FeatureBitset ActiveFeatures) const