72 SVEPredicateAsCounter,
78enum class MatrixKind { Array, Tile, Row, Col };
80enum RegConstraintEqualityTy {
91 StringMap<std::pair<RegKind, unsigned>> RegisterReqs;
95 static PrefixInfo CreateFromInst(
const MCInst &Inst, uint64_t TSFlags) {
98 case AArch64::MOVPRFX_ZZ:
102 case AArch64::MOVPRFX_ZPmZ_B:
103 case AArch64::MOVPRFX_ZPmZ_H:
104 case AArch64::MOVPRFX_ZPmZ_S:
105 case AArch64::MOVPRFX_ZPmZ_D:
110 "No destructive element size set for movprfx");
114 case AArch64::MOVPRFX_ZPzZ_B:
115 case AArch64::MOVPRFX_ZPzZ_H:
116 case AArch64::MOVPRFX_ZPzZ_S:
117 case AArch64::MOVPRFX_ZPzZ_D:
122 "No destructive element size set for movprfx");
133 PrefixInfo() =
default;
134 bool isActive()
const {
return Active; }
136 unsigned getElementSize()
const {
140 MCRegister getDstReg()
const {
return Dst; }
141 MCRegister getPgReg()
const {
148 bool Predicated =
false;
149 unsigned ElementSize;
154 AArch64TargetStreamer &getTargetStreamer() {
155 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
156 return static_cast<AArch64TargetStreamer &
>(TS);
159 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
161 bool parseSysAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
162 bool parseSyslAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
163 bool parseSyspAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
164 void createSysAlias(uint16_t Encoding,
OperandVector &Operands, SMLoc S);
166 std::string &Suggestion);
167 bool parseCondCode(
OperandVector &Operands,
bool invertCondCode);
168 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
170 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
173 bool parseOptionalVGOperand(
OperandVector &Operands, StringRef &VecGroup);
176 bool invertCondCode);
177 bool parseImmExpr(int64_t &Out);
179 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
182 bool showMatchError(SMLoc Loc,
unsigned ErrCode, uint64_t ErrorInfo,
185 bool parseDataExpr(
const MCExpr *&Res)
override;
186 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
188 bool parseDirectiveArch(SMLoc L);
189 bool parseDirectiveArchExtension(SMLoc L);
190 bool parseDirectiveCPU(SMLoc L);
191 bool parseDirectiveInst(SMLoc L);
193 bool parseDirectiveTLSDescCall(SMLoc L);
195 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
196 bool parseDirectiveLtorg(SMLoc L);
198 bool parseDirectiveReq(StringRef Name, SMLoc L);
199 bool parseDirectiveUnreq(SMLoc L);
200 bool parseDirectiveCFINegateRAState();
201 bool parseDirectiveCFINegateRAStateWithPC();
202 bool parseDirectiveCFIBKeyFrame();
203 bool parseDirectiveCFIMTETaggedFrame();
205 bool parseDirectiveVariantPCS(SMLoc L);
207 bool parseDirectiveSEHAllocStack(SMLoc L);
208 bool parseDirectiveSEHPrologEnd(SMLoc L);
209 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
210 bool parseDirectiveSEHSaveFPLR(SMLoc L);
211 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
212 bool parseDirectiveSEHSaveReg(SMLoc L);
213 bool parseDirectiveSEHSaveRegX(SMLoc L);
214 bool parseDirectiveSEHSaveRegP(SMLoc L);
215 bool parseDirectiveSEHSaveRegPX(SMLoc L);
216 bool parseDirectiveSEHSaveLRPair(SMLoc L);
217 bool parseDirectiveSEHSaveFReg(SMLoc L);
218 bool parseDirectiveSEHSaveFRegX(SMLoc L);
219 bool parseDirectiveSEHSaveFRegP(SMLoc L);
220 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
221 bool parseDirectiveSEHSetFP(SMLoc L);
222 bool parseDirectiveSEHAddFP(SMLoc L);
223 bool parseDirectiveSEHNop(SMLoc L);
224 bool parseDirectiveSEHSaveNext(SMLoc L);
225 bool parseDirectiveSEHEpilogStart(SMLoc L);
226 bool parseDirectiveSEHEpilogEnd(SMLoc L);
227 bool parseDirectiveSEHTrapFrame(SMLoc L);
228 bool parseDirectiveSEHMachineFrame(SMLoc L);
229 bool parseDirectiveSEHContext(SMLoc L);
230 bool parseDirectiveSEHECContext(SMLoc L);
231 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
232 bool parseDirectiveSEHPACSignLR(SMLoc L);
233 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
234 bool parseDirectiveSEHAllocZ(SMLoc L);
235 bool parseDirectiveSEHSaveZReg(SMLoc L);
236 bool parseDirectiveSEHSavePReg(SMLoc L);
237 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
238 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
240 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
241 SmallVectorImpl<SMLoc> &Loc);
242 unsigned getNumRegsForRegKind(RegKind K);
243 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
246 bool MatchingInlineAsm)
override;
250#define GET_ASSEMBLER_HEADER
251#include "AArch64GenAsmMatcher.inc"
265 template <
bool IsSVEPrefetch = false>
273 template <
bool AddFPZeroAsLiteral>
281 template <
bool ParseShiftExtend,
282 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
285 template <
bool ParseShiftExtend,
bool ParseSuffix>
287 template <RegKind RK>
290 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
291 template <RegKind VectorKind>
293 bool ExpectMatch =
false);
303 enum AArch64MatchResultTy {
304 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
305#define GET_OPERAND_DIAGNOSTIC_TYPES
306#include "AArch64GenAsmMatcher.inc"
309 bool IsWindowsArm64EC;
311 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
312 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
313 : MCTargetAsmParser(
Options, STI, MII) {
317 MCStreamer &S = getParser().getStreamer();
319 new AArch64TargetStreamer(S);
331 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
334 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
335 const MCParsedAsmOperand &Op2)
const override;
336 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
338 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
339 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
340 SMLoc &EndLoc)
override;
341 bool ParseDirective(AsmToken DirectiveID)
override;
342 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
343 unsigned Kind)
override;
378 SMLoc StartLoc, EndLoc;
387 struct ShiftExtendOp {
390 bool HasExplicitAmount;
400 RegConstraintEqualityTy EqualityTy;
416 ShiftExtendOp ShiftExtend;
421 unsigned ElementWidth;
425 struct MatrixTileListOp {
426 unsigned RegMask = 0;
429 struct VectorListOp {
433 unsigned NumElements;
434 unsigned ElementWidth;
435 RegKind RegisterKind;
438 struct VectorIndexOp {
446 struct ShiftedImmOp {
448 unsigned ShiftAmount;
477 uint32_t PStateField;
505 struct CMHPriorityHintOp {
514 unsigned PStateField;
520 struct MatrixRegOp MatrixReg;
521 struct MatrixTileListOp MatrixTileList;
522 struct VectorListOp VectorList;
523 struct VectorIndexOp VectorIndex;
525 struct ShiftedImmOp ShiftedImm;
526 struct ImmRangeOp ImmRange;
528 struct FPImmOp FPImm;
530 struct SysRegOp SysReg;
531 struct SysCRImmOp SysCRImm;
533 struct PSBHintOp PSBHint;
534 struct PHintOp PHint;
535 struct BTIHintOp BTIHint;
536 struct CMHPriorityHintOp CMHPriorityHint;
537 struct ShiftExtendOp ShiftExtend;
546 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
548 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
550 StartLoc =
o.StartLoc;
560 ShiftedImm =
o.ShiftedImm;
563 ImmRange =
o.ImmRange;
577 case k_MatrixRegister:
578 MatrixReg =
o.MatrixReg;
580 case k_MatrixTileList:
581 MatrixTileList =
o.MatrixTileList;
584 VectorList =
o.VectorList;
587 VectorIndex =
o.VectorIndex;
593 SysCRImm =
o.SysCRImm;
607 case k_CMHPriorityHint:
608 CMHPriorityHint =
o.CMHPriorityHint;
611 ShiftExtend =
o.ShiftExtend;
620 SMLoc getStartLoc()
const override {
return StartLoc; }
622 SMLoc getEndLoc()
const override {
return EndLoc; }
625 assert(Kind == k_Token &&
"Invalid access!");
626 return StringRef(Tok.Data, Tok.Length);
629 bool isTokenSuffix()
const {
630 assert(Kind == k_Token &&
"Invalid access!");
634 const MCExpr *
getImm()
const {
635 assert(Kind == k_Immediate &&
"Invalid access!");
639 const MCExpr *getShiftedImmVal()
const {
640 assert(Kind == k_ShiftedImm &&
"Invalid access!");
641 return ShiftedImm.Val;
644 unsigned getShiftedImmShift()
const {
645 assert(Kind == k_ShiftedImm &&
"Invalid access!");
646 return ShiftedImm.ShiftAmount;
649 unsigned getFirstImmVal()
const {
650 assert(Kind == k_ImmRange &&
"Invalid access!");
651 return ImmRange.First;
654 unsigned getLastImmVal()
const {
655 assert(Kind == k_ImmRange &&
"Invalid access!");
656 return ImmRange.Last;
660 assert(Kind == k_CondCode &&
"Invalid access!");
665 assert (Kind == k_FPImm &&
"Invalid access!");
666 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
669 bool getFPImmIsExact()
const {
670 assert (Kind == k_FPImm &&
"Invalid access!");
671 return FPImm.IsExact;
674 unsigned getBarrier()
const {
675 assert(Kind == k_Barrier &&
"Invalid access!");
679 StringRef getBarrierName()
const {
680 assert(Kind == k_Barrier &&
"Invalid access!");
684 bool getBarriernXSModifier()
const {
685 assert(Kind == k_Barrier &&
"Invalid access!");
689 MCRegister
getReg()
const override {
690 assert(Kind == k_Register &&
"Invalid access!");
694 unsigned getMatrixReg()
const {
695 assert(Kind == k_MatrixRegister &&
"Invalid access!");
696 return MatrixReg.RegNum;
699 unsigned getMatrixElementWidth()
const {
700 assert(Kind == k_MatrixRegister &&
"Invalid access!");
701 return MatrixReg.ElementWidth;
704 MatrixKind getMatrixKind()
const {
705 assert(Kind == k_MatrixRegister &&
"Invalid access!");
706 return MatrixReg.Kind;
709 unsigned getMatrixTileListRegMask()
const {
710 assert(isMatrixTileList() &&
"Invalid access!");
711 return MatrixTileList.RegMask;
714 RegConstraintEqualityTy getRegEqualityTy()
const {
715 assert(Kind == k_Register &&
"Invalid access!");
716 return Reg.EqualityTy;
719 unsigned getVectorListStart()
const {
720 assert(Kind == k_VectorList &&
"Invalid access!");
721 return VectorList.RegNum;
724 unsigned getVectorListCount()
const {
725 assert(Kind == k_VectorList &&
"Invalid access!");
726 return VectorList.Count;
729 unsigned getVectorListStride()
const {
730 assert(Kind == k_VectorList &&
"Invalid access!");
731 return VectorList.Stride;
734 int getVectorIndex()
const {
735 assert(Kind == k_VectorIndex &&
"Invalid access!");
736 return VectorIndex.Val;
739 StringRef getSysReg()
const {
740 assert(Kind == k_SysReg &&
"Invalid access!");
741 return StringRef(SysReg.Data, SysReg.Length);
744 unsigned getSysCR()
const {
745 assert(Kind == k_SysCR &&
"Invalid access!");
749 unsigned getPrefetch()
const {
750 assert(Kind == k_Prefetch &&
"Invalid access!");
754 unsigned getPSBHint()
const {
755 assert(Kind == k_PSBHint &&
"Invalid access!");
759 unsigned getPHint()
const {
760 assert(Kind == k_PHint &&
"Invalid access!");
764 StringRef getPSBHintName()
const {
765 assert(Kind == k_PSBHint &&
"Invalid access!");
766 return StringRef(PSBHint.Data, PSBHint.Length);
769 StringRef getPHintName()
const {
770 assert(Kind == k_PHint &&
"Invalid access!");
771 return StringRef(PHint.Data, PHint.Length);
774 unsigned getBTIHint()
const {
775 assert(Kind == k_BTIHint &&
"Invalid access!");
779 StringRef getBTIHintName()
const {
780 assert(Kind == k_BTIHint &&
"Invalid access!");
781 return StringRef(BTIHint.Data, BTIHint.Length);
784 unsigned getCMHPriorityHint()
const {
785 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
786 return CMHPriorityHint.Val;
789 StringRef getCMHPriorityHintName()
const {
790 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
791 return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
794 StringRef getSVCR()
const {
795 assert(Kind == k_SVCR &&
"Invalid access!");
796 return StringRef(SVCR.Data, SVCR.Length);
799 StringRef getPrefetchName()
const {
800 assert(Kind == k_Prefetch &&
"Invalid access!");
805 if (Kind == k_ShiftExtend)
806 return ShiftExtend.Type;
807 if (Kind == k_Register)
808 return Reg.ShiftExtend.Type;
812 unsigned getShiftExtendAmount()
const {
813 if (Kind == k_ShiftExtend)
814 return ShiftExtend.Amount;
815 if (Kind == k_Register)
816 return Reg.ShiftExtend.Amount;
820 bool hasShiftExtendAmount()
const {
821 if (Kind == k_ShiftExtend)
822 return ShiftExtend.HasExplicitAmount;
823 if (Kind == k_Register)
824 return Reg.ShiftExtend.HasExplicitAmount;
828 bool isImm()
const override {
return Kind == k_Immediate; }
829 bool isMem()
const override {
return false; }
831 bool isUImm6()
const {
838 return (Val >= 0 && Val < 64);
841 template <
int W
idth>
bool isSImm()
const {
842 return bool(isSImmScaled<Width, 1>());
845 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
846 return isImmScaled<Bits, Scale>(
true);
849 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
850 DiagnosticPredicate isUImmScaled()
const {
851 if (IsRange && isImmRange() &&
852 (getLastImmVal() != getFirstImmVal() +
Offset))
855 return isImmScaled<Bits, Scale, IsRange>(
false);
858 template <
int Bits,
int Scale,
bool IsRange = false>
859 DiagnosticPredicate isImmScaled(
bool Signed)
const {
860 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
861 (isImmRange() && !IsRange))
866 Val = getFirstImmVal();
874 int64_t MinVal, MaxVal;
876 int64_t Shift =
Bits - 1;
877 MinVal = (int64_t(1) << Shift) * -Scale;
878 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
881 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
884 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
890 DiagnosticPredicate isSVEPattern()
const {
897 if (Val >= 0 && Val < 32)
902 DiagnosticPredicate isSVEVecLenSpecifier()
const {
909 if (Val >= 0 && Val <= 1)
914 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
918 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
947 template <
int Scale>
bool isUImm12Offset()
const {
953 return isSymbolicUImm12Offset(
getImm());
956 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
959 template <
int N,
int M>
960 bool isImmInRange()
const {
967 return (Val >=
N && Val <= M);
972 template <
typename T>
973 bool isLogicalImm()
const {
982 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
990 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
992 bool isImmRange()
const {
return Kind == k_ImmRange; }
997 template <
unsigned W
idth>
998 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
999 if (isShiftedImm() && Width == getShiftedImmShift())
1001 return std::make_pair(
CE->getValue(), Width);
1005 int64_t Val =
CE->getValue();
1006 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
1007 return std::make_pair(Val >> Width, Width);
1009 return std::make_pair(Val, 0u);
1015 bool isAddSubImm()
const {
1016 if (!isShiftedImm() && !isImm())
1022 if (isShiftedImm()) {
1023 unsigned Shift = ShiftedImm.ShiftAmount;
1024 Expr = ShiftedImm.Val;
1025 if (Shift != 0 && Shift != 12)
1034 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1050 if (
auto ShiftedVal = getShiftedVal<12>())
1051 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1058 bool isAddSubImmNeg()
const {
1059 if (!isShiftedImm() && !isImm())
1063 if (
auto ShiftedVal = getShiftedVal<12>())
1064 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1074 template <
typename T>
1075 DiagnosticPredicate isSVECpyImm()
const {
1079 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1080 std::is_same<int8_t, T>::value;
1081 if (
auto ShiftedImm = getShiftedVal<8>())
1082 if (!(IsByte && ShiftedImm->second) &&
1084 << ShiftedImm->second))
1093 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1097 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1098 std::is_same<int8_t, T>::value;
1099 if (
auto ShiftedImm = getShiftedVal<8>())
1100 if (!(IsByte && ShiftedImm->second) &&
1102 << ShiftedImm->second))
1108 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1109 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1114 bool isCondCode()
const {
return Kind == k_CondCode; }
1116 bool isSIMDImmType10()
const {
1126 bool isBranchTarget()
const {
1135 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1136 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1146 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1156 bool isMovWSymbolG3()
const {
1160 bool isMovWSymbolG2()
const {
1167 bool isMovWSymbolG1()
const {
1175 bool isMovWSymbolG0()
const {
1183 template<
int RegW
idth,
int Shift>
1184 bool isMOVZMovAlias()
const {
1185 if (!isImm())
return false;
1189 uint64_t
Value =
CE->getValue();
1198 template<
int RegW
idth,
int Shift>
1199 bool isMOVNMovAlias()
const {
1200 if (!isImm())
return false;
1203 if (!CE)
return false;
1204 uint64_t
Value =
CE->getValue();
1209 bool isFPImm()
const {
1210 return Kind == k_FPImm &&
1214 bool isBarrier()
const {
1215 return Kind == k_Barrier && !getBarriernXSModifier();
1217 bool isBarriernXS()
const {
1218 return Kind == k_Barrier && getBarriernXSModifier();
1220 bool isSysReg()
const {
return Kind == k_SysReg; }
1222 bool isMRSSystemRegister()
const {
1223 if (!isSysReg())
return false;
1225 return SysReg.MRSReg != -1U;
1228 bool isMSRSystemRegister()
const {
1229 if (!isSysReg())
return false;
1230 return SysReg.MSRReg != -1U;
1233 bool isSystemPStateFieldWithImm0_1()
const {
1234 if (!isSysReg())
return false;
1235 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1238 bool isSystemPStateFieldWithImm0_15()
const {
1241 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1244 bool isSVCR()
const {
1247 return SVCR.PStateField != -1U;
1250 bool isReg()
const override {
1251 return Kind == k_Register;
1254 bool isVectorList()
const {
return Kind == k_VectorList; }
1256 bool isScalarReg()
const {
1257 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1260 bool isNeonVectorReg()
const {
1261 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1264 bool isNeonVectorRegLo()
const {
1265 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1266 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1268 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1272 bool isNeonVectorReg0to7()
const {
1273 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1274 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1278 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1279 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1281 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1284 case AArch64::PPRRegClassID:
1285 case AArch64::PPR_3bRegClassID:
1286 case AArch64::PPR_p8to15RegClassID:
1287 case AArch64::PNRRegClassID:
1288 case AArch64::PNR_p8to15RegClassID:
1289 case AArch64::PPRorPNRRegClassID:
1290 RK = RegKind::SVEPredicateAsCounter;
1296 return (Kind == k_Register &&
Reg.Kind == RK) &&
1297 AArch64MCRegisterClasses[
Class].contains(
getReg());
1300 template <
unsigned Class>
bool isSVEVectorReg()
const {
1303 case AArch64::ZPRRegClassID:
1304 case AArch64::ZPR_3bRegClassID:
1305 case AArch64::ZPR_4bRegClassID:
1306 case AArch64::ZPRMul2_LoRegClassID:
1307 case AArch64::ZPRMul2_HiRegClassID:
1308 case AArch64::ZPR_KRegClassID:
1309 RK = RegKind::SVEDataVector;
1311 case AArch64::PPRRegClassID:
1312 case AArch64::PPR_3bRegClassID:
1313 case AArch64::PPR_p8to15RegClassID:
1314 case AArch64::PNRRegClassID:
1315 case AArch64::PNR_p8to15RegClassID:
1316 case AArch64::PPRorPNRRegClassID:
1317 RK = RegKind::SVEPredicateVector;
1323 return (Kind == k_Register &&
Reg.Kind == RK) &&
1324 AArch64MCRegisterClasses[
Class].contains(
getReg());
1327 template <
unsigned Class>
bool isFPRasZPR()
const {
1328 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1329 AArch64MCRegisterClasses[
Class].contains(
getReg());
1332 template <
int ElementW
idth,
unsigned Class>
1333 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1334 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1337 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1343 template <
int ElementW
idth,
unsigned Class>
1344 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1345 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1346 Reg.Kind != RegKind::SVEPredicateVector))
1349 if ((isSVEPredicateAsCounterReg<Class>() ||
1350 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1351 Reg.ElementWidth == ElementWidth)
1357 template <
int ElementW
idth,
unsigned Class>
1358 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1359 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1362 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1368 template <
int ElementW
idth,
unsigned Class>
1369 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1370 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1373 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1379 template <
int ElementWidth,
unsigned Class,
1381 bool ShiftWidthAlwaysSame>
1382 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1383 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1384 if (!VectorMatch.isMatch())
1390 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1393 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1396 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1402 bool isGPR32as64()
const {
1403 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1404 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1407 bool isGPR64as32()
const {
1408 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1409 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1412 bool isGPR64x8()
const {
1413 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1414 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1418 bool isWSeqPair()
const {
1419 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1420 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1424 bool isXSeqPair()
const {
1425 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1426 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1430 bool isSyspXzrPair()
const {
1431 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1434 template<
int64_t Angle,
int64_t Remainder>
1435 DiagnosticPredicate isComplexRotation()
const {
1442 uint64_t
Value =
CE->getValue();
1444 if (
Value % Angle == Remainder &&
Value <= 270)
1449 template <
unsigned RegClassID>
bool isGPR64()
const {
1450 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1451 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1454 template <
unsigned RegClassID,
int ExtW
idth>
1455 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1456 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1459 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1460 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1467 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1468 bool isImplicitlyTypedVectorList()
const {
1469 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1470 VectorList.NumElements == 0 &&
1471 VectorList.RegisterKind == VectorKind &&
1472 (!IsConsecutive || (VectorList.Stride == 1));
1475 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1476 unsigned ElementWidth,
unsigned Stride = 1>
1477 bool isTypedVectorList()
const {
1478 if (Kind != k_VectorList)
1480 if (VectorList.Count != NumRegs)
1482 if (VectorList.RegisterKind != VectorKind)
1484 if (VectorList.ElementWidth != ElementWidth)
1486 if (VectorList.Stride != Stride)
1488 return VectorList.NumElements == NumElements;
1491 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1492 unsigned ElementWidth,
unsigned RegClass>
1493 DiagnosticPredicate isTypedVectorListMultiple()
const {
1495 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1498 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.RegNum))
1503 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1504 unsigned ElementWidth>
1505 DiagnosticPredicate isTypedVectorListStrided()
const {
1506 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1507 ElementWidth, Stride>();
1510 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1511 ((VectorList.RegNum >= AArch64::Z16) &&
1512 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1517 template <
int Min,
int Max>
1518 DiagnosticPredicate isVectorIndex()
const {
1519 if (Kind != k_VectorIndex)
1521 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1526 bool isToken()
const override {
return Kind == k_Token; }
1528 bool isTokenEqual(StringRef Str)
const {
1529 return Kind == k_Token &&
getToken() == Str;
1531 bool isSysCR()
const {
return Kind == k_SysCR; }
1532 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1533 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1534 bool isPHint()
const {
return Kind == k_PHint; }
1535 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1536 bool isCMHPriorityHint()
const {
return Kind == k_CMHPriorityHint; }
1537 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1538 bool isShifter()
const {
1539 if (!isShiftExtend())
1548 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1549 if (Kind != k_FPImm)
1552 if (getFPImmIsExact()) {
1554 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1558 APFloat RealVal(APFloat::IEEEdouble());
1560 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1561 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1564 if (
getFPImm().bitwiseIsEqual(RealVal))
1571 template <
unsigned ImmA,
unsigned ImmB>
1572 DiagnosticPredicate isExactFPImm()
const {
1574 if ((Res = isExactFPImm<ImmA>()))
1576 if ((Res = isExactFPImm<ImmB>()))
1581 bool isExtend()
const {
1582 if (!isShiftExtend())
1591 getShiftExtendAmount() <= 4;
1594 bool isExtend64()
const {
1604 bool isExtendLSL64()
const {
1610 getShiftExtendAmount() <= 4;
1613 bool isLSLImm3Shift()
const {
1614 if (!isShiftExtend())
1620 template<
int W
idth>
bool isMemXExtend()
const {
1625 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1626 getShiftExtendAmount() == 0);
1629 template<
int W
idth>
bool isMemWExtend()
const {
1634 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1635 getShiftExtendAmount() == 0);
1638 template <
unsigned w
idth>
1639 bool isArithmeticShifter()
const {
1649 template <
unsigned w
idth>
1650 bool isLogicalShifter()
const {
1658 getShiftExtendAmount() < width;
1661 bool isMovImm32Shifter()
const {
1669 uint64_t Val = getShiftExtendAmount();
1670 return (Val == 0 || Val == 16);
1673 bool isMovImm64Shifter()
const {
1681 uint64_t Val = getShiftExtendAmount();
1682 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1685 bool isLogicalVecShifter()
const {
1690 unsigned Shift = getShiftExtendAmount();
1692 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1695 bool isLogicalVecHalfWordShifter()
const {
1696 if (!isLogicalVecShifter())
1700 unsigned Shift = getShiftExtendAmount();
1702 (Shift == 0 || Shift == 8);
1705 bool isMoveVecShifter()
const {
1706 if (!isShiftExtend())
1710 unsigned Shift = getShiftExtendAmount();
1712 (Shift == 8 || Shift == 16);
1721 bool isSImm9OffsetFB()
const {
1722 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1725 bool isAdrpLabel()
const {
1732 int64_t Val =
CE->getValue();
1733 int64_t Min = - (4096 * (1LL << (21 - 1)));
1734 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1735 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1741 bool isAdrLabel()
const {
1748 int64_t Val =
CE->getValue();
1749 int64_t Min = - (1LL << (21 - 1));
1750 int64_t
Max = ((1LL << (21 - 1)) - 1);
1751 return Val >= Min && Val <=
Max;
1757 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1758 DiagnosticPredicate isMatrixRegOperand()
const {
1761 if (getMatrixKind() != Kind ||
1762 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1763 EltSize != getMatrixElementWidth())
1768 bool isPAuthPCRelLabel16Operand()
const {
1780 return (Val <= 0) && (Val > -(1 << 18));
1783 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1793 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1794 assert(
N == 1 &&
"Invalid number of operands!");
1798 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1799 assert(
N == 1 &&
"Invalid number of operands!");
1803 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1804 assert(
N == 1 &&
"Invalid number of operands!");
1806 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1808 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1815 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1816 assert(
N == 1 &&
"Invalid number of operands!");
1818 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1820 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1827 template <
int W
idth>
1828 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1831 case 8:
Base = AArch64::B0;
break;
1832 case 16:
Base = AArch64::H0;
break;
1833 case 32:
Base = AArch64::S0;
break;
1834 case 64:
Base = AArch64::D0;
break;
1835 case 128:
Base = AArch64::Q0;
break;
1842 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1843 assert(
N == 1 &&
"Invalid number of operands!");
1846 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1847 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1851 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1852 assert(
N == 1 &&
"Invalid number of operands!");
1857 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1858 assert(
N == 1 &&
"Invalid number of operands!");
1860 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1864 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1865 assert(
N == 1 &&
"Invalid number of operands!");
1867 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1871 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1872 assert(
N == 1 &&
"Invalid number of operands!");
1876 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1877 assert(
N == 1 &&
"Invalid number of operands!");
1881 enum VecListIndexType {
1882 VecListIdx_DReg = 0,
1883 VecListIdx_QReg = 1,
1884 VecListIdx_ZReg = 2,
1885 VecListIdx_PReg = 3,
1888 template <VecListIndexType RegTy,
unsigned NumRegs,
1889 bool IsConsecutive =
false>
1890 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1891 assert(
N == 1 &&
"Invalid number of operands!");
1892 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1893 "Expected consecutive registers");
1894 static const unsigned FirstRegs[][5] = {
1896 AArch64::D0, AArch64::D0_D1,
1897 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1899 AArch64::Q0, AArch64::Q0_Q1,
1900 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1902 AArch64::Z0, AArch64::Z0_Z1,
1903 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1905 AArch64::P0, AArch64::P0_P1 }
1908 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1909 " NumRegs must be <= 4 for ZRegs");
1911 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1912 " NumRegs must be <= 2 for PRegs");
1914 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1916 FirstRegs[(
unsigned)RegTy][0]));
1919 template <
unsigned NumRegs>
1920 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1921 assert(
N == 1 &&
"Invalid number of operands!");
1922 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1926 if (getVectorListStart() < AArch64::Z16) {
1927 assert((getVectorListStart() < AArch64::Z8) &&
1928 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1930 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1932 assert((getVectorListStart() < AArch64::Z24) &&
1933 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1935 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1939 if (getVectorListStart() < AArch64::Z16) {
1940 assert((getVectorListStart() < AArch64::Z4) &&
1941 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1943 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1945 assert((getVectorListStart() < AArch64::Z20) &&
1946 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1948 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1956 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1957 assert(
N == 1 &&
"Invalid number of operands!");
1958 unsigned RegMask = getMatrixTileListRegMask();
1959 assert(RegMask <= 0xFF &&
"Invalid mask!");
1963 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1964 assert(
N == 1 &&
"Invalid number of operands!");
1968 template <
unsigned ImmIs0,
unsigned ImmIs1>
1969 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1970 assert(
N == 1 &&
"Invalid number of operands!");
1971 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1975 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1976 assert(
N == 1 &&
"Invalid number of operands!");
1983 template <
int Shift>
1984 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1985 assert(
N == 2 &&
"Invalid number of operands!");
1986 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1989 }
else if (isShiftedImm()) {
1990 addExpr(Inst, getShiftedImmVal());
1998 template <
int Shift>
1999 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2000 assert(
N == 2 &&
"Invalid number of operands!");
2001 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2008 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2009 assert(
N == 1 &&
"Invalid number of operands!");
2013 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
2014 assert(
N == 1 &&
"Invalid number of operands!");
2022 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2023 addImmOperands(Inst,
N);
2027 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
2028 assert(
N == 1 &&
"Invalid number of operands!");
2038 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2039 assert(
N == 1 &&
"Invalid number of operands!");
2044 template <
int Scale>
2045 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2046 assert(
N == 1 &&
"Invalid number of operands!");
2051 template <
int Scale>
2052 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2053 assert(
N == 1 &&
"Invalid number of operands!");
2057 template <
typename T>
2058 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2059 assert(
N == 1 &&
"Invalid number of operands!");
2061 std::make_unsigned_t<T> Val = MCE->
getValue();
2066 template <
typename T>
2067 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2068 assert(
N == 1 &&
"Invalid number of operands!");
2070 std::make_unsigned_t<T> Val = ~MCE->getValue();
2075 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2076 assert(
N == 1 &&
"Invalid number of operands!");
2082 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2086 assert(
N == 1 &&
"Invalid number of operands!");
2092 assert(MCE &&
"Invalid constant immediate operand!");
2096 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2100 assert(
N == 1 &&
"Invalid number of operands!");
2109 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2113 assert(
N == 1 &&
"Invalid number of operands!");
2119 assert(MCE &&
"Invalid constant immediate operand!");
2123 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2127 assert(
N == 1 &&
"Invalid number of operands!");
2133 assert(MCE &&
"Invalid constant immediate operand!");
2137 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2141 assert(
N == 1 &&
"Invalid number of operands!");
2147 assert(MCE &&
"Invalid constant immediate operand!");
2151 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2152 assert(
N == 1 &&
"Invalid number of operands!");
2157 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2158 assert(
N == 1 &&
"Invalid number of operands!");
2162 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2167 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2168 assert(
N == 1 &&
"Invalid number of operands!");
2173 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2174 assert(
N == 1 &&
"Invalid number of operands!");
2179 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2185 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2186 assert(
N == 1 &&
"Invalid number of operands!");
2191 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2192 assert(
N == 1 &&
"Invalid number of operands!");
2197 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2198 assert(
N == 1 &&
"Invalid number of operands!");
2202 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2203 assert(
N == 1 &&
"Invalid number of operands!");
2207 void addPSBHintOperands(MCInst &Inst,
unsigned N)
const {
2208 assert(
N == 1 &&
"Invalid number of operands!");
2212 void addPHintOperands(MCInst &Inst,
unsigned N)
const {
2213 assert(
N == 1 &&
"Invalid number of operands!");
2217 void addBTIHintOperands(MCInst &Inst,
unsigned N)
const {
2218 assert(
N == 1 &&
"Invalid number of operands!");
2222 void addCMHPriorityHintOperands(MCInst &Inst,
unsigned N)
const {
2223 assert(
N == 1 &&
"Invalid number of operands!");
2227 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2228 assert(
N == 1 &&
"Invalid number of operands!");
2234 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2235 assert(
N == 1 &&
"Invalid number of operands!");
2236 unsigned Imm = getShiftExtendAmount();
2240 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2241 assert(
N == 1 &&
"Invalid number of operands!");
2246 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2249 if (
Reg != AArch64::XZR)
2255 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2256 assert(
N == 1 &&
"Invalid number of operands!");
2263 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2264 assert(
N == 1 &&
"Invalid number of operands!");
2271 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2272 assert(
N == 2 &&
"Invalid number of operands!");
2283 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2284 assert(
N == 2 &&
"Invalid number of operands!");
2292 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2293 assert(
N == 1 &&
"Invalid number of operands!");
2297 uint64_t
Value =
CE->getValue();
2305 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2306 assert(
N == 1 &&
"Invalid number of operands!");
2309 uint64_t
Value =
CE->getValue();
2313 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2314 assert(
N == 1 &&
"Invalid number of operands!");
2319 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2320 assert(
N == 1 &&
"Invalid number of operands!");
2325 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2327 static std::unique_ptr<AArch64Operand>
2328 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2329 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2330 Op->Tok.Data = Str.data();
2331 Op->Tok.Length = Str.size();
2332 Op->Tok.IsSuffix = IsSuffix;
2338 static std::unique_ptr<AArch64Operand>
2339 CreateReg(
unsigned RegNum, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2340 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2342 unsigned ShiftAmount = 0,
2343 unsigned HasExplicitAmount =
false) {
2344 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2345 Op->Reg.RegNum = RegNum;
2346 Op->Reg.Kind = Kind;
2347 Op->Reg.ElementWidth = 0;
2348 Op->Reg.EqualityTy = EqTy;
2349 Op->Reg.ShiftExtend.Type = ExtTy;
2350 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2351 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2357 static std::unique_ptr<AArch64Operand>
2358 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2359 SMLoc S, SMLoc
E, MCContext &Ctx,
2361 unsigned ShiftAmount = 0,
2362 unsigned HasExplicitAmount =
false) {
2363 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2364 Kind == RegKind::SVEPredicateVector ||
2365 Kind == RegKind::SVEPredicateAsCounter) &&
2366 "Invalid vector kind");
2367 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2369 Op->Reg.ElementWidth = ElementWidth;
2373 static std::unique_ptr<AArch64Operand>
2374 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2375 unsigned NumElements,
unsigned ElementWidth,
2376 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2377 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2378 Op->VectorList.RegNum = RegNum;
2380 Op->VectorList.Stride = Stride;
2381 Op->VectorList.NumElements = NumElements;
2382 Op->VectorList.ElementWidth = ElementWidth;
2383 Op->VectorList.RegisterKind = RegisterKind;
2389 static std::unique_ptr<AArch64Operand>
2390 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2391 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2392 Op->VectorIndex.Val = Idx;
2398 static std::unique_ptr<AArch64Operand>
2399 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2400 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2401 Op->MatrixTileList.RegMask = RegMask;
2407 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2408 const unsigned ElementWidth) {
2409 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2411 {{0, AArch64::ZAB0},
2412 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2413 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2414 {{8, AArch64::ZAB0},
2415 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2416 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2417 {{16, AArch64::ZAH0},
2418 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2419 {{16, AArch64::ZAH1},
2420 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2421 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2422 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2423 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2424 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2427 if (ElementWidth == 64)
2430 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2431 assert(!Regs.empty() &&
"Invalid tile or element width!");
2436 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2437 SMLoc
E, MCContext &Ctx) {
2438 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2445 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2446 unsigned ShiftAmount,
2449 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2450 Op->ShiftedImm .Val = Val;
2451 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2457 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2458 unsigned Last, SMLoc S,
2461 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2463 Op->ImmRange.Last =
Last;
2468 static std::unique_ptr<AArch64Operand>
2470 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2471 Op->CondCode.Code =
Code;
2477 static std::unique_ptr<AArch64Operand>
2478 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2479 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2481 Op->FPImm.IsExact = IsExact;
2487 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2491 bool HasnXSModifier) {
2492 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2493 Op->Barrier.Val = Val;
2494 Op->Barrier.Data = Str.data();
2495 Op->Barrier.Length = Str.size();
2496 Op->Barrier.HasnXSModifier = HasnXSModifier;
2502 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2505 uint32_t PStateField,
2507 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2508 Op->SysReg.Data = Str.data();
2509 Op->SysReg.Length = Str.size();
2510 Op->SysReg.MRSReg = MRSReg;
2511 Op->SysReg.MSRReg = MSRReg;
2512 Op->SysReg.PStateField = PStateField;
2518 static std::unique_ptr<AArch64Operand>
2519 CreatePHintInst(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2520 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2521 Op->PHint.Val = Val;
2522 Op->PHint.Data = Str.data();
2523 Op->PHint.Length = Str.size();
2529 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2530 SMLoc
E, MCContext &Ctx) {
2531 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2532 Op->SysCRImm.Val = Val;
2538 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2542 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2543 Op->Prefetch.Val = Val;
2544 Op->Barrier.Data = Str.data();
2545 Op->Barrier.Length = Str.size();
2551 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2555 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2556 Op->PSBHint.Val = Val;
2557 Op->PSBHint.Data = Str.data();
2558 Op->PSBHint.Length = Str.size();
2564 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2568 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2569 Op->BTIHint.Val = Val | 32;
2570 Op->BTIHint.Data = Str.data();
2571 Op->BTIHint.Length = Str.size();
2577 static std::unique_ptr<AArch64Operand>
2578 CreateCMHPriorityHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2579 auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
2580 Op->CMHPriorityHint.Val = Val;
2581 Op->CMHPriorityHint.Data = Str.data();
2582 Op->CMHPriorityHint.Length = Str.size();
2588 static std::unique_ptr<AArch64Operand>
2589 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2590 SMLoc S, SMLoc
E, MCContext &Ctx) {
2591 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2592 Op->MatrixReg.RegNum = RegNum;
2593 Op->MatrixReg.ElementWidth = ElementWidth;
2594 Op->MatrixReg.Kind = Kind;
2600 static std::unique_ptr<AArch64Operand>
2601 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2602 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2603 Op->SVCR.PStateField = PStateField;
2604 Op->SVCR.Data = Str.data();
2605 Op->SVCR.Length = Str.size();
2611 static std::unique_ptr<AArch64Operand>
2613 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2614 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2615 Op->ShiftExtend.Type = ShOp;
2616 Op->ShiftExtend.Amount = Val;
2617 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2629 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2630 if (!getFPImmIsExact())
2635 StringRef
Name = getBarrierName();
2637 OS <<
"<barrier " <<
Name <<
">";
2639 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2645 case k_ShiftedImm: {
2646 unsigned Shift = getShiftedImmShift();
2647 OS <<
"<shiftedimm ";
2654 OS << getFirstImmVal();
2655 OS <<
":" << getLastImmVal() <<
">";
2661 case k_VectorList: {
2662 OS <<
"<vectorlist ";
2663 unsigned Reg = getVectorListStart();
2664 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2665 OS <<
Reg + i * getVectorListStride() <<
" ";
2670 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2673 OS <<
"<sysreg: " << getSysReg() <<
'>';
2679 OS <<
"c" << getSysCR();
2682 StringRef
Name = getPrefetchName();
2684 OS <<
"<prfop " <<
Name <<
">";
2686 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2690 OS << getPSBHintName();
2693 OS << getPHintName();
2696 OS << getBTIHintName();
2698 case k_CMHPriorityHint:
2699 OS << getCMHPriorityHintName();
2701 case k_MatrixRegister:
2702 OS <<
"<matrix " << getMatrixReg() <<
">";
2704 case k_MatrixTileList: {
2705 OS <<
"<matrixlist ";
2706 unsigned RegMask = getMatrixTileListRegMask();
2707 unsigned MaxBits = 8;
2708 for (
unsigned I = MaxBits;
I > 0; --
I)
2709 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2718 OS <<
"<register " <<
getReg() <<
">";
2719 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2724 << getShiftExtendAmount();
2725 if (!hasShiftExtendAmount())
2741 .
Case(
"v0", AArch64::Q0)
2742 .
Case(
"v1", AArch64::Q1)
2743 .
Case(
"v2", AArch64::Q2)
2744 .
Case(
"v3", AArch64::Q3)
2745 .
Case(
"v4", AArch64::Q4)
2746 .
Case(
"v5", AArch64::Q5)
2747 .
Case(
"v6", AArch64::Q6)
2748 .
Case(
"v7", AArch64::Q7)
2749 .
Case(
"v8", AArch64::Q8)
2750 .
Case(
"v9", AArch64::Q9)
2751 .
Case(
"v10", AArch64::Q10)
2752 .
Case(
"v11", AArch64::Q11)
2753 .
Case(
"v12", AArch64::Q12)
2754 .
Case(
"v13", AArch64::Q13)
2755 .
Case(
"v14", AArch64::Q14)
2756 .
Case(
"v15", AArch64::Q15)
2757 .
Case(
"v16", AArch64::Q16)
2758 .
Case(
"v17", AArch64::Q17)
2759 .
Case(
"v18", AArch64::Q18)
2760 .
Case(
"v19", AArch64::Q19)
2761 .
Case(
"v20", AArch64::Q20)
2762 .
Case(
"v21", AArch64::Q21)
2763 .
Case(
"v22", AArch64::Q22)
2764 .
Case(
"v23", AArch64::Q23)
2765 .
Case(
"v24", AArch64::Q24)
2766 .
Case(
"v25", AArch64::Q25)
2767 .
Case(
"v26", AArch64::Q26)
2768 .
Case(
"v27", AArch64::Q27)
2769 .
Case(
"v28", AArch64::Q28)
2770 .
Case(
"v29", AArch64::Q29)
2771 .
Case(
"v30", AArch64::Q30)
2772 .
Case(
"v31", AArch64::Q31)
2781 RegKind VectorKind) {
2782 std::pair<int, int> Res = {-1, -1};
2784 switch (VectorKind) {
2785 case RegKind::NeonVector:
2788 .Case(
".1d", {1, 64})
2789 .Case(
".1q", {1, 128})
2791 .Case(
".2h", {2, 16})
2792 .Case(
".2b", {2, 8})
2793 .Case(
".2s", {2, 32})
2794 .Case(
".2d", {2, 64})
2797 .Case(
".4b", {4, 8})
2798 .Case(
".4h", {4, 16})
2799 .Case(
".4s", {4, 32})
2800 .Case(
".8b", {8, 8})
2801 .Case(
".8h", {8, 16})
2802 .Case(
".16b", {16, 8})
2807 .Case(
".h", {0, 16})
2808 .Case(
".s", {0, 32})
2809 .Case(
".d", {0, 64})
2812 case RegKind::SVEPredicateAsCounter:
2813 case RegKind::SVEPredicateVector:
2814 case RegKind::SVEDataVector:
2815 case RegKind::Matrix:
2819 .Case(
".h", {0, 16})
2820 .Case(
".s", {0, 32})
2821 .Case(
".d", {0, 64})
2822 .Case(
".q", {0, 128})
2829 if (Res == std::make_pair(-1, -1))
2830 return std::nullopt;
2832 return std::optional<std::pair<int, int>>(Res);
2841 .
Case(
"z0", AArch64::Z0)
2842 .
Case(
"z1", AArch64::Z1)
2843 .
Case(
"z2", AArch64::Z2)
2844 .
Case(
"z3", AArch64::Z3)
2845 .
Case(
"z4", AArch64::Z4)
2846 .
Case(
"z5", AArch64::Z5)
2847 .
Case(
"z6", AArch64::Z6)
2848 .
Case(
"z7", AArch64::Z7)
2849 .
Case(
"z8", AArch64::Z8)
2850 .
Case(
"z9", AArch64::Z9)
2851 .
Case(
"z10", AArch64::Z10)
2852 .
Case(
"z11", AArch64::Z11)
2853 .
Case(
"z12", AArch64::Z12)
2854 .
Case(
"z13", AArch64::Z13)
2855 .
Case(
"z14", AArch64::Z14)
2856 .
Case(
"z15", AArch64::Z15)
2857 .
Case(
"z16", AArch64::Z16)
2858 .
Case(
"z17", AArch64::Z17)
2859 .
Case(
"z18", AArch64::Z18)
2860 .
Case(
"z19", AArch64::Z19)
2861 .
Case(
"z20", AArch64::Z20)
2862 .
Case(
"z21", AArch64::Z21)
2863 .
Case(
"z22", AArch64::Z22)
2864 .
Case(
"z23", AArch64::Z23)
2865 .
Case(
"z24", AArch64::Z24)
2866 .
Case(
"z25", AArch64::Z25)
2867 .
Case(
"z26", AArch64::Z26)
2868 .
Case(
"z27", AArch64::Z27)
2869 .
Case(
"z28", AArch64::Z28)
2870 .
Case(
"z29", AArch64::Z29)
2871 .
Case(
"z30", AArch64::Z30)
2872 .
Case(
"z31", AArch64::Z31)
2878 .
Case(
"p0", AArch64::P0)
2879 .
Case(
"p1", AArch64::P1)
2880 .
Case(
"p2", AArch64::P2)
2881 .
Case(
"p3", AArch64::P3)
2882 .
Case(
"p4", AArch64::P4)
2883 .
Case(
"p5", AArch64::P5)
2884 .
Case(
"p6", AArch64::P6)
2885 .
Case(
"p7", AArch64::P7)
2886 .
Case(
"p8", AArch64::P8)
2887 .
Case(
"p9", AArch64::P9)
2888 .
Case(
"p10", AArch64::P10)
2889 .
Case(
"p11", AArch64::P11)
2890 .
Case(
"p12", AArch64::P12)
2891 .
Case(
"p13", AArch64::P13)
2892 .
Case(
"p14", AArch64::P14)
2893 .
Case(
"p15", AArch64::P15)
2899 .
Case(
"pn0", AArch64::PN0)
2900 .
Case(
"pn1", AArch64::PN1)
2901 .
Case(
"pn2", AArch64::PN2)
2902 .
Case(
"pn3", AArch64::PN3)
2903 .
Case(
"pn4", AArch64::PN4)
2904 .
Case(
"pn5", AArch64::PN5)
2905 .
Case(
"pn6", AArch64::PN6)
2906 .
Case(
"pn7", AArch64::PN7)
2907 .
Case(
"pn8", AArch64::PN8)
2908 .
Case(
"pn9", AArch64::PN9)
2909 .
Case(
"pn10", AArch64::PN10)
2910 .
Case(
"pn11", AArch64::PN11)
2911 .
Case(
"pn12", AArch64::PN12)
2912 .
Case(
"pn13", AArch64::PN13)
2913 .
Case(
"pn14", AArch64::PN14)
2914 .
Case(
"pn15", AArch64::PN15)
2920 .
Case(
"za0.d", AArch64::ZAD0)
2921 .
Case(
"za1.d", AArch64::ZAD1)
2922 .
Case(
"za2.d", AArch64::ZAD2)
2923 .
Case(
"za3.d", AArch64::ZAD3)
2924 .
Case(
"za4.d", AArch64::ZAD4)
2925 .
Case(
"za5.d", AArch64::ZAD5)
2926 .
Case(
"za6.d", AArch64::ZAD6)
2927 .
Case(
"za7.d", AArch64::ZAD7)
2928 .
Case(
"za0.s", AArch64::ZAS0)
2929 .
Case(
"za1.s", AArch64::ZAS1)
2930 .
Case(
"za2.s", AArch64::ZAS2)
2931 .
Case(
"za3.s", AArch64::ZAS3)
2932 .
Case(
"za0.h", AArch64::ZAH0)
2933 .
Case(
"za1.h", AArch64::ZAH1)
2934 .
Case(
"za0.b", AArch64::ZAB0)
2940 .
Case(
"za", AArch64::ZA)
2941 .
Case(
"za0.q", AArch64::ZAQ0)
2942 .
Case(
"za1.q", AArch64::ZAQ1)
2943 .
Case(
"za2.q", AArch64::ZAQ2)
2944 .
Case(
"za3.q", AArch64::ZAQ3)
2945 .
Case(
"za4.q", AArch64::ZAQ4)
2946 .
Case(
"za5.q", AArch64::ZAQ5)
2947 .
Case(
"za6.q", AArch64::ZAQ6)
2948 .
Case(
"za7.q", AArch64::ZAQ7)
2949 .
Case(
"za8.q", AArch64::ZAQ8)
2950 .
Case(
"za9.q", AArch64::ZAQ9)
2951 .
Case(
"za10.q", AArch64::ZAQ10)
2952 .
Case(
"za11.q", AArch64::ZAQ11)
2953 .
Case(
"za12.q", AArch64::ZAQ12)
2954 .
Case(
"za13.q", AArch64::ZAQ13)
2955 .
Case(
"za14.q", AArch64::ZAQ14)
2956 .
Case(
"za15.q", AArch64::ZAQ15)
2957 .
Case(
"za0.d", AArch64::ZAD0)
2958 .
Case(
"za1.d", AArch64::ZAD1)
2959 .
Case(
"za2.d", AArch64::ZAD2)
2960 .
Case(
"za3.d", AArch64::ZAD3)
2961 .
Case(
"za4.d", AArch64::ZAD4)
2962 .
Case(
"za5.d", AArch64::ZAD5)
2963 .
Case(
"za6.d", AArch64::ZAD6)
2964 .
Case(
"za7.d", AArch64::ZAD7)
2965 .
Case(
"za0.s", AArch64::ZAS0)
2966 .
Case(
"za1.s", AArch64::ZAS1)
2967 .
Case(
"za2.s", AArch64::ZAS2)
2968 .
Case(
"za3.s", AArch64::ZAS3)
2969 .
Case(
"za0.h", AArch64::ZAH0)
2970 .
Case(
"za1.h", AArch64::ZAH1)
2971 .
Case(
"za0.b", AArch64::ZAB0)
2972 .
Case(
"za0h.q", AArch64::ZAQ0)
2973 .
Case(
"za1h.q", AArch64::ZAQ1)
2974 .
Case(
"za2h.q", AArch64::ZAQ2)
2975 .
Case(
"za3h.q", AArch64::ZAQ3)
2976 .
Case(
"za4h.q", AArch64::ZAQ4)
2977 .
Case(
"za5h.q", AArch64::ZAQ5)
2978 .
Case(
"za6h.q", AArch64::ZAQ6)
2979 .
Case(
"za7h.q", AArch64::ZAQ7)
2980 .
Case(
"za8h.q", AArch64::ZAQ8)
2981 .
Case(
"za9h.q", AArch64::ZAQ9)
2982 .
Case(
"za10h.q", AArch64::ZAQ10)
2983 .
Case(
"za11h.q", AArch64::ZAQ11)
2984 .
Case(
"za12h.q", AArch64::ZAQ12)
2985 .
Case(
"za13h.q", AArch64::ZAQ13)
2986 .
Case(
"za14h.q", AArch64::ZAQ14)
2987 .
Case(
"za15h.q", AArch64::ZAQ15)
2988 .
Case(
"za0h.d", AArch64::ZAD0)
2989 .
Case(
"za1h.d", AArch64::ZAD1)
2990 .
Case(
"za2h.d", AArch64::ZAD2)
2991 .
Case(
"za3h.d", AArch64::ZAD3)
2992 .
Case(
"za4h.d", AArch64::ZAD4)
2993 .
Case(
"za5h.d", AArch64::ZAD5)
2994 .
Case(
"za6h.d", AArch64::ZAD6)
2995 .
Case(
"za7h.d", AArch64::ZAD7)
2996 .
Case(
"za0h.s", AArch64::ZAS0)
2997 .
Case(
"za1h.s", AArch64::ZAS1)
2998 .
Case(
"za2h.s", AArch64::ZAS2)
2999 .
Case(
"za3h.s", AArch64::ZAS3)
3000 .
Case(
"za0h.h", AArch64::ZAH0)
3001 .
Case(
"za1h.h", AArch64::ZAH1)
3002 .
Case(
"za0h.b", AArch64::ZAB0)
3003 .
Case(
"za0v.q", AArch64::ZAQ0)
3004 .
Case(
"za1v.q", AArch64::ZAQ1)
3005 .
Case(
"za2v.q", AArch64::ZAQ2)
3006 .
Case(
"za3v.q", AArch64::ZAQ3)
3007 .
Case(
"za4v.q", AArch64::ZAQ4)
3008 .
Case(
"za5v.q", AArch64::ZAQ5)
3009 .
Case(
"za6v.q", AArch64::ZAQ6)
3010 .
Case(
"za7v.q", AArch64::ZAQ7)
3011 .
Case(
"za8v.q", AArch64::ZAQ8)
3012 .
Case(
"za9v.q", AArch64::ZAQ9)
3013 .
Case(
"za10v.q", AArch64::ZAQ10)
3014 .
Case(
"za11v.q", AArch64::ZAQ11)
3015 .
Case(
"za12v.q", AArch64::ZAQ12)
3016 .
Case(
"za13v.q", AArch64::ZAQ13)
3017 .
Case(
"za14v.q", AArch64::ZAQ14)
3018 .
Case(
"za15v.q", AArch64::ZAQ15)
3019 .
Case(
"za0v.d", AArch64::ZAD0)
3020 .
Case(
"za1v.d", AArch64::ZAD1)
3021 .
Case(
"za2v.d", AArch64::ZAD2)
3022 .
Case(
"za3v.d", AArch64::ZAD3)
3023 .
Case(
"za4v.d", AArch64::ZAD4)
3024 .
Case(
"za5v.d", AArch64::ZAD5)
3025 .
Case(
"za6v.d", AArch64::ZAD6)
3026 .
Case(
"za7v.d", AArch64::ZAD7)
3027 .
Case(
"za0v.s", AArch64::ZAS0)
3028 .
Case(
"za1v.s", AArch64::ZAS1)
3029 .
Case(
"za2v.s", AArch64::ZAS2)
3030 .
Case(
"za3v.s", AArch64::ZAS3)
3031 .
Case(
"za0v.h", AArch64::ZAH0)
3032 .
Case(
"za1v.h", AArch64::ZAH1)
3033 .
Case(
"za0v.b", AArch64::ZAB0)
3037bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3039 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3042ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3044 StartLoc = getLoc();
3045 ParseStatus Res = tryParseScalarRegister(
Reg);
3051unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
3053 unsigned RegNum = 0;
3055 return Kind == RegKind::SVEDataVector ? RegNum : 0;
3058 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
3061 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
3064 return Kind == RegKind::NeonVector ? RegNum : 0;
3067 return Kind == RegKind::Matrix ? RegNum : 0;
3069 if (
Name.equals_insensitive(
"zt0"))
3070 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
3074 return (Kind == RegKind::Scalar) ? RegNum : 0;
3078 if (
auto RegNum = StringSwitch<unsigned>(
Name.lower())
3079 .Case(
"fp", AArch64::FP)
3080 .Case(
"lr", AArch64::LR)
3081 .Case(
"x31", AArch64::XZR)
3082 .Case(
"w31", AArch64::WZR)
3084 return Kind == RegKind::Scalar ? RegNum : 0;
3090 if (Entry == RegisterReqs.
end())
3094 if (Kind ==
Entry->getValue().first)
3095 RegNum =
Entry->getValue().second;
3100unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3102 case RegKind::Scalar:
3103 case RegKind::NeonVector:
3104 case RegKind::SVEDataVector:
3106 case RegKind::Matrix:
3107 case RegKind::SVEPredicateVector:
3108 case RegKind::SVEPredicateAsCounter:
3110 case RegKind::LookupTable:
3119ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3120 const AsmToken &Tok = getTok();
3125 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3135ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3139 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3142 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3143 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3147 if (BadNum || CRNum > 15)
3148 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3152 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3157ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3159 const AsmToken &Tok = getTok();
3161 unsigned MaxVal = 63;
3166 const MCExpr *ImmVal;
3167 if (getParser().parseExpression(ImmVal))
3172 return TokError(
"immediate value expected for prefetch operand");
3175 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3178 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3179 Operands.
push_back(AArch64Operand::CreatePrefetch(
3180 prfop, RPRFM ? RPRFM->Name :
"", S,
getContext()));
3185 return TokError(
"prefetch hint expected");
3187 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3189 return TokError(
"prefetch hint expected");
3191 Operands.
push_back(AArch64Operand::CreatePrefetch(
3198template <
bool IsSVEPrefetch>
3199ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3201 const AsmToken &Tok = getTok();
3203 auto LookupByName = [](StringRef
N) {
3204 if (IsSVEPrefetch) {
3205 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3206 return std::optional<unsigned>(Res->Encoding);
3207 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3208 return std::optional<unsigned>(Res->Encoding);
3209 return std::optional<unsigned>();
3212 auto LookupByEncoding = [](
unsigned E) {
3213 if (IsSVEPrefetch) {
3214 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3215 return std::optional<StringRef>(Res->Name);
3216 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3217 return std::optional<StringRef>(Res->Name);
3218 return std::optional<StringRef>();
3220 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3226 const MCExpr *ImmVal;
3227 if (getParser().parseExpression(ImmVal))
3232 return TokError(
"immediate value expected for prefetch operand");
3235 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3238 auto PRFM = LookupByEncoding(MCE->
getValue());
3239 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3245 return TokError(
"prefetch hint expected");
3247 auto PRFM = LookupByName(Tok.
getString());
3249 return TokError(
"prefetch hint expected");
3251 Operands.
push_back(AArch64Operand::CreatePrefetch(
3258ParseStatus AArch64AsmParser::tryParsePSBHint(
OperandVector &Operands) {
3260 const AsmToken &Tok = getTok();
3262 return TokError(
"invalid operand for instruction");
3264 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3266 return TokError(
"invalid operand for instruction");
3268 Operands.
push_back(AArch64Operand::CreatePSBHint(
3274ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3275 SMLoc StartLoc = getLoc();
3281 auto RegTok = getTok();
3282 if (!tryParseScalarRegister(RegNum).isSuccess())
3285 if (RegNum != AArch64::XZR) {
3286 getLexer().UnLex(RegTok);
3293 if (!tryParseScalarRegister(RegNum).isSuccess())
3294 return TokError(
"expected register operand");
3296 if (RegNum != AArch64::XZR)
3297 return TokError(
"xzr must be followed by xzr");
3301 Operands.
push_back(AArch64Operand::CreateReg(
3302 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3308ParseStatus AArch64AsmParser::tryParseBTIHint(
OperandVector &Operands) {
3310 const AsmToken &Tok = getTok();
3312 return TokError(
"invalid operand for instruction");
3314 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3316 return TokError(
"invalid operand for instruction");
3318 Operands.
push_back(AArch64Operand::CreateBTIHint(
3325ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(
OperandVector &Operands) {
3327 const AsmToken &Tok = getTok();
3329 return TokError(
"invalid operand for instruction");
3332 AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.
getString());
3334 return TokError(
"invalid operand for instruction");
3336 Operands.
push_back(AArch64Operand::CreateCMHPriorityHint(
3344ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3346 const MCExpr *Expr =
nullptr;
3352 if (parseSymbolicImmVal(Expr))
3358 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3367 return Error(S,
"gotpage label reference not allowed an addend");
3379 return Error(S,
"page or gotpage label reference expected");
3394ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3396 const MCExpr *Expr =
nullptr;
3405 if (parseSymbolicImmVal(Expr))
3411 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3423 return Error(S,
"unexpected adr label");
3433template <
bool AddFPZeroAsLiteral>
3434ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3442 const AsmToken &Tok = getTok();
3446 return TokError(
"invalid floating point immediate");
3451 if (Tok.
getIntVal() > 255 || isNegative)
3452 return TokError(
"encoded floating point value out of range");
3456 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3459 APFloat RealVal(APFloat::IEEEdouble());
3461 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3463 return TokError(
"invalid floating point representation");
3466 RealVal.changeSign();
3468 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3472 Operands.
push_back(AArch64Operand::CreateFPImm(
3473 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3484AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3495 return tryParseImmRange(Operands);
3497 const MCExpr *
Imm =
nullptr;
3498 if (parseSymbolicImmVal(Imm))
3502 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3509 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3511 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3513 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3519 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3520 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3528 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3530 int64_t ShiftAmount = getTok().getIntVal();
3532 if (ShiftAmount < 0)
3533 return Error(getLoc(),
"positive shift amount required");
3537 if (ShiftAmount == 0 && Imm !=
nullptr) {
3539 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3543 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3551AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3585 Suggestion =
"nfrst";
3591bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3592 bool invertCondCode) {
3594 const AsmToken &Tok = getTok();
3598 std::string Suggestion;
3601 std::string Msg =
"invalid condition code";
3602 if (!Suggestion.empty())
3603 Msg +=
", did you mean " + Suggestion +
"?";
3604 return TokError(Msg);
3608 if (invertCondCode) {
3610 return TokError(
"condition codes AL and NV are invalid for this instruction");
3615 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3619ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3620 const AsmToken &Tok = getTok();
3624 return TokError(
"invalid operand for instruction");
3626 unsigned PStateImm = -1;
3627 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3630 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3631 PStateImm = SVCR->Encoding;
3639ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3640 const AsmToken &Tok = getTok();
3645 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3647 unsigned ElementWidth = 0;
3648 auto DotPosition =
Name.find(
'.');
3650 const auto &KindRes =
3654 "Expected the register to be followed by element width suffix");
3655 ElementWidth = KindRes->second;
3657 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3658 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3663 if (parseOperand(Operands,
false,
false))
3670 unsigned Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3674 size_t DotPosition =
Name.find(
'.');
3677 StringRef Head =
Name.take_front(DotPosition);
3678 StringRef
Tail =
Name.drop_front(DotPosition);
3679 StringRef RowOrColumn = Head.
take_back();
3681 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3682 .Case(
"h", MatrixKind::Row)
3683 .Case(
"v", MatrixKind::Col)
3684 .Default(MatrixKind::Tile);
3690 "Expected the register to be followed by element width suffix");
3691 unsigned ElementWidth = KindRes->second;
3695 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3701 if (parseOperand(Operands,
false,
false))
3710AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3711 const AsmToken &Tok = getTok();
3714 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3743 return TokError(
"expected #imm after shift specifier");
3749 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3758 return Error(
E,
"expected integer shift amount");
3760 const MCExpr *ImmVal;
3761 if (getParser().parseExpression(ImmVal))
3766 return Error(
E,
"expected constant '#imm' after shift specifier");
3769 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3778 {
"crc", {AArch64::FeatureCRC}},
3779 {
"sm4", {AArch64::FeatureSM4}},
3780 {
"sha3", {AArch64::FeatureSHA3}},
3781 {
"sha2", {AArch64::FeatureSHA2}},
3782 {
"aes", {AArch64::FeatureAES}},
3783 {
"crypto", {AArch64::FeatureCrypto}},
3784 {
"fp", {AArch64::FeatureFPARMv8}},
3785 {
"simd", {AArch64::FeatureNEON}},
3786 {
"ras", {AArch64::FeatureRAS}},
3787 {
"rasv2", {AArch64::FeatureRASv2}},
3788 {
"lse", {AArch64::FeatureLSE}},
3789 {
"predres", {AArch64::FeaturePredRes}},
3790 {
"predres2", {AArch64::FeatureSPECRES2}},
3791 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3792 {
"mte", {AArch64::FeatureMTE}},
3793 {
"memtag", {AArch64::FeatureMTE}},
3794 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3795 {
"pan", {AArch64::FeaturePAN}},
3796 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3797 {
"ccpp", {AArch64::FeatureCCPP}},
3798 {
"rcpc", {AArch64::FeatureRCPC}},
3799 {
"rng", {AArch64::FeatureRandGen}},
3800 {
"sve", {AArch64::FeatureSVE}},
3801 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3802 {
"sve2", {AArch64::FeatureSVE2}},
3803 {
"sve-aes", {AArch64::FeatureSVEAES}},
3804 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3805 {
"sve-sm4", {AArch64::FeatureSVESM4}},
3806 {
"sve2-sm4", {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3807 {
"sve-sha3", {AArch64::FeatureSVESHA3}},
3808 {
"sve2-sha3", {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3809 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3811 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3812 AArch64::FeatureSVE2}},
3813 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3814 {
"ls64", {AArch64::FeatureLS64}},
3815 {
"xs", {AArch64::FeatureXS}},
3816 {
"pauth", {AArch64::FeaturePAuth}},
3817 {
"flagm", {AArch64::FeatureFlagM}},
3818 {
"rme", {AArch64::FeatureRME}},
3819 {
"sme", {AArch64::FeatureSME}},
3820 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3821 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3822 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3823 {
"sme2", {AArch64::FeatureSME2}},
3824 {
"sme2p1", {AArch64::FeatureSME2p1}},
3825 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3826 {
"hbc", {AArch64::FeatureHBC}},
3827 {
"mops", {AArch64::FeatureMOPS}},
3828 {
"mec", {AArch64::FeatureMEC}},
3829 {
"the", {AArch64::FeatureTHE}},
3830 {
"d128", {AArch64::FeatureD128}},
3831 {
"lse128", {AArch64::FeatureLSE128}},
3832 {
"ite", {AArch64::FeatureITE}},
3833 {
"cssc", {AArch64::FeatureCSSC}},
3834 {
"rcpc3", {AArch64::FeatureRCPC3}},
3835 {
"gcs", {AArch64::FeatureGCS}},
3836 {
"bf16", {AArch64::FeatureBF16}},
3837 {
"compnum", {AArch64::FeatureComplxNum}},
3838 {
"dotprod", {AArch64::FeatureDotProd}},
3839 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3840 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3841 {
"fp16", {AArch64::FeatureFullFP16}},
3842 {
"fp16fml", {AArch64::FeatureFP16FML}},
3843 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3844 {
"lor", {AArch64::FeatureLOR}},
3845 {
"profile", {AArch64::FeatureSPE}},
3849 {
"rdm", {AArch64::FeatureRDM}},
3850 {
"rdma", {AArch64::FeatureRDM}},
3851 {
"sb", {AArch64::FeatureSB}},
3852 {
"ssbs", {AArch64::FeatureSSBS}},
3853 {
"tme", {AArch64::FeatureTME}},
3854 {
"fp8", {AArch64::FeatureFP8}},
3855 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3856 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3857 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3858 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3859 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3860 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3861 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3862 {
"lut", {AArch64::FeatureLUT}},
3863 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3864 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3865 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3866 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3867 {
"cpa", {AArch64::FeatureCPA}},
3868 {
"tlbiw", {AArch64::FeatureTLBIW}},
3869 {
"pops", {AArch64::FeaturePoPS}},
3870 {
"cmpbr", {AArch64::FeatureCMPBR}},
3871 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3872 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3873 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3874 {
"lsfe", {AArch64::FeatureLSFE}},
3875 {
"sme2p2", {AArch64::FeatureSME2p2}},
3876 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3877 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3878 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3879 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3880 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3881 {
"lsui", {AArch64::FeatureLSUI}},
3882 {
"occmo", {AArch64::FeatureOCCMO}},
3883 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3884 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3885 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3886 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3887 {
"cmh", {AArch64::FeatureCMH}},
3888 {
"lscp", {AArch64::FeatureLSCP}},
3889 {
"tlbid", {AArch64::FeatureTLBID}},
3890 {
"mpamv2", {AArch64::FeatureMPAMv2}},
3891 {
"mtetc", {AArch64::FeatureMTETC}},
3892 {
"gcie", {AArch64::FeatureGCIE}},
3893 {
"sme2p3", {AArch64::FeatureSME2p3}},
3894 {
"sve2p3", {AArch64::FeatureSVE2p3}},
3895 {
"sve-b16mm", {AArch64::FeatureSVE_B16MM}},
3896 {
"f16mm", {AArch64::FeatureF16MM}},
3897 {
"f16f32dot", {AArch64::FeatureF16F32DOT}},
3898 {
"f16f32mm", {AArch64::FeatureF16F32MM}},
3902 if (FBS[AArch64::HasV8_0aOps])
3904 if (FBS[AArch64::HasV8_1aOps])
3906 else if (FBS[AArch64::HasV8_2aOps])
3908 else if (FBS[AArch64::HasV8_3aOps])
3910 else if (FBS[AArch64::HasV8_4aOps])
3912 else if (FBS[AArch64::HasV8_5aOps])
3914 else if (FBS[AArch64::HasV8_6aOps])
3916 else if (FBS[AArch64::HasV8_7aOps])
3918 else if (FBS[AArch64::HasV8_8aOps])
3920 else if (FBS[AArch64::HasV8_9aOps])
3922 else if (FBS[AArch64::HasV9_0aOps])
3924 else if (FBS[AArch64::HasV9_1aOps])
3926 else if (FBS[AArch64::HasV9_2aOps])
3928 else if (FBS[AArch64::HasV9_3aOps])
3930 else if (FBS[AArch64::HasV9_4aOps])
3932 else if (FBS[AArch64::HasV9_5aOps])
3934 else if (FBS[AArch64::HasV9_6aOps])
3936 else if (FBS[AArch64::HasV9_7aOps])
3938 else if (FBS[AArch64::HasV8_0rOps])
3947 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3951void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
3953 const uint16_t Op2 = Encoding & 7;
3954 const uint16_t Cm = (Encoding & 0x78) >> 3;
3955 const uint16_t Cn = (Encoding & 0x780) >> 7;
3956 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3961 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3963 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3965 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3968 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3974bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3976 if (
Name.contains(
'.'))
3977 return TokError(
"invalid operand");
3982 const AsmToken &Tok = getTok();
3985 bool ExpectRegister =
true;
3986 bool OptionalRegister =
false;
3987 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3989 if (Mnemonic ==
"ic") {
3990 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3992 return TokError(
"invalid operand for IC instruction");
3993 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3994 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3996 return TokError(Str);
3999 createSysAlias(IC->
Encoding, Operands, S);
4000 }
else if (Mnemonic ==
"dc") {
4001 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
4003 return TokError(
"invalid operand for DC instruction");
4004 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
4005 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
4007 return TokError(Str);
4009 createSysAlias(DC->
Encoding, Operands, S);
4010 }
else if (Mnemonic ==
"at") {
4011 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
4013 return TokError(
"invalid operand for AT instruction");
4014 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
4015 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
4017 return TokError(Str);
4019 createSysAlias(AT->
Encoding, Operands, S);
4020 }
else if (Mnemonic ==
"tlbi") {
4021 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
4023 return TokError(
"invalid operand for TLBI instruction");
4024 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
4025 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
4027 return TokError(Str);
4030 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4031 if (hasAll || hasTLBID) {
4034 createSysAlias(TLBI->
Encoding, Operands, S);
4035 }
else if (Mnemonic ==
"mlbi") {
4036 const AArch64MLBI::MLBI *MLBI = AArch64MLBI::lookupMLBIByName(
Op);
4038 return TokError(
"invalid operand for MLBI instruction");
4039 else if (!MLBI->
haveFeatures(getSTI().getFeatureBits())) {
4040 std::string Str(
"MLBI " + std::string(MLBI->
Name) +
" requires: ");
4042 return TokError(Str);
4045 createSysAlias(MLBI->
Encoding, Operands, S);
4046 }
else if (Mnemonic ==
"gic") {
4047 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
4049 return TokError(
"invalid operand for GIC instruction");
4050 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
4051 std::string Str(
"GIC " + std::string(GIC->
Name) +
" requires: ");
4053 return TokError(Str);
4055 ExpectRegister =
true;
4056 createSysAlias(GIC->
Encoding, Operands, S);
4057 }
else if (Mnemonic ==
"gsb") {
4058 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
4060 return TokError(
"invalid operand for GSB instruction");
4061 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
4062 std::string Str(
"GSB " + std::string(GSB->
Name) +
" requires: ");
4064 return TokError(Str);
4066 ExpectRegister =
false;
4067 createSysAlias(GSB->
Encoding, Operands, S);
4068 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
4069 Mnemonic ==
"cosp") {
4071 if (
Op.lower() !=
"rctx")
4072 return TokError(
"invalid operand for prediction restriction instruction");
4074 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
4075 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
4077 if (Mnemonic ==
"cosp" && !hasSpecres2)
4078 return TokError(
"COSP requires: predres2");
4080 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
4082 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
4083 : Mnemonic ==
"dvp" ? 0b101
4084 : Mnemonic ==
"cosp" ? 0b110
4085 : Mnemonic ==
"cpp" ? 0b111
4088 "Invalid mnemonic for prediction restriction instruction");
4089 const auto SYS_3_7_3 = 0b01101110011;
4090 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
4092 createSysAlias(Encoding, Operands, S);
4097 bool HasRegister =
false;
4102 return TokError(
"expected register operand");
4106 if (!OptionalRegister) {
4107 if (ExpectRegister && !HasRegister)
4108 return TokError(
"specified " + Mnemonic +
" op requires a register");
4109 else if (!ExpectRegister && HasRegister)
4110 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4122bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4127 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4130 SMLoc startLoc = getLoc();
4131 const AsmToken ®Tok = getTok();
4133 unsigned RegNum = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4135 return TokError(
"expected register operand");
4137 Operands.
push_back(AArch64Operand::CreateReg(
4138 RegNum, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4145 const AsmToken &operandTok = getTok();
4147 SMLoc S2 = operandTok.
getLoc();
4150 if (Mnemonic ==
"gicr") {
4151 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4153 return Error(S2,
"invalid operand for GICR instruction");
4154 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4155 std::string Str(
"GICR " + std::string(GICR->
Name) +
" requires: ");
4157 return Error(S2, Str);
4159 createSysAlias(GICR->
Encoding, Operands, S2);
4170bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4172 if (
Name.contains(
'.'))
4173 return TokError(
"invalid operand");
4177 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4179 const AsmToken &Tok = getTok();
4183 if (Mnemonic ==
"tlbip") {
4184 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4185 if (HasnXSQualifier) {
4186 Op =
Op.drop_back(3);
4188 const AArch64TLBIP::TLBIP *TLBIPorig = AArch64TLBIP::lookupTLBIPByName(
Op);
4190 return TokError(
"invalid operand for TLBIP instruction");
4191 const AArch64TLBIP::TLBIP TLBIP(
4192 TLBIPorig->
Name, TLBIPorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4197 if (!TLBIP.haveFeatures(getSTI().getFeatureBits())) {
4199 std::string(TLBIP.Name) + (HasnXSQualifier ?
"nXS" :
"");
4200 std::string Str(
"TLBIP " + Name +
" requires: ");
4202 return TokError(Str);
4204 createSysAlias(TLBIP.Encoding, Operands, S);
4213 return TokError(
"expected register identifier");
4214 auto Result = tryParseSyspXzrPair(Operands);
4216 Result = tryParseGPRSeqPair(Operands);
4218 return TokError(
"specified " + Mnemonic +
4219 " op requires a pair of registers");
4227ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4228 MCAsmParser &Parser = getParser();
4229 const AsmToken &Tok = getTok();
4232 return TokError(
"'csync' operand expected");
4235 const MCExpr *ImmVal;
4236 SMLoc ExprLoc = getLoc();
4237 AsmToken IntTok = Tok;
4238 if (getParser().parseExpression(ImmVal))
4242 return Error(ExprLoc,
"immediate value expected for barrier operand");
4244 if (Mnemonic ==
"dsb" &&
Value > 15) {
4252 return Error(ExprLoc,
"barrier operand out of range");
4253 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4254 Operands.
push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4261 return TokError(
"invalid operand for instruction");
4264 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4265 auto DB = AArch64DB::lookupDBByName(Operand);
4267 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4268 return TokError(
"'sy' or #imm operand expected");
4270 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4271 return TokError(
"'csync' operand expected");
4273 if (Mnemonic ==
"dsb") {
4278 return TokError(
"invalid barrier option name");
4281 Operands.
push_back(AArch64Operand::CreateBarrier(
4282 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4290AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4291 const AsmToken &Tok = getTok();
4293 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4294 if (Mnemonic !=
"dsb")
4299 const MCExpr *ImmVal;
4300 SMLoc ExprLoc = getLoc();
4301 if (getParser().parseExpression(ImmVal))
4305 return Error(ExprLoc,
"immediate value expected for barrier operand");
4310 return Error(ExprLoc,
"barrier operand out of range");
4311 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4312 Operands.
push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4319 return TokError(
"invalid operand for instruction");
4322 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4325 return TokError(
"invalid barrier option name");
4328 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4335ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4336 const AsmToken &Tok = getTok();
4341 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4345 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4346 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4347 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4348 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4352 unsigned PStateImm = -1;
4353 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4354 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4355 PStateImm = PState15->Encoding;
4357 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4358 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4359 PStateImm = PState1->Encoding;
4363 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4371AArch64AsmParser::tryParsePHintInstOperand(
OperandVector &Operands) {
4373 const AsmToken &Tok = getTok();
4375 return TokError(
"invalid operand for instruction");
4379 return TokError(
"invalid operand for instruction");
4381 Operands.
push_back(AArch64Operand::CreatePHintInst(
4388bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4396 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4404 unsigned ElementWidth = KindRes->second;
4406 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4414 return tryParseVectorIndex(Operands).isFailure();
4417ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4418 SMLoc SIdx = getLoc();
4420 const MCExpr *ImmVal;
4421 if (getParser().parseExpression(ImmVal))
4425 return TokError(
"immediate value expected for vector index");
4443ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4445 RegKind MatchKind) {
4446 const AsmToken &Tok = getTok();
4455 StringRef Head =
Name.slice(Start,
Next);
4456 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4462 return TokError(
"invalid vector kind qualifier");
4473ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4475 ParseStatus Status =
4476 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4478 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4483template <RegKind RK>
4485AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4487 const SMLoc S = getLoc();
4490 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4498 unsigned ElementWidth = KindRes->second;
4499 Operands.
push_back(AArch64Operand::CreateVectorReg(
4500 RegNum, RK, ElementWidth, S,
4504 if (RK == RegKind::SVEPredicateAsCounter) {
4505 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4511 if (parseOperand(Operands,
false,
false))
4522 return Error(S,
"not expecting size suffix");
4530 auto Pred = getTok().getString().lower();
4531 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4532 return Error(getLoc(),
"expecting 'z' predication");
4534 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4535 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4538 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4546bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4548 if (!tryParseNeonVectorRegister(Operands))
4551 if (tryParseZTOperand(Operands).isSuccess())
4555 if (tryParseGPROperand<false>(Operands).isSuccess())
4561bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4562 bool HasELFModifier =
false;
4564 SMLoc Loc = getLexer().getLoc();
4566 HasELFModifier =
true;
4569 return TokError(
"expect relocation specifier in operand after ':'");
4571 std::string LowerCase = getTok().getIdentifier().lower();
4572 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4626 return TokError(
"expect relocation specifier in operand after ':'");
4630 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4634 if (getParser().parseExpression(ImmVal))
4641 if (
getContext().getAsmInfo()->hasSubsectionsViaSymbols()) {
4642 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4652 if (getParser().parsePrimaryExpr(Term, EndLoc))
4660ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4664 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4665 unsigned &ElementWidth) -> ParseStatus {
4666 StringRef
Name = getTok().getString();
4667 size_t DotPosition =
Name.find(
'.');
4675 StringRef
Tail =
Name.drop_front(DotPosition);
4676 const std::optional<std::pair<int, int>> &KindRes =
4680 "Expected the register to be followed by element width suffix");
4681 ElementWidth = KindRes->second;
4688 auto LCurly = getTok();
4693 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4699 if (getTok().getString().equals_insensitive(
"za")) {
4705 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4710 SMLoc TileLoc = getLoc();
4712 unsigned FirstReg, ElementWidth;
4713 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4714 if (!ParseRes.isSuccess()) {
4715 getLexer().UnLex(LCurly);
4719 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4721 unsigned PrevReg = FirstReg;
4723 SmallSet<unsigned, 8> DRegs;
4724 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4726 SmallSet<unsigned, 8> SeenRegs;
4727 SeenRegs.
insert(FirstReg);
4731 unsigned Reg, NextElementWidth;
4732 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4733 if (!ParseRes.isSuccess())
4737 if (ElementWidth != NextElementWidth)
4738 return Error(TileLoc,
"mismatched register size suffix");
4741 Warning(TileLoc,
"tile list not in ascending order");
4744 Warning(TileLoc,
"duplicate tile in list");
4747 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4756 unsigned RegMask = 0;
4757 for (
auto Reg : DRegs)
4761 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4766template <RegKind VectorKind>
4767ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4769 MCAsmParser &Parser = getParser();
4774 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4775 bool NoMatchIsError) -> ParseStatus {
4776 auto RegTok = getTok();
4777 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4778 if (ParseRes.isSuccess()) {
4785 RegTok.getString().equals_insensitive(
"zt0"))
4789 (ParseRes.isNoMatch() && NoMatchIsError &&
4790 !RegTok.getString().starts_with_insensitive(
"za")))
4791 return Error(Loc,
"vector register expected");
4796 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4798 auto LCurly = getTok();
4802 MCRegister FirstReg;
4803 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4807 if (ParseRes.isNoMatch())
4810 if (!ParseRes.isSuccess())
4813 MCRegister PrevReg = FirstReg;
4816 unsigned Stride = 1;
4818 SMLoc Loc = getLoc();
4822 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4823 if (!ParseRes.isSuccess())
4827 if (Kind != NextKind)
4828 return Error(Loc,
"mismatched register size suffix");
4831 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4833 if (Space == 0 || Space > 3)
4834 return Error(Loc,
"invalid number of vectors");
4839 bool HasCalculatedStride =
false;
4841 SMLoc Loc = getLoc();
4844 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4845 if (!ParseRes.isSuccess())
4849 if (Kind != NextKind)
4850 return Error(Loc,
"mismatched register size suffix");
4852 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4853 unsigned PrevRegVal =
4854 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4855 if (!HasCalculatedStride) {
4856 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4857 : (NumRegs - (PrevRegVal - RegVal));
4858 HasCalculatedStride =
true;
4862 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4863 return Error(Loc,
"registers must have the same sequential stride");
4874 return Error(S,
"invalid number of vectors");
4876 unsigned NumElements = 0;
4877 unsigned ElementWidth = 0;
4878 if (!
Kind.empty()) {
4880 std::tie(NumElements, ElementWidth) = *VK;
4883 Operands.
push_back(AArch64Operand::CreateVectorList(
4884 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4888 ParseStatus Res = tryParseVectorIndex(Operands);
4898bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4899 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4900 if (!ParseRes.isSuccess())
4903 return tryParseVectorIndex(Operands).isFailure();
4906ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4907 SMLoc StartLoc = getLoc();
4910 ParseStatus Res = tryParseScalarRegister(RegNum);
4915 Operands.
push_back(AArch64Operand::CreateReg(
4916 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4923 return Error(getLoc(),
"index must be absent or #0");
4925 const MCExpr *ImmVal;
4928 return Error(getLoc(),
"index must be absent or #0");
4930 Operands.
push_back(AArch64Operand::CreateReg(
4931 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4935ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
4936 SMLoc StartLoc = getLoc();
4937 const AsmToken &Tok = getTok();
4940 unsigned RegNum = matchRegisterNameAlias(Name, RegKind::LookupTable);
4945 Operands.
push_back(AArch64Operand::CreateReg(
4946 RegNum, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4952 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4953 const MCExpr *ImmVal;
4954 if (getParser().parseExpression(ImmVal))
4958 return TokError(
"immediate value expected for vector index");
4959 Operands.
push_back(AArch64Operand::CreateImm(
4963 if (parseOptionalMulOperand(Operands))
4968 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4973template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4974ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
4975 SMLoc StartLoc = getLoc();
4978 ParseStatus Res = tryParseScalarRegister(RegNum);
4984 Operands.
push_back(AArch64Operand::CreateReg(
4985 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4994 Res = tryParseOptionalShiftExtend(ExtOpnd);
4998 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4999 Operands.
push_back(AArch64Operand::CreateReg(
5000 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(),
getContext(), EqTy,
5001 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
5002 Ext->hasShiftExtendAmount()));
5007bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
5008 MCAsmParser &Parser = getParser();
5016 if (!getTok().getString().equals_insensitive(
"mul") ||
5017 !(NextIsVL || NextIsHash))
5021 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
5026 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
5036 const MCExpr *ImmVal;
5039 Operands.
push_back(AArch64Operand::CreateImm(
5046 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
5049bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
5050 StringRef &VecGroup) {
5051 MCAsmParser &Parser = getParser();
5052 auto Tok = Parser.
getTok();
5057 .Case(
"vgx2",
"vgx2")
5058 .Case(
"vgx4",
"vgx4")
5069bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
5070 auto Tok = getTok();
5088bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
5089 bool invertCondCode) {
5090 MCAsmParser &Parser = getParser();
5093 MatchOperandParserImpl(Operands, Mnemonic,
true);
5107 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
5109 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
5112 getLexer().UnLex(SavedTok);
5116 switch (getLexer().getKind()) {
5120 if (parseSymbolicImmVal(Expr))
5121 return Error(S,
"invalid operand");
5125 return parseOptionalShiftExtend(getTok());
5129 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5134 return parseOperand(Operands,
false,
false);
5137 if (!parseNeonVectorList(Operands))
5141 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5146 return parseOperand(Operands,
false,
false);
5151 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5153 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5158 return parseCondCode(Operands, invertCondCode);
5161 if (!parseRegister(Operands)) {
5163 AsmToken SavedTok = getTok();
5168 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5172 Res = tryParseOptionalShiftExtend(Operands);
5175 getLexer().UnLex(SavedTok);
5182 if (!parseOptionalMulOperand(Operands))
5187 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5189 return parseKeywordOperand(Operands);
5193 const MCExpr *IdVal, *
Term;
5195 if (getParser().parseExpression(IdVal))
5197 if (getParser().parseAtSpecifier(IdVal,
E))
5199 std::optional<MCBinaryExpr::Opcode> Opcode;
5205 if (getParser().parsePrimaryExpr(Term,
E))
5212 return parseOptionalShiftExtend(getTok());
5223 bool isNegative =
false;
5235 const AsmToken &Tok = getTok();
5238 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5239 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5240 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5241 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5242 return TokError(
"unexpected floating point literal");
5243 else if (IntVal != 0 || isNegative)
5244 return TokError(
"expected floating-point constant #0.0");
5252 const MCExpr *ImmVal;
5253 if (parseSymbolicImmVal(ImmVal))
5260 return parseOptionalShiftExtend(Tok);
5263 SMLoc Loc = getLoc();
5264 if (Mnemonic !=
"ldr")
5265 return TokError(
"unexpected token in operand");
5267 const MCExpr *SubExprVal;
5268 if (getParser().parseExpression(SubExprVal))
5271 if (Operands.
size() < 2 ||
5272 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5273 return Error(Loc,
"Only valid when first operand is register");
5276 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5284 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5289 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5290 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5291 Operands.
push_back(AArch64Operand::CreateImm(
5295 ShiftAmt,
true, S,
E, Ctx));
5298 APInt Simm = APInt(64, Imm << ShiftAmt);
5301 return Error(Loc,
"Immediate too large for register");
5304 const MCExpr *CPLoc =
5305 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5306 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5312bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5313 const MCExpr *Expr =
nullptr;
5315 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5318 if (check(!
Value, L,
"expected constant expression"))
5320 Out =
Value->getValue();
5324bool AArch64AsmParser::parseComma() {
5332bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5336 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5341 unsigned RangeEnd =
Last;
5342 if (
Base == AArch64::X0) {
5343 if (
Last == AArch64::FP) {
5344 RangeEnd = AArch64::X28;
5345 if (
Reg == AArch64::FP) {
5350 if (
Last == AArch64::LR) {
5351 RangeEnd = AArch64::X28;
5352 if (
Reg == AArch64::FP) {
5355 }
else if (
Reg == AArch64::LR) {
5363 Twine(
"expected register in range ") +
5371bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5372 const MCParsedAsmOperand &Op2)
const {
5373 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5374 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5376 if (AOp1.isVectorList() && AOp2.isVectorList())
5377 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5378 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5379 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5381 if (!AOp1.isReg() || !AOp2.isReg())
5384 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5385 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5388 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5389 "Testing equality of non-scalar registers not supported");
5392 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5394 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5396 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5398 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5405bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &
Info,
5406 StringRef Name, SMLoc NameLoc,
5408 Name = StringSwitch<StringRef>(
Name.lower())
5409 .Case(
"beq",
"b.eq")
5410 .Case(
"bne",
"b.ne")
5411 .Case(
"bhs",
"b.hs")
5412 .Case(
"bcs",
"b.cs")
5413 .Case(
"blo",
"b.lo")
5414 .Case(
"bcc",
"b.cc")
5415 .Case(
"bmi",
"b.mi")
5416 .Case(
"bpl",
"b.pl")
5417 .Case(
"bvs",
"b.vs")
5418 .Case(
"bvc",
"b.vc")
5419 .Case(
"bhi",
"b.hi")
5420 .Case(
"bls",
"b.ls")
5421 .Case(
"bge",
"b.ge")
5422 .Case(
"blt",
"b.lt")
5423 .Case(
"bgt",
"b.gt")
5424 .Case(
"ble",
"b.le")
5425 .Case(
"bal",
"b.al")
5426 .Case(
"bnv",
"b.nv")
5431 getTok().getIdentifier().lower() ==
".req") {
5432 parseDirectiveReq(Name, NameLoc);
5440 StringRef Head =
Name.slice(Start,
Next);
5444 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5445 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5446 Head ==
"mlbi" || Head ==
"gic" || Head ==
"gsb")
5447 return parseSysAlias(Head, NameLoc, Operands);
5451 return parseSyslAlias(Head, NameLoc, Operands);
5454 if (Head ==
"tlbip")
5455 return parseSyspAlias(Head, NameLoc, Operands);
5464 Head =
Name.slice(Start + 1,
Next);
5468 std::string Suggestion;
5471 std::string Msg =
"invalid condition code";
5472 if (!Suggestion.empty())
5473 Msg +=
", did you mean " + Suggestion +
"?";
5474 return Error(SuffixLoc, Msg);
5479 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5489 Operands.
push_back(AArch64Operand::CreateToken(
5495 bool condCodeFourthOperand =
5496 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5497 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5498 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5506 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5507 bool condCodeThirdOperand =
5508 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5516 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5517 (
N == 3 && condCodeThirdOperand) ||
5518 (
N == 2 && condCodeSecondOperand),
5519 condCodeSecondOperand || condCodeThirdOperand)) {
5539 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5542 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5545 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5558 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5559 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5560 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5561 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5562 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5563 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5564 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5570bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5571 SmallVectorImpl<SMLoc> &Loc) {
5572 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5573 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5579 PrefixInfo
Prefix = NextPrefix;
5580 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5592 return Error(IDLoc,
"instruction is unpredictable when following a"
5593 " movprfx, suggest replacing movprfx with mov");
5597 return Error(Loc[0],
"instruction is unpredictable when following a"
5598 " movprfx writing to a different destination");
5605 return Error(Loc[0],
"instruction is unpredictable when following a"
5606 " movprfx and destination also used as non-destructive"
5610 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5611 if (
Prefix.isPredicated()) {
5625 return Error(IDLoc,
"instruction is unpredictable when following a"
5626 " predicated movprfx, suggest using unpredicated movprfx");
5630 return Error(IDLoc,
"instruction is unpredictable when following a"
5631 " predicated movprfx using a different general predicate");
5635 return Error(IDLoc,
"instruction is unpredictable when following a"
5636 " predicated movprfx with a different element size");
5642 if (IsWindowsArm64EC) {
5648 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5649 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5650 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5651 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5652 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5653 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5654 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5655 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5656 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5657 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5659 " is disallowed on ARM64EC.");
5669 case AArch64::LDPSWpre:
5670 case AArch64::LDPWpost:
5671 case AArch64::LDPWpre:
5672 case AArch64::LDPXpost:
5673 case AArch64::LDPXpre: {
5678 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5679 "is also a destination");
5681 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5682 "is also a destination");
5685 case AArch64::LDR_ZA:
5686 case AArch64::STR_ZA: {
5689 return Error(Loc[1],
5690 "unpredictable instruction, immediate and offset mismatch.");
5693 case AArch64::LDPDi:
5694 case AArch64::LDPQi:
5695 case AArch64::LDPSi:
5696 case AArch64::LDPSWi:
5697 case AArch64::LDPWi:
5698 case AArch64::LDPXi: {
5702 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5705 case AArch64::LDPDpost:
5706 case AArch64::LDPDpre:
5707 case AArch64::LDPQpost:
5708 case AArch64::LDPQpre:
5709 case AArch64::LDPSpost:
5710 case AArch64::LDPSpre:
5711 case AArch64::LDPSWpost: {
5715 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5718 case AArch64::STPDpost:
5719 case AArch64::STPDpre:
5720 case AArch64::STPQpost:
5721 case AArch64::STPQpre:
5722 case AArch64::STPSpost:
5723 case AArch64::STPSpre:
5724 case AArch64::STPWpost:
5725 case AArch64::STPWpre:
5726 case AArch64::STPXpost:
5727 case AArch64::STPXpre: {
5732 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5733 "is also a source");
5735 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5736 "is also a source");
5739 case AArch64::LDRBBpre:
5740 case AArch64::LDRBpre:
5741 case AArch64::LDRHHpre:
5742 case AArch64::LDRHpre:
5743 case AArch64::LDRSBWpre:
5744 case AArch64::LDRSBXpre:
5745 case AArch64::LDRSHWpre:
5746 case AArch64::LDRSHXpre:
5747 case AArch64::LDRSWpre:
5748 case AArch64::LDRWpre:
5749 case AArch64::LDRXpre:
5750 case AArch64::LDRBBpost:
5751 case AArch64::LDRBpost:
5752 case AArch64::LDRHHpost:
5753 case AArch64::LDRHpost:
5754 case AArch64::LDRSBWpost:
5755 case AArch64::LDRSBXpost:
5756 case AArch64::LDRSHWpost:
5757 case AArch64::LDRSHXpost:
5758 case AArch64::LDRSWpost:
5759 case AArch64::LDRWpost:
5760 case AArch64::LDRXpost: {
5764 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5765 "is also a source");
5768 case AArch64::STRBBpost:
5769 case AArch64::STRBpost:
5770 case AArch64::STRHHpost:
5771 case AArch64::STRHpost:
5772 case AArch64::STRWpost:
5773 case AArch64::STRXpost:
5774 case AArch64::STRBBpre:
5775 case AArch64::STRBpre:
5776 case AArch64::STRHHpre:
5777 case AArch64::STRHpre:
5778 case AArch64::STRWpre:
5779 case AArch64::STRXpre: {
5783 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5784 "is also a source");
5787 case AArch64::STXRB:
5788 case AArch64::STXRH:
5789 case AArch64::STXRW:
5790 case AArch64::STXRX:
5791 case AArch64::STLXRB:
5792 case AArch64::STLXRH:
5793 case AArch64::STLXRW:
5794 case AArch64::STLXRX: {
5800 return Error(Loc[0],
5801 "unpredictable STXR instruction, status is also a source");
5804 case AArch64::STXPW:
5805 case AArch64::STXPX:
5806 case AArch64::STLXPW:
5807 case AArch64::STLXPX: {
5814 return Error(Loc[0],
5815 "unpredictable STXP instruction, status is also a source");
5818 case AArch64::LDRABwriteback:
5819 case AArch64::LDRAAwriteback: {
5823 return Error(Loc[0],
5824 "unpredictable LDRA instruction, writeback base"
5825 " is also a destination");
5832 case AArch64::CPYFP:
5833 case AArch64::CPYFPWN:
5834 case AArch64::CPYFPRN:
5835 case AArch64::CPYFPN:
5836 case AArch64::CPYFPWT:
5837 case AArch64::CPYFPWTWN:
5838 case AArch64::CPYFPWTRN:
5839 case AArch64::CPYFPWTN:
5840 case AArch64::CPYFPRT:
5841 case AArch64::CPYFPRTWN:
5842 case AArch64::CPYFPRTRN:
5843 case AArch64::CPYFPRTN:
5844 case AArch64::CPYFPT:
5845 case AArch64::CPYFPTWN:
5846 case AArch64::CPYFPTRN:
5847 case AArch64::CPYFPTN:
5848 case AArch64::CPYFM:
5849 case AArch64::CPYFMWN:
5850 case AArch64::CPYFMRN:
5851 case AArch64::CPYFMN:
5852 case AArch64::CPYFMWT:
5853 case AArch64::CPYFMWTWN:
5854 case AArch64::CPYFMWTRN:
5855 case AArch64::CPYFMWTN:
5856 case AArch64::CPYFMRT:
5857 case AArch64::CPYFMRTWN:
5858 case AArch64::CPYFMRTRN:
5859 case AArch64::CPYFMRTN:
5860 case AArch64::CPYFMT:
5861 case AArch64::CPYFMTWN:
5862 case AArch64::CPYFMTRN:
5863 case AArch64::CPYFMTN:
5864 case AArch64::CPYFE:
5865 case AArch64::CPYFEWN:
5866 case AArch64::CPYFERN:
5867 case AArch64::CPYFEN:
5868 case AArch64::CPYFEWT:
5869 case AArch64::CPYFEWTWN:
5870 case AArch64::CPYFEWTRN:
5871 case AArch64::CPYFEWTN:
5872 case AArch64::CPYFERT:
5873 case AArch64::CPYFERTWN:
5874 case AArch64::CPYFERTRN:
5875 case AArch64::CPYFERTN:
5876 case AArch64::CPYFET:
5877 case AArch64::CPYFETWN:
5878 case AArch64::CPYFETRN:
5879 case AArch64::CPYFETN:
5881 case AArch64::CPYPWN:
5882 case AArch64::CPYPRN:
5883 case AArch64::CPYPN:
5884 case AArch64::CPYPWT:
5885 case AArch64::CPYPWTWN:
5886 case AArch64::CPYPWTRN:
5887 case AArch64::CPYPWTN:
5888 case AArch64::CPYPRT:
5889 case AArch64::CPYPRTWN:
5890 case AArch64::CPYPRTRN:
5891 case AArch64::CPYPRTN:
5892 case AArch64::CPYPT:
5893 case AArch64::CPYPTWN:
5894 case AArch64::CPYPTRN:
5895 case AArch64::CPYPTN:
5897 case AArch64::CPYMWN:
5898 case AArch64::CPYMRN:
5899 case AArch64::CPYMN:
5900 case AArch64::CPYMWT:
5901 case AArch64::CPYMWTWN:
5902 case AArch64::CPYMWTRN:
5903 case AArch64::CPYMWTN:
5904 case AArch64::CPYMRT:
5905 case AArch64::CPYMRTWN:
5906 case AArch64::CPYMRTRN:
5907 case AArch64::CPYMRTN:
5908 case AArch64::CPYMT:
5909 case AArch64::CPYMTWN:
5910 case AArch64::CPYMTRN:
5911 case AArch64::CPYMTN:
5913 case AArch64::CPYEWN:
5914 case AArch64::CPYERN:
5915 case AArch64::CPYEN:
5916 case AArch64::CPYEWT:
5917 case AArch64::CPYEWTWN:
5918 case AArch64::CPYEWTRN:
5919 case AArch64::CPYEWTN:
5920 case AArch64::CPYERT:
5921 case AArch64::CPYERTWN:
5922 case AArch64::CPYERTRN:
5923 case AArch64::CPYERTN:
5924 case AArch64::CPYET:
5925 case AArch64::CPYETWN:
5926 case AArch64::CPYETRN:
5927 case AArch64::CPYETN: {
5935 return Error(Loc[0],
5936 "invalid CPY instruction, Xd_wb and Xd do not match");
5938 return Error(Loc[0],
5939 "invalid CPY instruction, Xs_wb and Xs do not match");
5941 return Error(Loc[0],
5942 "invalid CPY instruction, Xn_wb and Xn do not match");
5944 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5945 " registers are the same");
5947 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5948 " registers are the same");
5950 return Error(Loc[0],
"invalid CPY instruction, source and size"
5951 " registers are the same");
5955 case AArch64::SETPT:
5956 case AArch64::SETPN:
5957 case AArch64::SETPTN:
5959 case AArch64::SETMT:
5960 case AArch64::SETMN:
5961 case AArch64::SETMTN:
5963 case AArch64::SETET:
5964 case AArch64::SETEN:
5965 case AArch64::SETETN:
5966 case AArch64::SETGP:
5967 case AArch64::SETGPT:
5968 case AArch64::SETGPN:
5969 case AArch64::SETGPTN:
5970 case AArch64::SETGM:
5971 case AArch64::SETGMT:
5972 case AArch64::SETGMN:
5973 case AArch64::SETGMTN:
5974 case AArch64::MOPSSETGE:
5975 case AArch64::MOPSSETGET:
5976 case AArch64::MOPSSETGEN:
5977 case AArch64::MOPSSETGETN: {
5984 return Error(Loc[0],
5985 "invalid SET instruction, Xd_wb and Xd do not match");
5987 return Error(Loc[0],
5988 "invalid SET instruction, Xn_wb and Xn do not match");
5990 return Error(Loc[0],
"invalid SET instruction, destination and size"
5991 " registers are the same");
5993 return Error(Loc[0],
"invalid SET instruction, destination and source"
5994 " registers are the same");
5996 return Error(Loc[0],
"invalid SET instruction, source and size"
5997 " registers are the same");
6006 case AArch64::ADDSWri:
6007 case AArch64::ADDSXri:
6008 case AArch64::ADDWri:
6009 case AArch64::ADDXri:
6010 case AArch64::SUBSWri:
6011 case AArch64::SUBSXri:
6012 case AArch64::SUBWri:
6013 case AArch64::SUBXri: {
6021 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
6046 return Error(Loc.
back(),
"invalid immediate expression");
6059 unsigned VariantID = 0);
6061bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
6065 case Match_InvalidTiedOperand: {
6066 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
6067 if (
Op.isVectorList())
6068 return Error(
Loc,
"operand must match destination register list");
6070 assert(
Op.isReg() &&
"Unexpected operand type");
6071 switch (
Op.getRegEqualityTy()) {
6072 case RegConstraintEqualityTy::EqualsSubReg:
6073 return Error(
Loc,
"operand must be 64-bit form of destination register");
6074 case RegConstraintEqualityTy::EqualsSuperReg:
6075 return Error(
Loc,
"operand must be 32-bit form of destination register");
6076 case RegConstraintEqualityTy::EqualsReg:
6077 return Error(
Loc,
"operand must match destination register");
6081 case Match_MissingFeature:
6083 "instruction requires a CPU feature not currently enabled");
6084 case Match_InvalidOperand:
6085 return Error(Loc,
"invalid operand for instruction");
6086 case Match_InvalidSuffix:
6087 return Error(Loc,
"invalid type suffix for instruction");
6088 case Match_InvalidCondCode:
6089 return Error(Loc,
"expected AArch64 condition code");
6090 case Match_AddSubRegExtendSmall:
6092 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
6093 case Match_AddSubRegExtendLarge:
6095 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
6096 case Match_AddSubSecondSource:
6098 "expected compatible register, symbol or integer in range [0, 4095]");
6099 case Match_LogicalSecondSource:
6100 return Error(Loc,
"expected compatible register or logical immediate");
6101 case Match_InvalidMovImm32Shift:
6102 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
6103 case Match_InvalidMovImm64Shift:
6104 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
6105 case Match_AddSubRegShift32:
6107 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
6108 case Match_AddSubRegShift64:
6110 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
6111 case Match_InvalidFPImm:
6113 "expected compatible register or floating-point constant");
6114 case Match_InvalidMemoryIndexedSImm6:
6115 return Error(Loc,
"index must be an integer in range [-32, 31].");
6116 case Match_InvalidMemoryIndexedSImm5:
6117 return Error(Loc,
"index must be an integer in range [-16, 15].");
6118 case Match_InvalidMemoryIndexed1SImm4:
6119 return Error(Loc,
"index must be an integer in range [-8, 7].");
6120 case Match_InvalidMemoryIndexed2SImm4:
6121 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6122 case Match_InvalidMemoryIndexed3SImm4:
6123 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6124 case Match_InvalidMemoryIndexed4SImm4:
6125 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6126 case Match_InvalidMemoryIndexed16SImm4:
6127 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6128 case Match_InvalidMemoryIndexed32SImm4:
6129 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6130 case Match_InvalidMemoryIndexed1SImm6:
6131 return Error(Loc,
"index must be an integer in range [-32, 31].");
6132 case Match_InvalidMemoryIndexedSImm8:
6133 return Error(Loc,
"index must be an integer in range [-128, 127].");
6134 case Match_InvalidMemoryIndexedSImm9:
6135 return Error(Loc,
"index must be an integer in range [-256, 255].");
6136 case Match_InvalidMemoryIndexed16SImm9:
6137 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6138 case Match_InvalidMemoryIndexed8SImm10:
6139 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6140 case Match_InvalidMemoryIndexed4SImm7:
6141 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6142 case Match_InvalidMemoryIndexed8SImm7:
6143 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6144 case Match_InvalidMemoryIndexed16SImm7:
6145 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6146 case Match_InvalidMemoryIndexed8UImm5:
6147 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6148 case Match_InvalidMemoryIndexed8UImm3:
6149 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6150 case Match_InvalidMemoryIndexed4UImm5:
6151 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6152 case Match_InvalidMemoryIndexed2UImm5:
6153 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6154 case Match_InvalidMemoryIndexed8UImm6:
6155 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6156 case Match_InvalidMemoryIndexed16UImm6:
6157 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6158 case Match_InvalidMemoryIndexed4UImm6:
6159 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6160 case Match_InvalidMemoryIndexed2UImm6:
6161 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6162 case Match_InvalidMemoryIndexed1UImm6:
6163 return Error(Loc,
"index must be in range [0, 63].");
6164 case Match_InvalidMemoryWExtend8:
6166 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6167 case Match_InvalidMemoryWExtend16:
6169 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6170 case Match_InvalidMemoryWExtend32:
6172 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6173 case Match_InvalidMemoryWExtend64:
6175 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6176 case Match_InvalidMemoryWExtend128:
6178 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6179 case Match_InvalidMemoryXExtend8:
6181 "expected 'lsl' or 'sxtx' with optional shift of #0");
6182 case Match_InvalidMemoryXExtend16:
6184 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6185 case Match_InvalidMemoryXExtend32:
6187 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6188 case Match_InvalidMemoryXExtend64:
6190 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6191 case Match_InvalidMemoryXExtend128:
6193 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6194 case Match_InvalidMemoryIndexed1:
6195 return Error(Loc,
"index must be an integer in range [0, 4095].");
6196 case Match_InvalidMemoryIndexed2:
6197 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6198 case Match_InvalidMemoryIndexed4:
6199 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6200 case Match_InvalidMemoryIndexed8:
6201 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6202 case Match_InvalidMemoryIndexed16:
6203 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6204 case Match_InvalidImm0_0:
6205 return Error(Loc,
"immediate must be 0.");
6206 case Match_InvalidImm0_1:
6207 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6208 case Match_InvalidImm0_3:
6209 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6210 case Match_InvalidImm0_7:
6211 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6212 case Match_InvalidImm0_15:
6213 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6214 case Match_InvalidImm0_31:
6215 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6216 case Match_InvalidImm0_63:
6217 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6218 case Match_InvalidImm0_127:
6219 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6220 case Match_InvalidImm0_255:
6221 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6222 case Match_InvalidImm0_65535:
6223 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6224 case Match_InvalidImm1_8:
6225 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6226 case Match_InvalidImm1_16:
6227 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6228 case Match_InvalidImm1_32:
6229 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6230 case Match_InvalidImm1_64:
6231 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6232 case Match_InvalidImmM1_62:
6233 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6234 case Match_InvalidMemoryIndexedRange2UImm0:
6235 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6236 case Match_InvalidMemoryIndexedRange2UImm1:
6237 return Error(Loc,
"vector select offset must be an immediate range of the "
6238 "form <immf>:<imml>, where the first "
6239 "immediate is a multiple of 2 in the range [0, 2], and "
6240 "the second immediate is immf + 1.");
6241 case Match_InvalidMemoryIndexedRange2UImm2:
6242 case Match_InvalidMemoryIndexedRange2UImm3:
6245 "vector select offset must be an immediate range of the form "
6247 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6249 "depending on the instruction, and the second immediate is immf + 1.");
6250 case Match_InvalidMemoryIndexedRange4UImm0:
6251 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6252 case Match_InvalidMemoryIndexedRange4UImm1:
6253 case Match_InvalidMemoryIndexedRange4UImm2:
6256 "vector select offset must be an immediate range of the form "
6258 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6260 "depending on the instruction, and the second immediate is immf + 3.");
6261 case Match_InvalidSVEAddSubImm8:
6262 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6263 " with a shift amount of 0");
6264 case Match_InvalidSVEAddSubImm16:
6265 case Match_InvalidSVEAddSubImm32:
6266 case Match_InvalidSVEAddSubImm64:
6267 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6268 "multiple of 256 in range [256, 65280]");
6269 case Match_InvalidSVECpyImm8:
6270 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6271 " with a shift amount of 0");
6272 case Match_InvalidSVECpyImm16:
6273 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6274 "multiple of 256 in range [-32768, 65280]");
6275 case Match_InvalidSVECpyImm32:
6276 case Match_InvalidSVECpyImm64:
6277 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6278 "multiple of 256 in range [-32768, 32512]");
6279 case Match_InvalidIndexRange0_0:
6280 return Error(Loc,
"expected lane specifier '[0]'");
6281 case Match_InvalidIndexRange1_1:
6282 return Error(Loc,
"expected lane specifier '[1]'");
6283 case Match_InvalidIndexRange0_15:
6284 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6285 case Match_InvalidIndexRange0_7:
6286 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6287 case Match_InvalidIndexRange0_3:
6288 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6289 case Match_InvalidIndexRange0_1:
6290 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6291 case Match_InvalidSVEIndexRange0_63:
6292 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6293 case Match_InvalidSVEIndexRange0_31:
6294 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6295 case Match_InvalidSVEIndexRange0_15:
6296 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6297 case Match_InvalidSVEIndexRange0_7:
6298 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6299 case Match_InvalidSVEIndexRange0_3:
6300 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6301 case Match_InvalidLabel:
6302 return Error(Loc,
"expected label or encodable integer pc offset");
6304 return Error(Loc,
"expected readable system register");
6306 case Match_InvalidSVCR:
6307 return Error(Loc,
"expected writable system register or pstate");
6308 case Match_InvalidComplexRotationEven:
6309 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6310 case Match_InvalidComplexRotationOdd:
6311 return Error(Loc,
"complex rotation must be 90 or 270.");
6312 case Match_MnemonicFail: {
6314 ((AArch64Operand &)*Operands[0]).
getToken(),
6315 ComputeAvailableFeatures(STI->getFeatureBits()));
6316 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6318 case Match_InvalidGPR64shifted8:
6319 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6320 case Match_InvalidGPR64shifted16:
6321 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6322 case Match_InvalidGPR64shifted32:
6323 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6324 case Match_InvalidGPR64shifted64:
6325 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6326 case Match_InvalidGPR64shifted128:
6328 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6329 case Match_InvalidGPR64NoXZRshifted8:
6330 return Error(Loc,
"register must be x0..x30 without shift");
6331 case Match_InvalidGPR64NoXZRshifted16:
6332 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6333 case Match_InvalidGPR64NoXZRshifted32:
6334 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6335 case Match_InvalidGPR64NoXZRshifted64:
6336 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6337 case Match_InvalidGPR64NoXZRshifted128:
6338 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6339 case Match_InvalidZPR32UXTW8:
6340 case Match_InvalidZPR32SXTW8:
6341 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6342 case Match_InvalidZPR32UXTW16:
6343 case Match_InvalidZPR32SXTW16:
6344 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6345 case Match_InvalidZPR32UXTW32:
6346 case Match_InvalidZPR32SXTW32:
6347 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6348 case Match_InvalidZPR32UXTW64:
6349 case Match_InvalidZPR32SXTW64:
6350 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6351 case Match_InvalidZPR64UXTW8:
6352 case Match_InvalidZPR64SXTW8:
6353 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6354 case Match_InvalidZPR64UXTW16:
6355 case Match_InvalidZPR64SXTW16:
6356 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6357 case Match_InvalidZPR64UXTW32:
6358 case Match_InvalidZPR64SXTW32:
6359 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6360 case Match_InvalidZPR64UXTW64:
6361 case Match_InvalidZPR64SXTW64:
6362 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6363 case Match_InvalidZPR32LSL8:
6364 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6365 case Match_InvalidZPR32LSL16:
6366 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6367 case Match_InvalidZPR32LSL32:
6368 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6369 case Match_InvalidZPR32LSL64:
6370 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6371 case Match_InvalidZPR64LSL8:
6372 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6373 case Match_InvalidZPR64LSL16:
6374 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6375 case Match_InvalidZPR64LSL32:
6376 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6377 case Match_InvalidZPR64LSL64:
6378 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6379 case Match_InvalidZPR0:
6380 return Error(Loc,
"expected register without element width suffix");
6381 case Match_InvalidZPR8:
6382 case Match_InvalidZPR16:
6383 case Match_InvalidZPR32:
6384 case Match_InvalidZPR64:
6385 case Match_InvalidZPR128:
6386 return Error(Loc,
"invalid element width");
6387 case Match_InvalidZPR_3b8:
6388 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6389 case Match_InvalidZPR_3b16:
6390 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6391 case Match_InvalidZPR_3b32:
6392 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6393 case Match_InvalidZPR_4b8:
6395 "Invalid restricted vector register, expected z0.b..z15.b");
6396 case Match_InvalidZPR_4b16:
6397 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6398 case Match_InvalidZPR_4b32:
6399 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6400 case Match_InvalidZPR_4b64:
6401 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6402 case Match_InvalidZPRMul2_Lo8:
6403 return Error(Loc,
"Invalid restricted vector register, expected even "
6404 "register in z0.b..z14.b");
6405 case Match_InvalidZPRMul2_Hi8:
6406 return Error(Loc,
"Invalid restricted vector register, expected even "
6407 "register in z16.b..z30.b");
6408 case Match_InvalidZPRMul2_Lo16:
6409 return Error(Loc,
"Invalid restricted vector register, expected even "
6410 "register in z0.h..z14.h");
6411 case Match_InvalidZPRMul2_Hi16:
6412 return Error(Loc,
"Invalid restricted vector register, expected even "
6413 "register in z16.h..z30.h");
6414 case Match_InvalidZPRMul2_Lo32:
6415 return Error(Loc,
"Invalid restricted vector register, expected even "
6416 "register in z0.s..z14.s");
6417 case Match_InvalidZPRMul2_Hi32:
6418 return Error(Loc,
"Invalid restricted vector register, expected even "
6419 "register in z16.s..z30.s");
6420 case Match_InvalidZPRMul2_Lo64:
6421 return Error(Loc,
"Invalid restricted vector register, expected even "
6422 "register in z0.d..z14.d");
6423 case Match_InvalidZPRMul2_Hi64:
6424 return Error(Loc,
"Invalid restricted vector register, expected even "
6425 "register in z16.d..z30.d");
6426 case Match_InvalidZPR_K0:
6427 return Error(Loc,
"invalid restricted vector register, expected register "
6428 "in z20..z23 or z28..z31");
6429 case Match_InvalidSVEPattern:
6430 return Error(Loc,
"invalid predicate pattern");
6431 case Match_InvalidSVEPPRorPNRAnyReg:
6432 case Match_InvalidSVEPPRorPNRBReg:
6433 case Match_InvalidSVEPredicateAnyReg:
6434 case Match_InvalidSVEPredicateBReg:
6435 case Match_InvalidSVEPredicateHReg:
6436 case Match_InvalidSVEPredicateSReg:
6437 case Match_InvalidSVEPredicateDReg:
6438 return Error(Loc,
"invalid predicate register.");
6439 case Match_InvalidSVEPredicate3bAnyReg:
6440 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6441 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6442 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6443 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6444 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6445 return Error(Loc,
"Invalid predicate register, expected PN in range "
6446 "pn8..pn15 with element suffix.");
6447 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6448 return Error(Loc,
"invalid restricted predicate-as-counter register "
6449 "expected pn8..pn15");
6450 case Match_InvalidSVEPNPredicateBReg:
6451 case Match_InvalidSVEPNPredicateHReg:
6452 case Match_InvalidSVEPNPredicateSReg:
6453 case Match_InvalidSVEPNPredicateDReg:
6454 return Error(Loc,
"Invalid predicate register, expected PN in range "
6455 "pn0..pn15 with element suffix.");
6456 case Match_InvalidSVEVecLenSpecifier:
6457 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6458 case Match_InvalidSVEPredicateListMul2x8:
6459 case Match_InvalidSVEPredicateListMul2x16:
6460 case Match_InvalidSVEPredicateListMul2x32:
6461 case Match_InvalidSVEPredicateListMul2x64:
6462 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6463 "predicate registers, where the first vector is a multiple of 2 "
6464 "and with correct element type");
6465 case Match_InvalidSVEExactFPImmOperandHalfOne:
6466 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6467 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6468 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6469 case Match_InvalidSVEExactFPImmOperandZeroOne:
6470 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6471 case Match_InvalidMatrixTileVectorH8:
6472 case Match_InvalidMatrixTileVectorV8:
6473 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6474 case Match_InvalidMatrixTileVectorH16:
6475 case Match_InvalidMatrixTileVectorV16:
6477 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6478 case Match_InvalidMatrixTileVectorH32:
6479 case Match_InvalidMatrixTileVectorV32:
6481 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6482 case Match_InvalidMatrixTileVectorH64:
6483 case Match_InvalidMatrixTileVectorV64:
6485 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6486 case Match_InvalidMatrixTileVectorH128:
6487 case Match_InvalidMatrixTileVectorV128:
6489 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6490 case Match_InvalidMatrixTile16:
6491 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6492 case Match_InvalidMatrixTile32:
6493 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6494 case Match_InvalidMatrixTile64:
6495 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6496 case Match_InvalidMatrix:
6497 return Error(Loc,
"invalid matrix operand, expected za");
6498 case Match_InvalidMatrix8:
6499 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6500 case Match_InvalidMatrix16:
6501 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6502 case Match_InvalidMatrix32:
6503 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6504 case Match_InvalidMatrix64:
6505 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6506 case Match_InvalidMatrixIndexGPR32_12_15:
6507 return Error(Loc,
"operand must be a register in range [w12, w15]");
6508 case Match_InvalidMatrixIndexGPR32_8_11:
6509 return Error(Loc,
"operand must be a register in range [w8, w11]");
6510 case Match_InvalidSVEVectorList2x8Mul2:
6511 case Match_InvalidSVEVectorList2x16Mul2:
6512 case Match_InvalidSVEVectorList2x32Mul2:
6513 case Match_InvalidSVEVectorList2x64Mul2:
6514 case Match_InvalidSVEVectorList2x128Mul2:
6515 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6516 "SVE vectors, where the first vector is a multiple of 2 "
6517 "and with matching element types");
6518 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6519 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6520 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6521 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6522 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6523 "SVE vectors in the range z0-z14, where the first vector "
6524 "is a multiple of 2 "
6525 "and with matching element types");
6526 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6527 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6528 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6529 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6531 "Invalid vector list, expected list with 2 consecutive "
6532 "SVE vectors in the range z16-z30, where the first vector "
6533 "is a multiple of 2 "
6534 "and with matching element types");
6535 case Match_InvalidSVEVectorList4x8Mul4:
6536 case Match_InvalidSVEVectorList4x16Mul4:
6537 case Match_InvalidSVEVectorList4x32Mul4:
6538 case Match_InvalidSVEVectorList4x64Mul4:
6539 case Match_InvalidSVEVectorList4x128Mul4:
6540 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6541 "SVE vectors, where the first vector is a multiple of 4 "
6542 "and with matching element types");
6543 case Match_InvalidLookupTable:
6544 return Error(Loc,
"Invalid lookup table, expected zt0");
6545 case Match_InvalidSVEVectorListStrided2x8:
6546 case Match_InvalidSVEVectorListStrided2x16:
6547 case Match_InvalidSVEVectorListStrided2x32:
6548 case Match_InvalidSVEVectorListStrided2x64:
6551 "Invalid vector list, expected list with each SVE vector in the list "
6552 "8 registers apart, and the first register in the range [z0, z7] or "
6553 "[z16, z23] and with correct element type");
6554 case Match_InvalidSVEVectorListStrided4x8:
6555 case Match_InvalidSVEVectorListStrided4x16:
6556 case Match_InvalidSVEVectorListStrided4x32:
6557 case Match_InvalidSVEVectorListStrided4x64:
6560 "Invalid vector list, expected list with each SVE vector in the list "
6561 "4 registers apart, and the first register in the range [z0, z3] or "
6562 "[z16, z19] and with correct element type");
6563 case Match_AddSubLSLImm3ShiftLarge:
6565 "expected 'lsl' with optional integer in range [0, 7]");
6573bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6577 bool MatchingInlineAsm) {
6578 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6579 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6580 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6583 unsigned NumOperands = Operands.
size();
6585 if (NumOperands == 4 && Tok ==
"lsl") {
6586 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6587 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6588 if (Op2.isScalarReg() && Op3.isImm()) {
6594 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6596 NewOp3Val = (32 - Op3Val) & 0x1f;
6597 NewOp4Val = 31 - Op3Val;
6599 NewOp3Val = (64 - Op3Val) & 0x3f;
6600 NewOp4Val = 63 - Op3Val;
6607 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6608 Operands.
push_back(AArch64Operand::CreateImm(
6609 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6610 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6614 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6616 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6617 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6618 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6620 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6624 if (LSBCE && WidthCE) {
6626 uint64_t Width = WidthCE->
getValue();
6628 uint64_t RegWidth = 0;
6629 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6635 if (LSB >= RegWidth)
6636 return Error(LSBOp.getStartLoc(),
6637 "expected integer in range [0, 31]");
6638 if (Width < 1 || Width > RegWidth)
6639 return Error(WidthOp.getStartLoc(),
6640 "expected integer in range [1, 32]");
6644 ImmR = (32 - LSB) & 0x1f;
6646 ImmR = (64 - LSB) & 0x3f;
6648 uint64_t ImmS = Width - 1;
6650 if (ImmR != 0 && ImmS >= ImmR)
6651 return Error(WidthOp.getStartLoc(),
6652 "requested insert overflows register");
6657 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6658 Operands[2] = AArch64Operand::CreateReg(
6659 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6661 Operands[3] = AArch64Operand::CreateImm(
6662 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6664 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6668 }
else if (NumOperands == 5) {
6671 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6672 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6673 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6674 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6676 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6680 if (Op3CE && Op4CE) {
6681 uint64_t Op3Val = Op3CE->
getValue();
6682 uint64_t Op4Val = Op4CE->
getValue();
6684 uint64_t RegWidth = 0;
6685 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6691 if (Op3Val >= RegWidth)
6692 return Error(Op3.getStartLoc(),
6693 "expected integer in range [0, 31]");
6694 if (Op4Val < 1 || Op4Val > RegWidth)
6695 return Error(Op4.getStartLoc(),
6696 "expected integer in range [1, 32]");
6698 uint64_t NewOp3Val = 0;
6700 NewOp3Val = (32 - Op3Val) & 0x1f;
6702 NewOp3Val = (64 - Op3Val) & 0x3f;
6704 uint64_t NewOp4Val = Op4Val - 1;
6706 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6707 return Error(Op4.getStartLoc(),
6708 "requested insert overflows register");
6710 const MCExpr *NewOp3 =
6712 const MCExpr *NewOp4 =
6714 Operands[3] = AArch64Operand::CreateImm(
6715 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6716 Operands[4] = AArch64Operand::CreateImm(
6717 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6719 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6721 else if (Tok ==
"sbfiz")
6722 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6724 else if (Tok ==
"ubfiz")
6725 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6734 }
else if (NumOperands == 5 &&
6735 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6736 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6737 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6738 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6740 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6744 if (Op3CE && Op4CE) {
6745 uint64_t Op3Val = Op3CE->
getValue();
6746 uint64_t Op4Val = Op4CE->
getValue();
6748 uint64_t RegWidth = 0;
6749 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6755 if (Op3Val >= RegWidth)
6756 return Error(Op3.getStartLoc(),
6757 "expected integer in range [0, 31]");
6758 if (Op4Val < 1 || Op4Val > RegWidth)
6759 return Error(Op4.getStartLoc(),
6760 "expected integer in range [1, 32]");
6762 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6764 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6765 return Error(Op4.getStartLoc(),
6766 "requested extract overflows register");
6768 const MCExpr *NewOp4 =
6770 Operands[4] = AArch64Operand::CreateImm(
6771 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6773 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6775 else if (Tok ==
"sbfx")
6776 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6778 else if (Tok ==
"ubfx")
6779 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6792 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6793 NumOperands == 4 && Tok ==
"movi") {
6794 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6795 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6796 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6797 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6798 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6799 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6800 if (Suffix.
lower() ==
".2d" &&
6802 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6803 " correctly on this CPU, converting to equivalent movi.16b");
6805 unsigned Idx = Op1.isToken() ? 1 : 2;
6807 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6815 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6818 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6819 if (
Op.isScalarReg()) {
6821 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6822 Op.getStartLoc(),
Op.getEndLoc(),
6827 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6828 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6829 if (
Op.isScalarReg() &&
6830 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6834 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6835 if (
Op.isScalarReg()) {
6837 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6844 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6845 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6846 if (
Op.isScalarReg() &&
6847 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6851 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6852 if (
Op.isScalarReg()) {
6854 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6862 FeatureBitset MissingFeatures;
6865 unsigned MatchResult =
6866 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6867 MatchingInlineAsm, 1);
6871 if (MatchResult != Match_Success) {
6874 auto ShortFormNEONErrorInfo = ErrorInfo;
6875 auto ShortFormNEONMatchResult = MatchResult;
6876 auto ShortFormNEONMissingFeatures = MissingFeatures;
6879 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6880 MatchingInlineAsm, 0);
6885 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6886 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6887 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6888 MatchResult = ShortFormNEONMatchResult;
6889 ErrorInfo = ShortFormNEONErrorInfo;
6890 MissingFeatures = ShortFormNEONMissingFeatures;
6894 switch (MatchResult) {
6895 case Match_Success: {
6898 NumOperands = Operands.
size();
6899 for (
unsigned i = 1; i < NumOperands; ++i)
6900 OperandLocs.
push_back(Operands[i]->getStartLoc());
6901 if (validateInstruction(Inst, IDLoc, OperandLocs))
6908 case Match_MissingFeature: {
6909 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6912 std::string Msg =
"instruction requires:";
6913 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6914 if (MissingFeatures[i]) {
6919 return Error(IDLoc, Msg);
6921 case Match_MnemonicFail:
6922 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
6923 case Match_InvalidOperand: {
6924 SMLoc ErrorLoc = IDLoc;
6926 if (ErrorInfo != ~0ULL) {
6927 if (ErrorInfo >= Operands.
size())
6928 return Error(IDLoc,
"too few operands for instruction",
6929 SMRange(IDLoc, getTok().getLoc()));
6931 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
6932 if (ErrorLoc == SMLoc())
6937 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
6938 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
6939 MatchResult = Match_InvalidSuffix;
6941 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
6943 case Match_InvalidTiedOperand:
6944 case Match_InvalidMemoryIndexed1:
6945 case Match_InvalidMemoryIndexed2:
6946 case Match_InvalidMemoryIndexed4:
6947 case Match_InvalidMemoryIndexed8:
6948 case Match_InvalidMemoryIndexed16:
6949 case Match_InvalidCondCode:
6950 case Match_AddSubLSLImm3ShiftLarge:
6951 case Match_AddSubRegExtendSmall:
6952 case Match_AddSubRegExtendLarge:
6953 case Match_AddSubSecondSource:
6954 case Match_LogicalSecondSource:
6955 case Match_AddSubRegShift32:
6956 case Match_AddSubRegShift64:
6957 case Match_InvalidMovImm32Shift:
6958 case Match_InvalidMovImm64Shift:
6959 case Match_InvalidFPImm:
6960 case Match_InvalidMemoryWExtend8:
6961 case Match_InvalidMemoryWExtend16:
6962 case Match_InvalidMemoryWExtend32:
6963 case Match_InvalidMemoryWExtend64:
6964 case Match_InvalidMemoryWExtend128:
6965 case Match_InvalidMemoryXExtend8:
6966 case Match_InvalidMemoryXExtend16:
6967 case Match_InvalidMemoryXExtend32:
6968 case Match_InvalidMemoryXExtend64:
6969 case Match_InvalidMemoryXExtend128:
6970 case Match_InvalidMemoryIndexed1SImm4:
6971 case Match_InvalidMemoryIndexed2SImm4:
6972 case Match_InvalidMemoryIndexed3SImm4:
6973 case Match_InvalidMemoryIndexed4SImm4:
6974 case Match_InvalidMemoryIndexed1SImm6:
6975 case Match_InvalidMemoryIndexed16SImm4:
6976 case Match_InvalidMemoryIndexed32SImm4:
6977 case Match_InvalidMemoryIndexed4SImm7:
6978 case Match_InvalidMemoryIndexed8SImm7:
6979 case Match_InvalidMemoryIndexed16SImm7:
6980 case Match_InvalidMemoryIndexed8UImm5:
6981 case Match_InvalidMemoryIndexed8UImm3:
6982 case Match_InvalidMemoryIndexed4UImm5:
6983 case Match_InvalidMemoryIndexed2UImm5:
6984 case Match_InvalidMemoryIndexed1UImm6:
6985 case Match_InvalidMemoryIndexed2UImm6:
6986 case Match_InvalidMemoryIndexed4UImm6:
6987 case Match_InvalidMemoryIndexed8UImm6:
6988 case Match_InvalidMemoryIndexed16UImm6:
6989 case Match_InvalidMemoryIndexedSImm6:
6990 case Match_InvalidMemoryIndexedSImm5:
6991 case Match_InvalidMemoryIndexedSImm8:
6992 case Match_InvalidMemoryIndexedSImm9:
6993 case Match_InvalidMemoryIndexed16SImm9:
6994 case Match_InvalidMemoryIndexed8SImm10:
6995 case Match_InvalidImm0_0:
6996 case Match_InvalidImm0_1:
6997 case Match_InvalidImm0_3:
6998 case Match_InvalidImm0_7:
6999 case Match_InvalidImm0_15:
7000 case Match_InvalidImm0_31:
7001 case Match_InvalidImm0_63:
7002 case Match_InvalidImm0_127:
7003 case Match_InvalidImm0_255:
7004 case Match_InvalidImm0_65535:
7005 case Match_InvalidImm1_8:
7006 case Match_InvalidImm1_16:
7007 case Match_InvalidImm1_32:
7008 case Match_InvalidImm1_64:
7009 case Match_InvalidImmM1_62:
7010 case Match_InvalidMemoryIndexedRange2UImm0:
7011 case Match_InvalidMemoryIndexedRange2UImm1:
7012 case Match_InvalidMemoryIndexedRange2UImm2:
7013 case Match_InvalidMemoryIndexedRange2UImm3:
7014 case Match_InvalidMemoryIndexedRange4UImm0:
7015 case Match_InvalidMemoryIndexedRange4UImm1:
7016 case Match_InvalidMemoryIndexedRange4UImm2:
7017 case Match_InvalidSVEAddSubImm8:
7018 case Match_InvalidSVEAddSubImm16:
7019 case Match_InvalidSVEAddSubImm32:
7020 case Match_InvalidSVEAddSubImm64:
7021 case Match_InvalidSVECpyImm8:
7022 case Match_InvalidSVECpyImm16:
7023 case Match_InvalidSVECpyImm32:
7024 case Match_InvalidSVECpyImm64:
7025 case Match_InvalidIndexRange0_0:
7026 case Match_InvalidIndexRange1_1:
7027 case Match_InvalidIndexRange0_15:
7028 case Match_InvalidIndexRange0_7:
7029 case Match_InvalidIndexRange0_3:
7030 case Match_InvalidIndexRange0_1:
7031 case Match_InvalidSVEIndexRange0_63:
7032 case Match_InvalidSVEIndexRange0_31:
7033 case Match_InvalidSVEIndexRange0_15:
7034 case Match_InvalidSVEIndexRange0_7:
7035 case Match_InvalidSVEIndexRange0_3:
7036 case Match_InvalidLabel:
7037 case Match_InvalidComplexRotationEven:
7038 case Match_InvalidComplexRotationOdd:
7039 case Match_InvalidGPR64shifted8:
7040 case Match_InvalidGPR64shifted16:
7041 case Match_InvalidGPR64shifted32:
7042 case Match_InvalidGPR64shifted64:
7043 case Match_InvalidGPR64shifted128:
7044 case Match_InvalidGPR64NoXZRshifted8:
7045 case Match_InvalidGPR64NoXZRshifted16:
7046 case Match_InvalidGPR64NoXZRshifted32:
7047 case Match_InvalidGPR64NoXZRshifted64:
7048 case Match_InvalidGPR64NoXZRshifted128:
7049 case Match_InvalidZPR32UXTW8:
7050 case Match_InvalidZPR32UXTW16:
7051 case Match_InvalidZPR32UXTW32:
7052 case Match_InvalidZPR32UXTW64:
7053 case Match_InvalidZPR32SXTW8:
7054 case Match_InvalidZPR32SXTW16:
7055 case Match_InvalidZPR32SXTW32:
7056 case Match_InvalidZPR32SXTW64:
7057 case Match_InvalidZPR64UXTW8:
7058 case Match_InvalidZPR64SXTW8:
7059 case Match_InvalidZPR64UXTW16:
7060 case Match_InvalidZPR64SXTW16:
7061 case Match_InvalidZPR64UXTW32:
7062 case Match_InvalidZPR64SXTW32:
7063 case Match_InvalidZPR64UXTW64:
7064 case Match_InvalidZPR64SXTW64:
7065 case Match_InvalidZPR32LSL8:
7066 case Match_InvalidZPR32LSL16:
7067 case Match_InvalidZPR32LSL32:
7068 case Match_InvalidZPR32LSL64:
7069 case Match_InvalidZPR64LSL8:
7070 case Match_InvalidZPR64LSL16:
7071 case Match_InvalidZPR64LSL32:
7072 case Match_InvalidZPR64LSL64:
7073 case Match_InvalidZPR0:
7074 case Match_InvalidZPR8:
7075 case Match_InvalidZPR16:
7076 case Match_InvalidZPR32:
7077 case Match_InvalidZPR64:
7078 case Match_InvalidZPR128:
7079 case Match_InvalidZPR_3b8:
7080 case Match_InvalidZPR_3b16:
7081 case Match_InvalidZPR_3b32:
7082 case Match_InvalidZPR_4b8:
7083 case Match_InvalidZPR_4b16:
7084 case Match_InvalidZPR_4b32:
7085 case Match_InvalidZPR_4b64:
7086 case Match_InvalidSVEPPRorPNRAnyReg:
7087 case Match_InvalidSVEPPRorPNRBReg:
7088 case Match_InvalidSVEPredicateAnyReg:
7089 case Match_InvalidSVEPattern:
7090 case Match_InvalidSVEVecLenSpecifier:
7091 case Match_InvalidSVEPredicateBReg:
7092 case Match_InvalidSVEPredicateHReg:
7093 case Match_InvalidSVEPredicateSReg:
7094 case Match_InvalidSVEPredicateDReg:
7095 case Match_InvalidSVEPredicate3bAnyReg:
7096 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7097 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7098 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7099 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7100 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7101 case Match_InvalidSVEPNPredicateBReg:
7102 case Match_InvalidSVEPNPredicateHReg:
7103 case Match_InvalidSVEPNPredicateSReg:
7104 case Match_InvalidSVEPNPredicateDReg:
7105 case Match_InvalidSVEPredicateListMul2x8:
7106 case Match_InvalidSVEPredicateListMul2x16:
7107 case Match_InvalidSVEPredicateListMul2x32:
7108 case Match_InvalidSVEPredicateListMul2x64:
7109 case Match_InvalidSVEExactFPImmOperandHalfOne:
7110 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7111 case Match_InvalidSVEExactFPImmOperandZeroOne:
7112 case Match_InvalidMatrixTile16:
7113 case Match_InvalidMatrixTile32:
7114 case Match_InvalidMatrixTile64:
7115 case Match_InvalidMatrix:
7116 case Match_InvalidMatrix8:
7117 case Match_InvalidMatrix16:
7118 case Match_InvalidMatrix32:
7119 case Match_InvalidMatrix64:
7120 case Match_InvalidMatrixTileVectorH8:
7121 case Match_InvalidMatrixTileVectorH16:
7122 case Match_InvalidMatrixTileVectorH32:
7123 case Match_InvalidMatrixTileVectorH64:
7124 case Match_InvalidMatrixTileVectorH128:
7125 case Match_InvalidMatrixTileVectorV8:
7126 case Match_InvalidMatrixTileVectorV16:
7127 case Match_InvalidMatrixTileVectorV32:
7128 case Match_InvalidMatrixTileVectorV64:
7129 case Match_InvalidMatrixTileVectorV128:
7130 case Match_InvalidSVCR:
7131 case Match_InvalidMatrixIndexGPR32_12_15:
7132 case Match_InvalidMatrixIndexGPR32_8_11:
7133 case Match_InvalidLookupTable:
7134 case Match_InvalidZPRMul2_Lo8:
7135 case Match_InvalidZPRMul2_Hi8:
7136 case Match_InvalidZPRMul2_Lo16:
7137 case Match_InvalidZPRMul2_Hi16:
7138 case Match_InvalidZPRMul2_Lo32:
7139 case Match_InvalidZPRMul2_Hi32:
7140 case Match_InvalidZPRMul2_Lo64:
7141 case Match_InvalidZPRMul2_Hi64:
7142 case Match_InvalidZPR_K0:
7143 case Match_InvalidSVEVectorList2x8Mul2:
7144 case Match_InvalidSVEVectorList2x16Mul2:
7145 case Match_InvalidSVEVectorList2x32Mul2:
7146 case Match_InvalidSVEVectorList2x64Mul2:
7147 case Match_InvalidSVEVectorList2x128Mul2:
7148 case Match_InvalidSVEVectorList4x8Mul4:
7149 case Match_InvalidSVEVectorList4x16Mul4:
7150 case Match_InvalidSVEVectorList4x32Mul4:
7151 case Match_InvalidSVEVectorList4x64Mul4:
7152 case Match_InvalidSVEVectorList4x128Mul4:
7153 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7154 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7155 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7156 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7157 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7158 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7159 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7160 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7161 case Match_InvalidSVEVectorListStrided2x8:
7162 case Match_InvalidSVEVectorListStrided2x16:
7163 case Match_InvalidSVEVectorListStrided2x32:
7164 case Match_InvalidSVEVectorListStrided2x64:
7165 case Match_InvalidSVEVectorListStrided4x8:
7166 case Match_InvalidSVEVectorListStrided4x16:
7167 case Match_InvalidSVEVectorListStrided4x32:
7168 case Match_InvalidSVEVectorListStrided4x64:
7171 if (ErrorInfo >= Operands.
size())
7172 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7175 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7176 if (ErrorLoc == SMLoc())
7178 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7186bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7193 SMLoc Loc = DirectiveID.
getLoc();
7194 if (IDVal ==
".arch")
7195 parseDirectiveArch(Loc);
7196 else if (IDVal ==
".cpu")
7197 parseDirectiveCPU(Loc);
7198 else if (IDVal ==
".tlsdesccall")
7199 parseDirectiveTLSDescCall(Loc);
7200 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7201 parseDirectiveLtorg(Loc);
7202 else if (IDVal ==
".unreq")
7203 parseDirectiveUnreq(Loc);
7204 else if (IDVal ==
".inst")
7205 parseDirectiveInst(Loc);
7206 else if (IDVal ==
".cfi_negate_ra_state")
7207 parseDirectiveCFINegateRAState();
7208 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7209 parseDirectiveCFINegateRAStateWithPC();
7210 else if (IDVal ==
".cfi_b_key_frame")
7211 parseDirectiveCFIBKeyFrame();
7212 else if (IDVal ==
".cfi_mte_tagged_frame")
7213 parseDirectiveCFIMTETaggedFrame();
7214 else if (IDVal ==
".arch_extension")
7215 parseDirectiveArchExtension(Loc);
7216 else if (IDVal ==
".variant_pcs")
7217 parseDirectiveVariantPCS(Loc);
7220 parseDirectiveLOH(IDVal, Loc);
7223 }
else if (IsCOFF) {
7224 if (IDVal ==
".seh_stackalloc")
7225 parseDirectiveSEHAllocStack(Loc);
7226 else if (IDVal ==
".seh_endprologue")
7227 parseDirectiveSEHPrologEnd(Loc);
7228 else if (IDVal ==
".seh_save_r19r20_x")
7229 parseDirectiveSEHSaveR19R20X(Loc);
7230 else if (IDVal ==
".seh_save_fplr")
7231 parseDirectiveSEHSaveFPLR(Loc);
7232 else if (IDVal ==
".seh_save_fplr_x")
7233 parseDirectiveSEHSaveFPLRX(Loc);
7234 else if (IDVal ==
".seh_save_reg")
7235 parseDirectiveSEHSaveReg(Loc);
7236 else if (IDVal ==
".seh_save_reg_x")
7237 parseDirectiveSEHSaveRegX(Loc);
7238 else if (IDVal ==
".seh_save_regp")
7239 parseDirectiveSEHSaveRegP(Loc);
7240 else if (IDVal ==
".seh_save_regp_x")
7241 parseDirectiveSEHSaveRegPX(Loc);
7242 else if (IDVal ==
".seh_save_lrpair")
7243 parseDirectiveSEHSaveLRPair(Loc);
7244 else if (IDVal ==
".seh_save_freg")
7245 parseDirectiveSEHSaveFReg(Loc);
7246 else if (IDVal ==
".seh_save_freg_x")
7247 parseDirectiveSEHSaveFRegX(Loc);
7248 else if (IDVal ==
".seh_save_fregp")
7249 parseDirectiveSEHSaveFRegP(Loc);
7250 else if (IDVal ==
".seh_save_fregp_x")
7251 parseDirectiveSEHSaveFRegPX(Loc);
7252 else if (IDVal ==
".seh_set_fp")
7253 parseDirectiveSEHSetFP(Loc);
7254 else if (IDVal ==
".seh_add_fp")
7255 parseDirectiveSEHAddFP(Loc);
7256 else if (IDVal ==
".seh_nop")
7257 parseDirectiveSEHNop(Loc);
7258 else if (IDVal ==
".seh_save_next")
7259 parseDirectiveSEHSaveNext(Loc);
7260 else if (IDVal ==
".seh_startepilogue")
7261 parseDirectiveSEHEpilogStart(Loc);
7262 else if (IDVal ==
".seh_endepilogue")
7263 parseDirectiveSEHEpilogEnd(Loc);
7264 else if (IDVal ==
".seh_trap_frame")
7265 parseDirectiveSEHTrapFrame(Loc);
7266 else if (IDVal ==
".seh_pushframe")
7267 parseDirectiveSEHMachineFrame(Loc);
7268 else if (IDVal ==
".seh_context")
7269 parseDirectiveSEHContext(Loc);
7270 else if (IDVal ==
".seh_ec_context")
7271 parseDirectiveSEHECContext(Loc);
7272 else if (IDVal ==
".seh_clear_unwound_to_call")
7273 parseDirectiveSEHClearUnwoundToCall(Loc);
7274 else if (IDVal ==
".seh_pac_sign_lr")
7275 parseDirectiveSEHPACSignLR(Loc);
7276 else if (IDVal ==
".seh_save_any_reg")
7277 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7278 else if (IDVal ==
".seh_save_any_reg_p")
7279 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7280 else if (IDVal ==
".seh_save_any_reg_x")
7281 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7282 else if (IDVal ==
".seh_save_any_reg_px")
7283 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7284 else if (IDVal ==
".seh_allocz")
7285 parseDirectiveSEHAllocZ(Loc);
7286 else if (IDVal ==
".seh_save_zreg")
7287 parseDirectiveSEHSaveZReg(Loc);
7288 else if (IDVal ==
".seh_save_preg")
7289 parseDirectiveSEHSavePReg(Loc);
7293 if (IDVal ==
".aeabi_subsection")
7294 parseDirectiveAeabiSubSectionHeader(Loc);
7295 else if (IDVal ==
".aeabi_attribute")
7296 parseDirectiveAeabiAArch64Attr(Loc);
7309 if (!NoCrypto && Crypto) {
7312 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7313 ArchInfo == AArch64::ARMV8_3A) {
7317 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7318 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7319 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7320 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7321 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7322 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7328 }
else if (NoCrypto) {
7331 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7332 ArchInfo == AArch64::ARMV8_3A) {
7333 RequestedExtensions.
push_back(
"nosha2");
7336 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7337 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7338 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7339 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7340 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7341 ArchInfo == AArch64::ARMV9_4A) {
7343 RequestedExtensions.
push_back(
"nosha3");
7344 RequestedExtensions.
push_back(
"nosha2");
7356bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7357 SMLoc CurLoc = getLoc();
7359 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7360 StringRef Arch, ExtensionString;
7361 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7365 return Error(CurLoc,
"unknown arch name");
7371 std::vector<StringRef> AArch64Features;
7375 MCSubtargetInfo &STI = copySTI();
7376 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7378 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7381 if (!ExtensionString.
empty())
7382 ExtensionString.
split(RequestedExtensions,
'+');
7387 for (
auto Name : RequestedExtensions) {
7391 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7398 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7406 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7407 setAvailableFeatures(Features);
7409 getTargetStreamer().emitDirectiveArch(Name);
7415bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7416 SMLoc ExtLoc = getLoc();
7418 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7423 bool EnableFeature =
true;
7424 StringRef
Name = FullName;
7425 if (
Name.starts_with_insensitive(
"no")) {
7426 EnableFeature =
false;
7435 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7437 MCSubtargetInfo &STI = copySTI();
7442 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7443 setAvailableFeatures(Features);
7445 getTargetStreamer().emitDirectiveArchExtension(FullName);
7451bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7452 SMLoc CurLoc = getLoc();
7454 StringRef CPU, ExtensionString;
7455 std::tie(CPU, ExtensionString) =
7456 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7462 if (!ExtensionString.
empty())
7463 ExtensionString.
split(RequestedExtensions,
'+');
7467 Error(CurLoc,
"unknown CPU name");
7472 MCSubtargetInfo &STI = copySTI();
7476 for (
auto Name : RequestedExtensions) {
7480 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7487 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7495 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7496 setAvailableFeatures(Features);
7502bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7504 return Error(Loc,
"expected expression following '.inst' directive");
7506 auto parseOp = [&]() ->
bool {
7508 const MCExpr *Expr =
nullptr;
7509 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7512 if (check(!
Value, L,
"expected constant expression"))
7514 getTargetStreamer().emitInst(
Value->getValue());
7518 return parseMany(parseOp);
7523bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7525 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7537 getParser().getStreamer().emitInstruction(Inst, getSTI());
7543bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7547 return TokError(
"expected an identifier or a number in directive");
7550 int64_t
Id = getTok().getIntVal();
7552 return TokError(
"invalid numeric identifier in directive");
7555 StringRef
Name = getTok().getIdentifier();
7561 return TokError(
"invalid identifier in directive");
7569 assert(NbArgs != -1 &&
"Invalid number of arguments");
7572 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7574 if (getParser().parseIdentifier(Name))
7575 return TokError(
"expected identifier in directive");
7578 if (Idx + 1 == NbArgs)
7586 getStreamer().emitLOHDirective(Kind, Args);
7592bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7595 getTargetStreamer().emitCurrentConstantPool();
7601bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7603 SMLoc SRegLoc = getLoc();
7604 RegKind RegisterKind = RegKind::Scalar;
7606 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7610 RegisterKind = RegKind::NeonVector;
7611 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7617 return Error(SRegLoc,
"vector register without type specifier expected");
7622 RegisterKind = RegKind::SVEDataVector;
7624 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7630 return Error(SRegLoc,
7631 "sve vector register without type specifier expected");
7636 RegisterKind = RegKind::SVEPredicateVector;
7637 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7643 return Error(SRegLoc,
7644 "sve predicate register without type specifier expected");
7648 return Error(SRegLoc,
"register name or alias expected");
7654 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7655 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7656 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7663bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7665 return TokError(
"unexpected input in .unreq directive.");
7666 RegisterReqs.
erase(getTok().getIdentifier().lower());
7671bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7674 getStreamer().emitCFINegateRAState();
7678bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7681 getStreamer().emitCFINegateRAStateWithPC();
7687bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7690 getStreamer().emitCFIBKeyFrame();
7696bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7699 getStreamer().emitCFIMTETaggedFrame();
7705bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7707 if (getParser().parseIdentifier(Name))
7708 return TokError(
"expected symbol name");
7711 getTargetStreamer().emitDirectiveVariantPCS(
7718bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7720 if (parseImmExpr(
Size))
7722 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7728bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7729 getTargetStreamer().emitARM64WinCFIPrologEnd();
7735bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7737 if (parseImmExpr(
Offset))
7739 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7745bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7747 if (parseImmExpr(
Offset))
7749 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7755bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7757 if (parseImmExpr(
Offset))
7759 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7765bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7768 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7769 parseComma() || parseImmExpr(
Offset))
7771 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7777bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7780 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7781 parseComma() || parseImmExpr(
Offset))
7783 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7789bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7792 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7793 parseComma() || parseImmExpr(
Offset))
7795 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7801bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7804 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7805 parseComma() || parseImmExpr(
Offset))
7807 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7813bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7817 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7818 parseComma() || parseImmExpr(
Offset))
7820 if (check(((
Reg - 19) % 2 != 0), L,
7821 "expected register with even offset from x19"))
7823 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7829bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7832 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7833 parseComma() || parseImmExpr(
Offset))
7835 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7841bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7844 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7845 parseComma() || parseImmExpr(
Offset))
7847 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7853bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7856 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7857 parseComma() || parseImmExpr(
Offset))
7859 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7865bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7868 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7869 parseComma() || parseImmExpr(
Offset))
7871 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7877bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7878 getTargetStreamer().emitARM64WinCFISetFP();
7884bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7886 if (parseImmExpr(
Size))
7888 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7894bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7895 getTargetStreamer().emitARM64WinCFINop();
7901bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7902 getTargetStreamer().emitARM64WinCFISaveNext();
7908bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7909 getTargetStreamer().emitARM64WinCFIEpilogStart();
7915bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7916 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7922bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7923 getTargetStreamer().emitARM64WinCFITrapFrame();
7929bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7930 getTargetStreamer().emitARM64WinCFIMachineFrame();
7936bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7937 getTargetStreamer().emitARM64WinCFIContext();
7943bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7944 getTargetStreamer().emitARM64WinCFIECContext();
7950bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7951 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7957bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7958 getTargetStreamer().emitARM64WinCFIPACSignLR();
7967bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7972 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7973 parseComma() || parseImmExpr(
Offset))
7976 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7977 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7978 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7979 return Error(L,
"invalid save_any_reg offset");
7980 unsigned EncodedReg;
7981 if (
Reg == AArch64::FP)
7983 else if (
Reg == AArch64::LR)
7986 EncodedReg =
Reg - AArch64::X0;
7988 if (
Reg == AArch64::LR)
7989 return Error(Start,
"lr cannot be paired with another register");
7991 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7993 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7996 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7998 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
8000 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
8001 unsigned EncodedReg =
Reg - AArch64::D0;
8002 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8003 return Error(L,
"invalid save_any_reg offset");
8005 if (
Reg == AArch64::D31)
8006 return Error(Start,
"d31 cannot be paired with another register");
8008 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
8010 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
8013 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
8015 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
8017 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
8018 unsigned EncodedReg =
Reg - AArch64::Q0;
8020 return Error(L,
"invalid save_any_reg offset");
8022 if (
Reg == AArch64::Q31)
8023 return Error(Start,
"q31 cannot be paired with another register");
8025 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
8027 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
8030 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
8032 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
8035 return Error(Start,
"save_any_reg register must be x, q or d register");
8042bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8044 if (parseImmExpr(
Offset))
8046 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8052bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8057 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8060 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8061 "expected register in range z8 to z23"))
8063 if (parseComma() || parseImmExpr(
Offset))
8065 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8071bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8076 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8079 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8080 "expected register in range p4 to p15"))
8082 if (parseComma() || parseImmExpr(
Offset))
8084 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8088bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8094 MCAsmParser &Parser = getParser();
8097 StringRef SubsectionName;
8108 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8109 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8114 if (SubsectionExists) {
8115 getTargetStreamer().emitAttributesSubsection(
8118 SubsectionExists->IsOptional),
8120 SubsectionExists->ParameterType));
8126 "Could not switch to subsection '" + SubsectionName +
8127 "' using subsection name, subsection has not been defined");
8150 if (SubsectionExists) {
8151 if (IsOptional != SubsectionExists->IsOptional) {
8153 "optionality mismatch! subsection '" + SubsectionName +
8154 "' already exists with optionality defined as '" +
8156 SubsectionExists->IsOptional) +
8164 "optionality parameter not found, expected required|optional");
8171 "aeabi_feature_and_bits must be marked as optional");
8178 "aeabi_pauthabi must be marked as required");
8198 if (SubsectionExists) {
8199 if (
Type != SubsectionExists->ParameterType) {
8201 "type mismatch! subsection '" + SubsectionName +
8202 "' already exists with type defined as '" +
8204 SubsectionExists->ParameterType) +
8212 "type parameter not found, expected uleb128|ntbs");
8220 SubsectionName +
" must be marked as ULEB128");
8229 "attributes subsection header directive");
8233 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8238bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8242 MCAsmParser &Parser = getParser();
8244 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8245 getTargetStreamer().getActiveAttributesSubsection();
8246 if (
nullptr == ActiveSubsection) {
8248 "no active subsection, build attribute can not be added");
8251 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8252 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8260 ActiveSubsectionName)
8263 StringRef TagStr =
"";
8266 Tag = getTok().getIntVal();
8269 switch (ActiveSubsectionID) {
8274 "' \nExcept for public subsections, "
8275 "tags have to be an unsigned int.");
8282 TagStr +
"' for subsection '" +
8283 ActiveSubsectionName +
"'");
8291 TagStr +
"' for subsection '" +
8292 ActiveSubsectionName +
"'");
8310 unsigned ValueInt = unsigned(-1);
8311 std::string ValueStr =
"";
8316 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8319 ValueInt = getTok().getIntVal();
8324 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8332 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8343 if (0 != ValueInt && 1 != ValueInt) {
8345 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8346 "' options are 0|1");
8355 "unexpected token for AArch64 build attributes tag and value "
8356 "attribute directive");
8360 if (
unsigned(-1) != ValueInt) {
8361 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8363 if (
"" != ValueStr) {
8364 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8370bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8373 if (getParser().parseExpression(Res))
8375 MCAsmParser &Parser = getParser();
8379 return Error(getLoc(),
"expected relocation specifier");
8382 SMLoc Loc = getLoc();
8384 if (Identifier ==
"auth")
8385 return parseAuthExpr(Res, EndLoc);
8389 if (Identifier ==
"got")
8393 if (Identifier ==
"gotpcrel")
8395 else if (Identifier ==
"plt")
8397 else if (Identifier ==
"funcinit")
8401 return Error(Loc,
"invalid relocation specifier");
8406 return Error(Loc,
"@ specifier only allowed after a symbol");
8409 std::optional<MCBinaryExpr::Opcode> Opcode;
8417 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8428bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8429 MCAsmParser &Parser = getParser();
8431 AsmToken Tok = Parser.
getTok();
8438 return TokError(
"expected key name");
8443 return TokError(
"invalid key '" + KeyStr +
"'");
8450 return TokError(
"expected integer discriminator");
8454 return TokError(
"integer discriminator " + Twine(Discriminator) +
8455 " out of range [0, 0xFFFF]");
8458 bool UseAddressDiversity =
false;
8463 return TokError(
"expected 'addr'");
8464 UseAddressDiversity =
true;
8473 UseAddressDiversity, Ctx, Res->
getLoc());
8477bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8486 ELFSpec = AE->getSpecifier();
8487 Expr = AE->getSubExpr();
8527#define GET_REGISTER_MATCHER
8528#define GET_SUBTARGET_FEATURE_NAME
8529#define GET_MATCHER_IMPLEMENTATION
8530#define GET_MNEMONIC_SPELL_CHECKER
8531#include "AArch64GenAsmMatcher.inc"
8537 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8539 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8541 return Match_InvalidOperand;
8544 return Match_InvalidOperand;
8545 if (CE->getValue() == ExpectedVal)
8546 return Match_Success;
8547 return Match_InvalidOperand;
8552 return Match_InvalidOperand;
8558 if (
Op.isTokenEqual(
"za"))
8559 return Match_Success;
8560 return Match_InvalidOperand;
8566#define MATCH_HASH(N) \
8567 case MCK__HASH_##N: \
8568 return MatchesOpImmediate(N);
8594#define MATCH_HASH_MINUS(N) \
8595 case MCK__HASH__MINUS_##N: \
8596 return MatchesOpImmediate(-N);
8600#undef MATCH_HASH_MINUS
8604ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8609 return Error(S,
"expected register");
8611 MCRegister FirstReg;
8612 ParseStatus Res = tryParseScalarRegister(FirstReg);
8614 return Error(S,
"expected first even register of a consecutive same-size "
8615 "even/odd register pair");
8617 const MCRegisterClass &WRegClass =
8618 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8619 const MCRegisterClass &XRegClass =
8620 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8622 bool isXReg = XRegClass.
contains(FirstReg),
8623 isWReg = WRegClass.
contains(FirstReg);
8624 if (!isXReg && !isWReg)
8625 return Error(S,
"expected first even register of a consecutive same-size "
8626 "even/odd register pair");
8628 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8631 if (FirstEncoding & 0x1)
8632 return Error(S,
"expected first even register of a consecutive same-size "
8633 "even/odd register pair");
8636 return Error(getLoc(),
"expected comma");
8641 MCRegister SecondReg;
8642 Res = tryParseScalarRegister(SecondReg);
8644 return Error(
E,
"expected second odd register of a consecutive same-size "
8645 "even/odd register pair");
8648 (isXReg && !XRegClass.
contains(SecondReg)) ||
8649 (isWReg && !WRegClass.
contains(SecondReg)))
8650 return Error(
E,
"expected second odd register of a consecutive same-size "
8651 "even/odd register pair");
8656 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8659 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8662 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8668template <
bool ParseShiftExtend,
bool ParseSuffix>
8669ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8670 const SMLoc S = getLoc();
8676 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8681 if (ParseSuffix &&
Kind.empty())
8688 unsigned ElementWidth = KindRes->second;
8692 Operands.
push_back(AArch64Operand::CreateVectorReg(
8693 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8695 ParseStatus Res = tryParseVectorIndex(Operands);
8706 Res = tryParseOptionalShiftExtend(ExtOpnd);
8710 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8711 Operands.
push_back(AArch64Operand::CreateVectorReg(
8712 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8714 Ext->hasShiftExtendAmount()));
8719ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8720 MCAsmParser &Parser = getParser();
8722 SMLoc
SS = getLoc();
8723 const AsmToken &TokE = getTok();
8734 const MCExpr *ImmVal;
8741 return TokError(
"invalid operand for instruction");
8746 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8751 Pattern = Pat->Encoding;
8752 assert(Pattern >= 0 && Pattern < 32);
8763AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8765 SMLoc
SS = getLoc();
8766 const AsmToken &TokE = getTok();
8768 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8774 Pattern = Pat->Encoding;
8775 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8784ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8785 SMLoc
SS = getLoc();
8788 if (!tryParseScalarRegister(XReg).isSuccess())
8794 XReg, AArch64::x8sub_0,
8795 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8798 "expected an even-numbered x-register in the range [x0,x22]");
8801 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8805ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8815 if (getParser().parseExpression(ImmF))
8825 SMLoc
E = getTok().getLoc();
8827 if (getParser().parseExpression(ImmL))
8834 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8839ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8849 if (getParser().parseExpression(Ex))
8859 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8866 Operands.
push_back(AArch64Operand::CreateImm(
#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.
static unsigned matchMatrixRegName(StringRef Name)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static const struct Extension ExtensionMap[]
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
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")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Value * getPointer(Value *Ptr)
loop data Loop Data Prefetch
static unsigned 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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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.
constexpr size_t size() const
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.
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
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB)
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
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.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
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
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
SubsectionType getTypeID(StringRef Type)
StringRef getVendorName(unsigned const Vendor)
StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
StringRef getSubsectionTypeUnknownError()
SubsectionOptional getOptionalID(StringRef Optional)
StringRef getSubsectionOptionalUnknownError()
FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
VendorID getVendorID(StringRef const Vendor)
PauthABITags getPauthABITagsID(StringRef PauthABITag)
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 ==...
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.
FunctionAddr VTableAddr Value
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)
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)
FunctionAddr VTableAddr Count
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.
FunctionAddr VTableAddr Next
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.
const FeatureBitset Features
AArch64::ExtensionBitset DefaultExts
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
FeatureBitset FeaturesRequired