72 SVEPredicateAsCounter,
78enum class MatrixKind { Array, Tile, Row, Col };
80enum RegConstraintEqualityTy {
91 StringMap<std::pair<RegKind, MCRegister>> 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 MCRegister 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 parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
186 bool parseDataExpr(
const MCExpr *&Res)
override;
187 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
189 bool parseDirectiveArch(SMLoc L);
190 bool parseDirectiveArchExtension(SMLoc L);
191 bool parseDirectiveCPU(SMLoc L);
192 bool parseDirectiveInst(SMLoc L);
194 bool parseDirectiveTLSDescCall(SMLoc L);
196 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
197 bool parseDirectiveLtorg(SMLoc L);
199 bool parseDirectiveReq(StringRef Name, SMLoc L);
200 bool parseDirectiveUnreq(SMLoc L);
201 bool parseDirectiveCFINegateRAState();
202 bool parseDirectiveCFINegateRAStateWithPC();
203 bool parseDirectiveCFIBKeyFrame();
204 bool parseDirectiveCFIMTETaggedFrame();
206 bool parseDirectiveVariantPCS(SMLoc L);
208 bool parseDirectiveSEHAllocStack(SMLoc L);
209 bool parseDirectiveSEHPrologEnd(SMLoc L);
210 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
211 bool parseDirectiveSEHSaveFPLR(SMLoc L);
212 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
213 bool parseDirectiveSEHSaveReg(SMLoc L);
214 bool parseDirectiveSEHSaveRegX(SMLoc L);
215 bool parseDirectiveSEHSaveRegP(SMLoc L);
216 bool parseDirectiveSEHSaveRegPX(SMLoc L);
217 bool parseDirectiveSEHSaveLRPair(SMLoc L);
218 bool parseDirectiveSEHSaveFReg(SMLoc L);
219 bool parseDirectiveSEHSaveFRegX(SMLoc L);
220 bool parseDirectiveSEHSaveFRegP(SMLoc L);
221 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
222 bool parseDirectiveSEHSetFP(SMLoc L);
223 bool parseDirectiveSEHAddFP(SMLoc L);
224 bool parseDirectiveSEHNop(SMLoc L);
225 bool parseDirectiveSEHSaveNext(SMLoc L);
226 bool parseDirectiveSEHEpilogStart(SMLoc L);
227 bool parseDirectiveSEHEpilogEnd(SMLoc L);
228 bool parseDirectiveSEHTrapFrame(SMLoc L);
229 bool parseDirectiveSEHMachineFrame(SMLoc L);
230 bool parseDirectiveSEHContext(SMLoc L);
231 bool parseDirectiveSEHECContext(SMLoc L);
232 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
233 bool parseDirectiveSEHPACSignLR(SMLoc L);
234 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
235 bool parseDirectiveSEHAllocZ(SMLoc L);
236 bool parseDirectiveSEHSaveZReg(SMLoc L);
237 bool parseDirectiveSEHSavePReg(SMLoc L);
238 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
239 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
241 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
242 SmallVectorImpl<SMLoc> &Loc);
243 unsigned getNumRegsForRegKind(RegKind K);
244 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
247 bool MatchingInlineAsm)
override;
251#define GET_ASSEMBLER_HEADER
252#include "AArch64GenAsmMatcher.inc"
266 template <
bool IsSVEPrefetch = false>
275 template <
bool AddFPZeroAsLiteral>
283 template <
bool ParseShiftExtend,
284 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
287 template <
bool ParseShiftExtend,
bool ParseSuffix>
289 template <RegKind RK>
292 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
293 template <RegKind VectorKind>
295 bool ExpectMatch =
false);
305 enum AArch64MatchResultTy {
306 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
307#define GET_OPERAND_DIAGNOSTIC_TYPES
308#include "AArch64GenAsmMatcher.inc"
311 bool IsWindowsArm64EC;
313 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
314 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
315 : MCTargetAsmParser(
Options, STI, MII) {
319 MCStreamer &S = getParser().getStreamer();
321 new AArch64TargetStreamer(S);
333 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
336 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
337 const MCParsedAsmOperand &Op2)
const override;
338 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
340 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
341 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
342 SMLoc &EndLoc)
override;
343 bool ParseDirective(AsmToken DirectiveID)
override;
344 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
345 unsigned Kind)
override;
381 SMLoc StartLoc, EndLoc;
390 struct ShiftExtendOp {
393 bool HasExplicitAmount;
403 RegConstraintEqualityTy EqualityTy;
419 ShiftExtendOp ShiftExtend;
424 unsigned ElementWidth;
428 struct MatrixTileListOp {
429 unsigned RegMask = 0;
432 struct VectorListOp {
436 unsigned NumElements;
437 unsigned ElementWidth;
438 RegKind RegisterKind;
441 struct VectorIndexOp {
449 struct ShiftedImmOp {
451 unsigned ShiftAmount;
480 uint32_t PStateField;
508 struct CMHPriorityHintOp {
513 struct TIndexHintOp {
522 unsigned PStateField;
528 struct MatrixRegOp MatrixReg;
529 struct MatrixTileListOp MatrixTileList;
530 struct VectorListOp VectorList;
531 struct VectorIndexOp VectorIndex;
533 struct ShiftedImmOp ShiftedImm;
534 struct ImmRangeOp ImmRange;
536 struct FPImmOp FPImm;
538 struct SysRegOp SysReg;
539 struct SysCRImmOp SysCRImm;
541 struct PSBHintOp PSBHint;
542 struct PHintOp PHint;
543 struct BTIHintOp BTIHint;
544 struct CMHPriorityHintOp CMHPriorityHint;
545 struct TIndexHintOp TIndexHint;
546 struct ShiftExtendOp ShiftExtend;
555 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
557 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
559 StartLoc =
o.StartLoc;
569 ShiftedImm =
o.ShiftedImm;
572 ImmRange =
o.ImmRange;
586 case k_MatrixRegister:
587 MatrixReg =
o.MatrixReg;
589 case k_MatrixTileList:
590 MatrixTileList =
o.MatrixTileList;
593 VectorList =
o.VectorList;
596 VectorIndex =
o.VectorIndex;
602 SysCRImm =
o.SysCRImm;
616 case k_CMHPriorityHint:
617 CMHPriorityHint =
o.CMHPriorityHint;
620 TIndexHint =
o.TIndexHint;
623 ShiftExtend =
o.ShiftExtend;
632 SMLoc getStartLoc()
const override {
return StartLoc; }
634 SMLoc getEndLoc()
const override {
return EndLoc; }
637 assert(Kind == k_Token &&
"Invalid access!");
638 return StringRef(Tok.Data, Tok.Length);
641 bool isTokenSuffix()
const {
642 assert(Kind == k_Token &&
"Invalid access!");
646 const MCExpr *
getImm()
const {
647 assert(Kind == k_Immediate &&
"Invalid access!");
651 const MCExpr *getShiftedImmVal()
const {
652 assert(Kind == k_ShiftedImm &&
"Invalid access!");
653 return ShiftedImm.Val;
656 unsigned getShiftedImmShift()
const {
657 assert(Kind == k_ShiftedImm &&
"Invalid access!");
658 return ShiftedImm.ShiftAmount;
661 unsigned getFirstImmVal()
const {
662 assert(Kind == k_ImmRange &&
"Invalid access!");
663 return ImmRange.First;
666 unsigned getLastImmVal()
const {
667 assert(Kind == k_ImmRange &&
"Invalid access!");
668 return ImmRange.Last;
672 assert(Kind == k_CondCode &&
"Invalid access!");
677 assert (Kind == k_FPImm &&
"Invalid access!");
678 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
681 bool getFPImmIsExact()
const {
682 assert (Kind == k_FPImm &&
"Invalid access!");
683 return FPImm.IsExact;
686 unsigned getBarrier()
const {
687 assert(Kind == k_Barrier &&
"Invalid access!");
691 StringRef getBarrierName()
const {
692 assert(Kind == k_Barrier &&
"Invalid access!");
696 bool getBarriernXSModifier()
const {
697 assert(Kind == k_Barrier &&
"Invalid access!");
701 MCRegister
getReg()
const override {
702 assert(Kind == k_Register &&
"Invalid access!");
706 MCRegister getMatrixReg()
const {
707 assert(Kind == k_MatrixRegister &&
"Invalid access!");
708 return MatrixReg.Reg;
711 unsigned getMatrixElementWidth()
const {
712 assert(Kind == k_MatrixRegister &&
"Invalid access!");
713 return MatrixReg.ElementWidth;
716 MatrixKind getMatrixKind()
const {
717 assert(Kind == k_MatrixRegister &&
"Invalid access!");
718 return MatrixReg.Kind;
721 unsigned getMatrixTileListRegMask()
const {
722 assert(isMatrixTileList() &&
"Invalid access!");
723 return MatrixTileList.RegMask;
726 RegConstraintEqualityTy getRegEqualityTy()
const {
727 assert(Kind == k_Register &&
"Invalid access!");
728 return Reg.EqualityTy;
731 MCRegister getVectorListStart()
const {
732 assert(Kind == k_VectorList &&
"Invalid access!");
733 return VectorList.Reg;
736 unsigned getVectorListCount()
const {
737 assert(Kind == k_VectorList &&
"Invalid access!");
738 return VectorList.Count;
741 unsigned getVectorListStride()
const {
742 assert(Kind == k_VectorList &&
"Invalid access!");
743 return VectorList.Stride;
746 int getVectorIndex()
const {
747 assert(Kind == k_VectorIndex &&
"Invalid access!");
748 return VectorIndex.Val;
751 StringRef getSysReg()
const {
752 assert(Kind == k_SysReg &&
"Invalid access!");
753 return StringRef(SysReg.Data, SysReg.Length);
756 unsigned getSysCR()
const {
757 assert(Kind == k_SysCR &&
"Invalid access!");
761 unsigned getPrefetch()
const {
762 assert(Kind == k_Prefetch &&
"Invalid access!");
766 unsigned getPSBHint()
const {
767 assert(Kind == k_PSBHint &&
"Invalid access!");
771 unsigned getPHint()
const {
772 assert(Kind == k_PHint &&
"Invalid access!");
776 StringRef getPSBHintName()
const {
777 assert(Kind == k_PSBHint &&
"Invalid access!");
778 return StringRef(PSBHint.Data, PSBHint.Length);
781 StringRef getPHintName()
const {
782 assert(Kind == k_PHint &&
"Invalid access!");
783 return StringRef(PHint.Data, PHint.Length);
786 unsigned getBTIHint()
const {
787 assert(Kind == k_BTIHint &&
"Invalid access!");
791 StringRef getBTIHintName()
const {
792 assert(Kind == k_BTIHint &&
"Invalid access!");
793 return StringRef(BTIHint.Data, BTIHint.Length);
796 unsigned getCMHPriorityHint()
const {
797 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
798 return CMHPriorityHint.Val;
801 StringRef getCMHPriorityHintName()
const {
802 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
803 return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
806 unsigned getTIndexHint()
const {
807 assert(Kind == k_TIndexHint &&
"Invalid access!");
808 return TIndexHint.Val;
811 StringRef getTIndexHintName()
const {
812 assert(Kind == k_TIndexHint &&
"Invalid access!");
813 return StringRef(TIndexHint.Data, TIndexHint.Length);
816 StringRef getSVCR()
const {
817 assert(Kind == k_SVCR &&
"Invalid access!");
818 return StringRef(SVCR.Data, SVCR.Length);
821 StringRef getPrefetchName()
const {
822 assert(Kind == k_Prefetch &&
"Invalid access!");
827 if (Kind == k_ShiftExtend)
828 return ShiftExtend.Type;
829 if (Kind == k_Register)
830 return Reg.ShiftExtend.Type;
834 unsigned getShiftExtendAmount()
const {
835 if (Kind == k_ShiftExtend)
836 return ShiftExtend.Amount;
837 if (Kind == k_Register)
838 return Reg.ShiftExtend.Amount;
842 bool hasShiftExtendAmount()
const {
843 if (Kind == k_ShiftExtend)
844 return ShiftExtend.HasExplicitAmount;
845 if (Kind == k_Register)
846 return Reg.ShiftExtend.HasExplicitAmount;
850 bool isImm()
const override {
return Kind == k_Immediate; }
851 bool isMem()
const override {
return false; }
853 bool isUImm6()
const {
860 return (Val >= 0 && Val < 64);
863 template <
int W
idth>
bool isSImm()
const {
864 return bool(isSImmScaled<Width, 1>());
867 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
868 return isImmScaled<Bits, Scale>(
true);
871 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
872 DiagnosticPredicate isUImmScaled()
const {
873 if (IsRange && isImmRange() &&
874 (getLastImmVal() != getFirstImmVal() +
Offset))
877 return isImmScaled<Bits, Scale, IsRange>(
false);
880 template <
int Bits,
int Scale,
bool IsRange = false>
881 DiagnosticPredicate isImmScaled(
bool Signed)
const {
882 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
883 (isImmRange() && !IsRange))
888 Val = getFirstImmVal();
896 int64_t MinVal, MaxVal;
898 int64_t Shift =
Bits - 1;
899 MinVal = (int64_t(1) << Shift) * -Scale;
900 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
903 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
906 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
912 DiagnosticPredicate isSVEPattern()
const {
919 if (Val >= 0 && Val < 32)
924 DiagnosticPredicate isSVEVecLenSpecifier()
const {
931 if (Val >= 0 && Val <= 1)
936 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
940 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
969 template <
int Scale>
bool isUImm12Offset()
const {
975 return isSymbolicUImm12Offset(
getImm());
978 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
981 template <
int N,
int M>
982 bool isImmInRange()
const {
989 return (Val >=
N && Val <= M);
994 template <
typename T>
995 bool isLogicalImm()
const {
1004 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
1012 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
1014 bool isImmRange()
const {
return Kind == k_ImmRange; }
1019 template <
unsigned W
idth>
1020 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
1021 if (isShiftedImm() && Width == getShiftedImmShift())
1023 return std::make_pair(
CE->getValue(), Width);
1027 int64_t Val =
CE->getValue();
1028 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
1029 return std::make_pair(Val >> Width, Width);
1031 return std::make_pair(Val, 0u);
1037 bool isAddSubImm()
const {
1038 if (!isShiftedImm() && !isImm())
1044 if (isShiftedImm()) {
1045 unsigned Shift = ShiftedImm.ShiftAmount;
1046 Expr = ShiftedImm.Val;
1047 if (Shift != 0 && Shift != 12)
1056 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1072 if (
auto ShiftedVal = getShiftedVal<12>())
1073 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1080 bool isAddSubImmNeg()
const {
1081 if (!isShiftedImm() && !isImm())
1085 if (
auto ShiftedVal = getShiftedVal<12>())
1086 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1096 template <
typename T>
1097 DiagnosticPredicate isSVECpyImm()
const {
1101 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1102 std::is_same<int8_t, T>::value;
1103 if (
auto ShiftedImm = getShiftedVal<8>())
1104 if (!(IsByte && ShiftedImm->second) &&
1106 << ShiftedImm->second))
1115 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1119 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1120 std::is_same<int8_t, T>::value;
1121 if (
auto ShiftedImm = getShiftedVal<8>())
1122 if (!(IsByte && ShiftedImm->second) &&
1124 << ShiftedImm->second))
1130 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1131 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1136 bool isCondCode()
const {
return Kind == k_CondCode; }
1138 bool isSIMDImmType10()
const {
1148 bool isBranchTarget()
const {
1157 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1158 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1168 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1178 bool isMovWSymbolG3()
const {
1182 bool isMovWSymbolG2()
const {
1189 bool isMovWSymbolG1()
const {
1197 bool isMovWSymbolG0()
const {
1205 template<
int RegW
idth,
int Shift>
1206 bool isMOVZMovAlias()
const {
1207 if (!isImm())
return false;
1211 uint64_t
Value =
CE->getValue();
1220 template<
int RegW
idth,
int Shift>
1221 bool isMOVNMovAlias()
const {
1222 if (!isImm())
return false;
1225 if (!CE)
return false;
1226 uint64_t
Value =
CE->getValue();
1231 bool isFPImm()
const {
1232 return Kind == k_FPImm &&
1236 bool isBarrier()
const {
1237 return Kind == k_Barrier && !getBarriernXSModifier();
1239 bool isBarriernXS()
const {
1240 return Kind == k_Barrier && getBarriernXSModifier();
1242 bool isSysReg()
const {
return Kind == k_SysReg; }
1244 bool isMRSSystemRegister()
const {
1245 if (!isSysReg())
return false;
1247 return SysReg.MRSReg != -1U;
1250 bool isMSRSystemRegister()
const {
1251 if (!isSysReg())
return false;
1252 return SysReg.MSRReg != -1U;
1255 bool isSystemPStateFieldWithImm0_1()
const {
1256 if (!isSysReg())
return false;
1257 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1260 bool isSystemPStateFieldWithImm0_15()
const {
1263 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1266 bool isSVCR()
const {
1269 return SVCR.PStateField != -1U;
1272 bool isReg()
const override {
1273 return Kind == k_Register;
1276 bool isVectorList()
const {
return Kind == k_VectorList; }
1278 bool isScalarReg()
const {
1279 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1282 bool isNeonVectorReg()
const {
1283 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1286 bool isNeonVectorRegLo()
const {
1287 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1288 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1290 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1294 bool isNeonVectorReg0to7()
const {
1295 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1296 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1300 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1301 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1303 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1306 case AArch64::PPRRegClassID:
1307 case AArch64::PPR_3bRegClassID:
1308 case AArch64::PPR_p8to15RegClassID:
1309 case AArch64::PNRRegClassID:
1310 case AArch64::PNR_p8to15RegClassID:
1311 case AArch64::PPRorPNRRegClassID:
1312 RK = RegKind::SVEPredicateAsCounter;
1318 return (Kind == k_Register &&
Reg.Kind == RK) &&
1319 AArch64MCRegisterClasses[
Class].contains(
getReg());
1322 template <
unsigned Class>
bool isSVEVectorReg()
const {
1325 case AArch64::ZPRRegClassID:
1326 case AArch64::ZPR_3bRegClassID:
1327 case AArch64::ZPR_4bRegClassID:
1328 case AArch64::ZPRMul2_LoRegClassID:
1329 case AArch64::ZPRMul2_HiRegClassID:
1330 case AArch64::ZPR_KRegClassID:
1331 RK = RegKind::SVEDataVector;
1333 case AArch64::PPRRegClassID:
1334 case AArch64::PPR_3bRegClassID:
1335 case AArch64::PPR_p8to15RegClassID:
1336 case AArch64::PNRRegClassID:
1337 case AArch64::PNR_p8to15RegClassID:
1338 case AArch64::PPRorPNRRegClassID:
1339 RK = RegKind::SVEPredicateVector;
1345 return (Kind == k_Register &&
Reg.Kind == RK) &&
1346 AArch64MCRegisterClasses[
Class].contains(
getReg());
1349 template <
unsigned Class>
bool isFPRasZPR()
const {
1350 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1351 AArch64MCRegisterClasses[
Class].contains(
getReg());
1354 template <
int ElementW
idth,
unsigned Class>
1355 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1356 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1359 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1365 template <
int ElementW
idth,
unsigned Class>
1366 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1367 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1368 Reg.Kind != RegKind::SVEPredicateVector))
1371 if ((isSVEPredicateAsCounterReg<Class>() ||
1372 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1373 Reg.ElementWidth == ElementWidth)
1379 template <
int ElementW
idth,
unsigned Class>
1380 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1381 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1384 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1390 template <
int ElementW
idth,
unsigned Class>
1391 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1392 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1395 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1401 template <
int ElementWidth,
unsigned Class,
1403 bool ShiftWidthAlwaysSame>
1404 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1405 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1406 if (!VectorMatch.isMatch())
1412 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1415 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1418 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1424 bool isGPR32as64()
const {
1425 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1426 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.Reg);
1429 bool isGPR64as32()
const {
1430 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1431 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.Reg);
1434 bool isGPR64x8()
const {
1435 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1436 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1440 bool isWSeqPair()
const {
1441 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1442 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1446 bool isXSeqPair()
const {
1447 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1448 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1452 bool isSyspXzrPair()
const {
1453 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.Reg == AArch64::XZR;
1456 template<
int64_t Angle,
int64_t Remainder>
1457 DiagnosticPredicate isComplexRotation()
const {
1464 uint64_t
Value =
CE->getValue();
1466 if (
Value % Angle == Remainder &&
Value <= 270)
1471 template <
unsigned RegClassID>
bool isGPR64()
const {
1472 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1473 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1476 template <
unsigned RegClassID,
int ExtW
idth>
1477 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1478 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1481 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1482 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1489 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1490 bool isImplicitlyTypedVectorList()
const {
1491 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1492 VectorList.NumElements == 0 &&
1493 VectorList.RegisterKind == VectorKind &&
1494 (!IsConsecutive || (VectorList.Stride == 1));
1497 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1498 unsigned ElementWidth,
unsigned Stride = 1>
1499 bool isTypedVectorList()
const {
1500 if (Kind != k_VectorList)
1502 if (VectorList.Count != NumRegs)
1504 if (VectorList.RegisterKind != VectorKind)
1506 if (VectorList.ElementWidth != ElementWidth)
1508 if (VectorList.Stride != Stride)
1510 return VectorList.NumElements == NumElements;
1513 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1514 unsigned ElementWidth,
unsigned RegClass>
1515 DiagnosticPredicate isTypedVectorListMultiple()
const {
1517 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1520 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.Reg))
1525 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1526 unsigned ElementWidth>
1527 DiagnosticPredicate isTypedVectorListStrided()
const {
1528 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1529 ElementWidth, Stride>();
1532 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1533 ((VectorList.Reg >= AArch64::Z16) &&
1534 (VectorList.Reg < (AArch64::Z16 + Stride))))
1539 template <
int Min,
int Max>
1540 DiagnosticPredicate isVectorIndex()
const {
1541 if (Kind != k_VectorIndex)
1543 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1548 bool isToken()
const override {
return Kind == k_Token; }
1550 bool isTokenEqual(StringRef Str)
const {
1551 return Kind == k_Token &&
getToken() == Str;
1553 bool isSysCR()
const {
return Kind == k_SysCR; }
1554 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1555 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1556 bool isPHint()
const {
return Kind == k_PHint; }
1557 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1558 bool isCMHPriorityHint()
const {
return Kind == k_CMHPriorityHint; }
1559 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1560 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1561 bool isShifter()
const {
1562 if (!isShiftExtend())
1571 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1572 if (Kind != k_FPImm)
1575 if (getFPImmIsExact()) {
1577 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1581 APFloat RealVal(APFloat::IEEEdouble());
1583 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1584 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1587 if (
getFPImm().bitwiseIsEqual(RealVal))
1594 template <
unsigned ImmA,
unsigned ImmB>
1595 DiagnosticPredicate isExactFPImm()
const {
1597 if ((Res = isExactFPImm<ImmA>()))
1599 if ((Res = isExactFPImm<ImmB>()))
1604 bool isExtend()
const {
1605 if (!isShiftExtend())
1614 getShiftExtendAmount() <= 4;
1617 bool isExtend64()
const {
1627 bool isExtendLSL64()
const {
1633 getShiftExtendAmount() <= 4;
1636 bool isLSLImm3Shift()
const {
1637 if (!isShiftExtend())
1643 template<
int W
idth>
bool isMemXExtend()
const {
1648 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1649 getShiftExtendAmount() == 0);
1652 template<
int W
idth>
bool isMemWExtend()
const {
1657 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1658 getShiftExtendAmount() == 0);
1661 template <
unsigned w
idth>
1662 bool isArithmeticShifter()
const {
1672 template <
unsigned w
idth>
1673 bool isLogicalShifter()
const {
1681 getShiftExtendAmount() < width;
1684 bool isMovImm32Shifter()
const {
1692 uint64_t Val = getShiftExtendAmount();
1693 return (Val == 0 || Val == 16);
1696 bool isMovImm64Shifter()
const {
1704 uint64_t Val = getShiftExtendAmount();
1705 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1708 bool isLogicalVecShifter()
const {
1713 unsigned Shift = getShiftExtendAmount();
1715 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1718 bool isLogicalVecHalfWordShifter()
const {
1719 if (!isLogicalVecShifter())
1723 unsigned Shift = getShiftExtendAmount();
1725 (Shift == 0 || Shift == 8);
1728 bool isMoveVecShifter()
const {
1729 if (!isShiftExtend())
1733 unsigned Shift = getShiftExtendAmount();
1735 (Shift == 8 || Shift == 16);
1744 bool isSImm9OffsetFB()
const {
1745 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1748 bool isAdrpLabel()
const {
1755 int64_t Val =
CE->getValue();
1756 int64_t Min = - (4096 * (1LL << (21 - 1)));
1757 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1758 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1764 bool isAdrLabel()
const {
1771 int64_t Val =
CE->getValue();
1772 int64_t Min = - (1LL << (21 - 1));
1773 int64_t
Max = ((1LL << (21 - 1)) - 1);
1774 return Val >= Min && Val <=
Max;
1780 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1781 DiagnosticPredicate isMatrixRegOperand()
const {
1784 if (getMatrixKind() != Kind ||
1785 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1786 EltSize != getMatrixElementWidth())
1791 bool isPAuthPCRelLabel16Operand()
const {
1803 return (Val <= 0) && (Val > -(1 << 18));
1806 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1816 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1817 assert(
N == 1 &&
"Invalid number of operands!");
1821 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1822 assert(
N == 1 &&
"Invalid number of operands!");
1826 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1827 assert(
N == 1 &&
"Invalid number of operands!");
1829 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1831 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1838 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1839 assert(
N == 1 &&
"Invalid number of operands!");
1841 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1843 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1850 template <
int W
idth>
1851 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1854 case 8:
Base = AArch64::B0;
break;
1855 case 16:
Base = AArch64::H0;
break;
1856 case 32:
Base = AArch64::S0;
break;
1857 case 64:
Base = AArch64::D0;
break;
1858 case 128:
Base = AArch64::Q0;
break;
1865 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1866 assert(
N == 1 &&
"Invalid number of operands!");
1869 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1870 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1874 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1875 assert(
N == 1 &&
"Invalid number of operands!");
1880 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1881 assert(
N == 1 &&
"Invalid number of operands!");
1883 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1887 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1888 assert(
N == 1 &&
"Invalid number of operands!");
1890 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1894 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1895 assert(
N == 1 &&
"Invalid number of operands!");
1899 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1900 assert(
N == 1 &&
"Invalid number of operands!");
1904 enum VecListIndexType {
1905 VecListIdx_DReg = 0,
1906 VecListIdx_QReg = 1,
1907 VecListIdx_ZReg = 2,
1908 VecListIdx_PReg = 3,
1911 template <VecListIndexType RegTy,
unsigned NumRegs,
1912 bool IsConsecutive =
false>
1913 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1914 assert(
N == 1 &&
"Invalid number of operands!");
1915 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1916 "Expected consecutive registers");
1917 static const unsigned FirstRegs[][5] = {
1919 AArch64::D0, AArch64::D0_D1,
1920 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1922 AArch64::Q0, AArch64::Q0_Q1,
1923 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1925 AArch64::Z0, AArch64::Z0_Z1,
1926 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1928 AArch64::P0, AArch64::P0_P1 }
1931 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1932 " NumRegs must be <= 4 for ZRegs");
1934 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1935 " NumRegs must be <= 2 for PRegs");
1937 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1939 FirstRegs[(
unsigned)RegTy][0]));
1942 template <
unsigned NumRegs>
1943 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1944 assert(
N == 1 &&
"Invalid number of operands!");
1945 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1949 if (getVectorListStart() < AArch64::Z16) {
1950 assert((getVectorListStart() < AArch64::Z8) &&
1951 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1953 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1955 assert((getVectorListStart() < AArch64::Z24) &&
1956 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1958 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1962 if (getVectorListStart() < AArch64::Z16) {
1963 assert((getVectorListStart() < AArch64::Z4) &&
1964 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1966 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1968 assert((getVectorListStart() < AArch64::Z20) &&
1969 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1971 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1979 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1980 assert(
N == 1 &&
"Invalid number of operands!");
1981 unsigned RegMask = getMatrixTileListRegMask();
1982 assert(RegMask <= 0xFF &&
"Invalid mask!");
1986 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1987 assert(
N == 1 &&
"Invalid number of operands!");
1991 template <
unsigned ImmIs0,
unsigned ImmIs1>
1992 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1993 assert(
N == 1 &&
"Invalid number of operands!");
1994 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1998 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1999 assert(
N == 1 &&
"Invalid number of operands!");
2006 template <
int Shift>
2007 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2008 assert(
N == 2 &&
"Invalid number of operands!");
2009 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2012 }
else if (isShiftedImm()) {
2013 addExpr(Inst, getShiftedImmVal());
2021 template <
int Shift>
2022 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2023 assert(
N == 2 &&
"Invalid number of operands!");
2024 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2031 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2032 assert(
N == 1 &&
"Invalid number of operands!");
2036 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
2037 assert(
N == 1 &&
"Invalid number of operands!");
2045 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2046 addImmOperands(Inst,
N);
2050 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
2051 assert(
N == 1 &&
"Invalid number of operands!");
2061 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2062 assert(
N == 1 &&
"Invalid number of operands!");
2067 template <
int Scale>
2068 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2069 assert(
N == 1 &&
"Invalid number of operands!");
2074 template <
int Scale>
2075 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2076 assert(
N == 1 &&
"Invalid number of operands!");
2080 template <
typename T>
2081 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2082 assert(
N == 1 &&
"Invalid number of operands!");
2084 std::make_unsigned_t<T> Val = MCE->
getValue();
2089 template <
typename T>
2090 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2091 assert(
N == 1 &&
"Invalid number of operands!");
2093 std::make_unsigned_t<T> Val = ~MCE->getValue();
2098 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2099 assert(
N == 1 &&
"Invalid number of operands!");
2105 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2109 assert(
N == 1 &&
"Invalid number of operands!");
2115 assert(MCE &&
"Invalid constant immediate operand!");
2119 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2123 assert(
N == 1 &&
"Invalid number of operands!");
2132 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2142 assert(MCE &&
"Invalid constant immediate operand!");
2146 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2150 assert(
N == 1 &&
"Invalid number of operands!");
2156 assert(MCE &&
"Invalid constant immediate operand!");
2160 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2164 assert(
N == 1 &&
"Invalid number of operands!");
2170 assert(MCE &&
"Invalid constant immediate operand!");
2174 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2175 assert(
N == 1 &&
"Invalid number of operands!");
2180 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2181 assert(
N == 1 &&
"Invalid number of operands!");
2185 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2186 assert(
N == 1 &&
"Invalid number of operands!");
2190 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2191 assert(
N == 1 &&
"Invalid number of operands!");
2196 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2197 assert(
N == 1 &&
"Invalid number of operands!");
2202 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2203 assert(
N == 1 &&
"Invalid number of operands!");
2208 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2209 assert(
N == 1 &&
"Invalid number of operands!");
2214 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2215 assert(
N == 1 &&
"Invalid number of operands!");
2220 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2221 assert(
N == 1 &&
"Invalid number of operands!");
2225 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2226 assert(
N == 1 &&
"Invalid number of operands!");
2230 void addPSBHintOperands(MCInst &Inst,
unsigned N)
const {
2231 assert(
N == 1 &&
"Invalid number of operands!");
2235 void addPHintOperands(MCInst &Inst,
unsigned N)
const {
2236 assert(
N == 1 &&
"Invalid number of operands!");
2240 void addBTIHintOperands(MCInst &Inst,
unsigned N)
const {
2241 assert(
N == 1 &&
"Invalid number of operands!");
2245 void addCMHPriorityHintOperands(MCInst &Inst,
unsigned N)
const {
2246 assert(
N == 1 &&
"Invalid number of operands!");
2250 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2251 assert(
N == 1 &&
"Invalid number of operands!");
2255 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2256 assert(
N == 1 &&
"Invalid number of operands!");
2262 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2263 assert(
N == 1 &&
"Invalid number of operands!");
2264 unsigned Imm = getShiftExtendAmount();
2268 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2269 assert(
N == 1 &&
"Invalid number of operands!");
2274 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2277 if (
Reg != AArch64::XZR)
2283 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2284 assert(
N == 1 &&
"Invalid number of operands!");
2291 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2292 assert(
N == 1 &&
"Invalid number of operands!");
2299 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2300 assert(
N == 2 &&
"Invalid number of operands!");
2311 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2312 assert(
N == 2 &&
"Invalid number of operands!");
2320 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2321 assert(
N == 1 &&
"Invalid number of operands!");
2325 uint64_t
Value =
CE->getValue();
2333 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2334 assert(
N == 1 &&
"Invalid number of operands!");
2337 uint64_t
Value =
CE->getValue();
2341 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2342 assert(
N == 1 &&
"Invalid number of operands!");
2347 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2348 assert(
N == 1 &&
"Invalid number of operands!");
2353 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2355 static std::unique_ptr<AArch64Operand>
2356 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2357 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2358 Op->Tok.Data = Str.data();
2359 Op->Tok.Length = Str.size();
2360 Op->Tok.IsSuffix = IsSuffix;
2366 static std::unique_ptr<AArch64Operand>
2367 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2368 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2370 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2371 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2373 Op->Reg.Kind = Kind;
2374 Op->Reg.ElementWidth = 0;
2375 Op->Reg.EqualityTy = EqTy;
2376 Op->Reg.ShiftExtend.Type = ExtTy;
2377 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2378 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2384 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2385 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2387 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2388 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2389 Kind == RegKind::SVEPredicateVector ||
2390 Kind == RegKind::SVEPredicateAsCounter) &&
2391 "Invalid vector kind");
2392 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2394 Op->Reg.ElementWidth = ElementWidth;
2398 static std::unique_ptr<AArch64Operand>
2399 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2400 unsigned NumElements,
unsigned ElementWidth,
2401 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2402 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2403 Op->VectorList.Reg =
Reg;
2405 Op->VectorList.Stride = Stride;
2406 Op->VectorList.NumElements = NumElements;
2407 Op->VectorList.ElementWidth = ElementWidth;
2408 Op->VectorList.RegisterKind = RegisterKind;
2414 static std::unique_ptr<AArch64Operand>
2415 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2416 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2417 Op->VectorIndex.Val = Idx;
2423 static std::unique_ptr<AArch64Operand>
2424 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2425 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2426 Op->MatrixTileList.RegMask = RegMask;
2432 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2433 const unsigned ElementWidth) {
2434 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2436 {{0, AArch64::ZAB0},
2437 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2438 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2439 {{8, AArch64::ZAB0},
2440 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2441 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2442 {{16, AArch64::ZAH0},
2443 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2444 {{16, AArch64::ZAH1},
2445 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2446 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2447 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2448 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2449 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2452 if (ElementWidth == 64)
2455 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2456 assert(!Regs.empty() &&
"Invalid tile or element width!");
2461 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2462 SMLoc
E, MCContext &Ctx) {
2463 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2470 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2471 unsigned ShiftAmount,
2474 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2475 Op->ShiftedImm .Val = Val;
2476 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2482 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2483 unsigned Last, SMLoc S,
2486 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2488 Op->ImmRange.Last =
Last;
2493 static std::unique_ptr<AArch64Operand>
2495 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2496 Op->CondCode.Code =
Code;
2502 static std::unique_ptr<AArch64Operand>
2503 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2504 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2506 Op->FPImm.IsExact = IsExact;
2512 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2516 bool HasnXSModifier) {
2517 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2518 Op->Barrier.Val = Val;
2519 Op->Barrier.Data = Str.data();
2520 Op->Barrier.Length = Str.size();
2521 Op->Barrier.HasnXSModifier = HasnXSModifier;
2527 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2530 uint32_t PStateField,
2532 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2533 Op->SysReg.Data = Str.data();
2534 Op->SysReg.Length = Str.size();
2535 Op->SysReg.MRSReg = MRSReg;
2536 Op->SysReg.MSRReg = MSRReg;
2537 Op->SysReg.PStateField = PStateField;
2543 static std::unique_ptr<AArch64Operand>
2544 CreatePHintInst(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2545 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2546 Op->PHint.Val = Val;
2547 Op->PHint.Data = Str.data();
2548 Op->PHint.Length = Str.size();
2554 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2555 SMLoc
E, MCContext &Ctx) {
2556 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2557 Op->SysCRImm.Val = Val;
2563 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2567 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2568 Op->Prefetch.Val = Val;
2569 Op->Barrier.Data = Str.data();
2570 Op->Barrier.Length = Str.size();
2576 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2580 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2581 Op->PSBHint.Val = Val;
2582 Op->PSBHint.Data = Str.data();
2583 Op->PSBHint.Length = Str.size();
2589 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2593 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2594 Op->BTIHint.Val = Val | 32;
2595 Op->BTIHint.Data = Str.data();
2596 Op->BTIHint.Length = Str.size();
2602 static std::unique_ptr<AArch64Operand>
2603 CreateCMHPriorityHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2604 auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
2605 Op->CMHPriorityHint.Val = Val;
2606 Op->CMHPriorityHint.Data = Str.data();
2607 Op->CMHPriorityHint.Length = Str.size();
2613 static std::unique_ptr<AArch64Operand>
2614 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2615 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2616 Op->TIndexHint.Val = Val;
2617 Op->TIndexHint.Data = Str.data();
2618 Op->TIndexHint.Length = Str.size();
2624 static std::unique_ptr<AArch64Operand>
2625 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2626 SMLoc S, SMLoc
E, MCContext &Ctx) {
2627 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2628 Op->MatrixReg.Reg =
Reg;
2629 Op->MatrixReg.ElementWidth = ElementWidth;
2630 Op->MatrixReg.Kind = Kind;
2636 static std::unique_ptr<AArch64Operand>
2637 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2638 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2639 Op->SVCR.PStateField = PStateField;
2640 Op->SVCR.Data = Str.data();
2641 Op->SVCR.Length = Str.size();
2647 static std::unique_ptr<AArch64Operand>
2649 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2650 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2651 Op->ShiftExtend.Type = ShOp;
2652 Op->ShiftExtend.Amount = Val;
2653 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2665 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2666 if (!getFPImmIsExact())
2671 StringRef
Name = getBarrierName();
2673 OS <<
"<barrier " <<
Name <<
">";
2675 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2681 case k_ShiftedImm: {
2682 unsigned Shift = getShiftedImmShift();
2683 OS <<
"<shiftedimm ";
2690 OS << getFirstImmVal();
2691 OS <<
":" << getLastImmVal() <<
">";
2697 case k_VectorList: {
2698 OS <<
"<vectorlist ";
2699 MCRegister
Reg = getVectorListStart();
2700 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2701 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2706 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2709 OS <<
"<sysreg: " << getSysReg() <<
'>';
2715 OS <<
"c" << getSysCR();
2718 StringRef
Name = getPrefetchName();
2720 OS <<
"<prfop " <<
Name <<
">";
2722 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2726 OS << getPSBHintName();
2729 OS << getPHintName();
2732 OS << getBTIHintName();
2734 case k_CMHPriorityHint:
2735 OS << getCMHPriorityHintName();
2738 OS << getTIndexHintName();
2740 case k_MatrixRegister:
2741 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2743 case k_MatrixTileList: {
2744 OS <<
"<matrixlist ";
2745 unsigned RegMask = getMatrixTileListRegMask();
2746 unsigned MaxBits = 8;
2747 for (
unsigned I = MaxBits;
I > 0; --
I)
2748 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2757 OS <<
"<register " <<
getReg().
id() <<
">";
2758 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2763 << getShiftExtendAmount();
2764 if (!hasShiftExtendAmount())
2780 .
Case(
"v0", AArch64::Q0)
2781 .
Case(
"v1", AArch64::Q1)
2782 .
Case(
"v2", AArch64::Q2)
2783 .
Case(
"v3", AArch64::Q3)
2784 .
Case(
"v4", AArch64::Q4)
2785 .
Case(
"v5", AArch64::Q5)
2786 .
Case(
"v6", AArch64::Q6)
2787 .
Case(
"v7", AArch64::Q7)
2788 .
Case(
"v8", AArch64::Q8)
2789 .
Case(
"v9", AArch64::Q9)
2790 .
Case(
"v10", AArch64::Q10)
2791 .
Case(
"v11", AArch64::Q11)
2792 .
Case(
"v12", AArch64::Q12)
2793 .
Case(
"v13", AArch64::Q13)
2794 .
Case(
"v14", AArch64::Q14)
2795 .
Case(
"v15", AArch64::Q15)
2796 .
Case(
"v16", AArch64::Q16)
2797 .
Case(
"v17", AArch64::Q17)
2798 .
Case(
"v18", AArch64::Q18)
2799 .
Case(
"v19", AArch64::Q19)
2800 .
Case(
"v20", AArch64::Q20)
2801 .
Case(
"v21", AArch64::Q21)
2802 .
Case(
"v22", AArch64::Q22)
2803 .
Case(
"v23", AArch64::Q23)
2804 .
Case(
"v24", AArch64::Q24)
2805 .
Case(
"v25", AArch64::Q25)
2806 .
Case(
"v26", AArch64::Q26)
2807 .
Case(
"v27", AArch64::Q27)
2808 .
Case(
"v28", AArch64::Q28)
2809 .
Case(
"v29", AArch64::Q29)
2810 .
Case(
"v30", AArch64::Q30)
2811 .
Case(
"v31", AArch64::Q31)
2820 RegKind VectorKind) {
2821 std::pair<int, int> Res = {-1, -1};
2823 switch (VectorKind) {
2824 case RegKind::NeonVector:
2827 .Case(
".1d", {1, 64})
2828 .Case(
".1q", {1, 128})
2830 .Case(
".2h", {2, 16})
2831 .Case(
".2b", {2, 8})
2832 .Case(
".2s", {2, 32})
2833 .Case(
".2d", {2, 64})
2836 .Case(
".4b", {4, 8})
2837 .Case(
".4h", {4, 16})
2838 .Case(
".4s", {4, 32})
2839 .Case(
".8b", {8, 8})
2840 .Case(
".8h", {8, 16})
2841 .Case(
".16b", {16, 8})
2846 .Case(
".h", {0, 16})
2847 .Case(
".s", {0, 32})
2848 .Case(
".d", {0, 64})
2851 case RegKind::SVEPredicateAsCounter:
2852 case RegKind::SVEPredicateVector:
2853 case RegKind::SVEDataVector:
2854 case RegKind::Matrix:
2858 .Case(
".h", {0, 16})
2859 .Case(
".s", {0, 32})
2860 .Case(
".d", {0, 64})
2861 .Case(
".q", {0, 128})
2868 if (Res == std::make_pair(-1, -1))
2869 return std::nullopt;
2871 return std::optional<std::pair<int, int>>(Res);
2880 .
Case(
"z0", AArch64::Z0)
2881 .
Case(
"z1", AArch64::Z1)
2882 .
Case(
"z2", AArch64::Z2)
2883 .
Case(
"z3", AArch64::Z3)
2884 .
Case(
"z4", AArch64::Z4)
2885 .
Case(
"z5", AArch64::Z5)
2886 .
Case(
"z6", AArch64::Z6)
2887 .
Case(
"z7", AArch64::Z7)
2888 .
Case(
"z8", AArch64::Z8)
2889 .
Case(
"z9", AArch64::Z9)
2890 .
Case(
"z10", AArch64::Z10)
2891 .
Case(
"z11", AArch64::Z11)
2892 .
Case(
"z12", AArch64::Z12)
2893 .
Case(
"z13", AArch64::Z13)
2894 .
Case(
"z14", AArch64::Z14)
2895 .
Case(
"z15", AArch64::Z15)
2896 .
Case(
"z16", AArch64::Z16)
2897 .
Case(
"z17", AArch64::Z17)
2898 .
Case(
"z18", AArch64::Z18)
2899 .
Case(
"z19", AArch64::Z19)
2900 .
Case(
"z20", AArch64::Z20)
2901 .
Case(
"z21", AArch64::Z21)
2902 .
Case(
"z22", AArch64::Z22)
2903 .
Case(
"z23", AArch64::Z23)
2904 .
Case(
"z24", AArch64::Z24)
2905 .
Case(
"z25", AArch64::Z25)
2906 .
Case(
"z26", AArch64::Z26)
2907 .
Case(
"z27", AArch64::Z27)
2908 .
Case(
"z28", AArch64::Z28)
2909 .
Case(
"z29", AArch64::Z29)
2910 .
Case(
"z30", AArch64::Z30)
2911 .
Case(
"z31", AArch64::Z31)
2917 .
Case(
"p0", AArch64::P0)
2918 .
Case(
"p1", AArch64::P1)
2919 .
Case(
"p2", AArch64::P2)
2920 .
Case(
"p3", AArch64::P3)
2921 .
Case(
"p4", AArch64::P4)
2922 .
Case(
"p5", AArch64::P5)
2923 .
Case(
"p6", AArch64::P6)
2924 .
Case(
"p7", AArch64::P7)
2925 .
Case(
"p8", AArch64::P8)
2926 .
Case(
"p9", AArch64::P9)
2927 .
Case(
"p10", AArch64::P10)
2928 .
Case(
"p11", AArch64::P11)
2929 .
Case(
"p12", AArch64::P12)
2930 .
Case(
"p13", AArch64::P13)
2931 .
Case(
"p14", AArch64::P14)
2932 .
Case(
"p15", AArch64::P15)
2938 .
Case(
"pn0", AArch64::PN0)
2939 .
Case(
"pn1", AArch64::PN1)
2940 .
Case(
"pn2", AArch64::PN2)
2941 .
Case(
"pn3", AArch64::PN3)
2942 .
Case(
"pn4", AArch64::PN4)
2943 .
Case(
"pn5", AArch64::PN5)
2944 .
Case(
"pn6", AArch64::PN6)
2945 .
Case(
"pn7", AArch64::PN7)
2946 .
Case(
"pn8", AArch64::PN8)
2947 .
Case(
"pn9", AArch64::PN9)
2948 .
Case(
"pn10", AArch64::PN10)
2949 .
Case(
"pn11", AArch64::PN11)
2950 .
Case(
"pn12", AArch64::PN12)
2951 .
Case(
"pn13", AArch64::PN13)
2952 .
Case(
"pn14", AArch64::PN14)
2953 .
Case(
"pn15", AArch64::PN15)
2959 .
Case(
"za0.d", AArch64::ZAD0)
2960 .
Case(
"za1.d", AArch64::ZAD1)
2961 .
Case(
"za2.d", AArch64::ZAD2)
2962 .
Case(
"za3.d", AArch64::ZAD3)
2963 .
Case(
"za4.d", AArch64::ZAD4)
2964 .
Case(
"za5.d", AArch64::ZAD5)
2965 .
Case(
"za6.d", AArch64::ZAD6)
2966 .
Case(
"za7.d", AArch64::ZAD7)
2967 .
Case(
"za0.s", AArch64::ZAS0)
2968 .
Case(
"za1.s", AArch64::ZAS1)
2969 .
Case(
"za2.s", AArch64::ZAS2)
2970 .
Case(
"za3.s", AArch64::ZAS3)
2971 .
Case(
"za0.h", AArch64::ZAH0)
2972 .
Case(
"za1.h", AArch64::ZAH1)
2973 .
Case(
"za0.b", AArch64::ZAB0)
2979 .
Case(
"za", AArch64::ZA)
2980 .
Case(
"za0.q", AArch64::ZAQ0)
2981 .
Case(
"za1.q", AArch64::ZAQ1)
2982 .
Case(
"za2.q", AArch64::ZAQ2)
2983 .
Case(
"za3.q", AArch64::ZAQ3)
2984 .
Case(
"za4.q", AArch64::ZAQ4)
2985 .
Case(
"za5.q", AArch64::ZAQ5)
2986 .
Case(
"za6.q", AArch64::ZAQ6)
2987 .
Case(
"za7.q", AArch64::ZAQ7)
2988 .
Case(
"za8.q", AArch64::ZAQ8)
2989 .
Case(
"za9.q", AArch64::ZAQ9)
2990 .
Case(
"za10.q", AArch64::ZAQ10)
2991 .
Case(
"za11.q", AArch64::ZAQ11)
2992 .
Case(
"za12.q", AArch64::ZAQ12)
2993 .
Case(
"za13.q", AArch64::ZAQ13)
2994 .
Case(
"za14.q", AArch64::ZAQ14)
2995 .
Case(
"za15.q", AArch64::ZAQ15)
2996 .
Case(
"za0.d", AArch64::ZAD0)
2997 .
Case(
"za1.d", AArch64::ZAD1)
2998 .
Case(
"za2.d", AArch64::ZAD2)
2999 .
Case(
"za3.d", AArch64::ZAD3)
3000 .
Case(
"za4.d", AArch64::ZAD4)
3001 .
Case(
"za5.d", AArch64::ZAD5)
3002 .
Case(
"za6.d", AArch64::ZAD6)
3003 .
Case(
"za7.d", AArch64::ZAD7)
3004 .
Case(
"za0.s", AArch64::ZAS0)
3005 .
Case(
"za1.s", AArch64::ZAS1)
3006 .
Case(
"za2.s", AArch64::ZAS2)
3007 .
Case(
"za3.s", AArch64::ZAS3)
3008 .
Case(
"za0.h", AArch64::ZAH0)
3009 .
Case(
"za1.h", AArch64::ZAH1)
3010 .
Case(
"za0.b", AArch64::ZAB0)
3011 .
Case(
"za0h.q", AArch64::ZAQ0)
3012 .
Case(
"za1h.q", AArch64::ZAQ1)
3013 .
Case(
"za2h.q", AArch64::ZAQ2)
3014 .
Case(
"za3h.q", AArch64::ZAQ3)
3015 .
Case(
"za4h.q", AArch64::ZAQ4)
3016 .
Case(
"za5h.q", AArch64::ZAQ5)
3017 .
Case(
"za6h.q", AArch64::ZAQ6)
3018 .
Case(
"za7h.q", AArch64::ZAQ7)
3019 .
Case(
"za8h.q", AArch64::ZAQ8)
3020 .
Case(
"za9h.q", AArch64::ZAQ9)
3021 .
Case(
"za10h.q", AArch64::ZAQ10)
3022 .
Case(
"za11h.q", AArch64::ZAQ11)
3023 .
Case(
"za12h.q", AArch64::ZAQ12)
3024 .
Case(
"za13h.q", AArch64::ZAQ13)
3025 .
Case(
"za14h.q", AArch64::ZAQ14)
3026 .
Case(
"za15h.q", AArch64::ZAQ15)
3027 .
Case(
"za0h.d", AArch64::ZAD0)
3028 .
Case(
"za1h.d", AArch64::ZAD1)
3029 .
Case(
"za2h.d", AArch64::ZAD2)
3030 .
Case(
"za3h.d", AArch64::ZAD3)
3031 .
Case(
"za4h.d", AArch64::ZAD4)
3032 .
Case(
"za5h.d", AArch64::ZAD5)
3033 .
Case(
"za6h.d", AArch64::ZAD6)
3034 .
Case(
"za7h.d", AArch64::ZAD7)
3035 .
Case(
"za0h.s", AArch64::ZAS0)
3036 .
Case(
"za1h.s", AArch64::ZAS1)
3037 .
Case(
"za2h.s", AArch64::ZAS2)
3038 .
Case(
"za3h.s", AArch64::ZAS3)
3039 .
Case(
"za0h.h", AArch64::ZAH0)
3040 .
Case(
"za1h.h", AArch64::ZAH1)
3041 .
Case(
"za0h.b", AArch64::ZAB0)
3042 .
Case(
"za0v.q", AArch64::ZAQ0)
3043 .
Case(
"za1v.q", AArch64::ZAQ1)
3044 .
Case(
"za2v.q", AArch64::ZAQ2)
3045 .
Case(
"za3v.q", AArch64::ZAQ3)
3046 .
Case(
"za4v.q", AArch64::ZAQ4)
3047 .
Case(
"za5v.q", AArch64::ZAQ5)
3048 .
Case(
"za6v.q", AArch64::ZAQ6)
3049 .
Case(
"za7v.q", AArch64::ZAQ7)
3050 .
Case(
"za8v.q", AArch64::ZAQ8)
3051 .
Case(
"za9v.q", AArch64::ZAQ9)
3052 .
Case(
"za10v.q", AArch64::ZAQ10)
3053 .
Case(
"za11v.q", AArch64::ZAQ11)
3054 .
Case(
"za12v.q", AArch64::ZAQ12)
3055 .
Case(
"za13v.q", AArch64::ZAQ13)
3056 .
Case(
"za14v.q", AArch64::ZAQ14)
3057 .
Case(
"za15v.q", AArch64::ZAQ15)
3058 .
Case(
"za0v.d", AArch64::ZAD0)
3059 .
Case(
"za1v.d", AArch64::ZAD1)
3060 .
Case(
"za2v.d", AArch64::ZAD2)
3061 .
Case(
"za3v.d", AArch64::ZAD3)
3062 .
Case(
"za4v.d", AArch64::ZAD4)
3063 .
Case(
"za5v.d", AArch64::ZAD5)
3064 .
Case(
"za6v.d", AArch64::ZAD6)
3065 .
Case(
"za7v.d", AArch64::ZAD7)
3066 .
Case(
"za0v.s", AArch64::ZAS0)
3067 .
Case(
"za1v.s", AArch64::ZAS1)
3068 .
Case(
"za2v.s", AArch64::ZAS2)
3069 .
Case(
"za3v.s", AArch64::ZAS3)
3070 .
Case(
"za0v.h", AArch64::ZAH0)
3071 .
Case(
"za1v.h", AArch64::ZAH1)
3072 .
Case(
"za0v.b", AArch64::ZAB0)
3076bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3078 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3081ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3083 StartLoc = getLoc();
3084 ParseStatus Res = tryParseScalarRegister(
Reg);
3090MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
3092 MCRegister
Reg = MCRegister();
3094 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
3097 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
3100 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
3103 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
3106 return Kind == RegKind::Matrix ?
Reg : MCRegister();
3108 if (
Name.equals_insensitive(
"zt0"))
3109 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
3113 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
3117 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
3118 .Case(
"fp", AArch64::FP)
3119 .Case(
"lr", AArch64::LR)
3120 .Case(
"x31", AArch64::XZR)
3121 .Case(
"w31", AArch64::WZR)
3123 return Kind == RegKind::Scalar ?
Reg : MCRegister();
3129 if (Entry == RegisterReqs.
end())
3130 return MCRegister();
3133 if (Kind ==
Entry->getValue().first)
3139unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3141 case RegKind::Scalar:
3142 case RegKind::NeonVector:
3143 case RegKind::SVEDataVector:
3145 case RegKind::Matrix:
3146 case RegKind::SVEPredicateVector:
3147 case RegKind::SVEPredicateAsCounter:
3149 case RegKind::LookupTable:
3158ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3159 const AsmToken &Tok = getTok();
3164 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3174ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3178 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3181 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3182 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3186 if (BadNum || CRNum > 15)
3187 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3191 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3196ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3198 const AsmToken &Tok = getTok();
3200 unsigned MaxVal = 63;
3205 const MCExpr *ImmVal;
3206 if (getParser().parseExpression(ImmVal))
3211 return TokError(
"immediate value expected for prefetch operand");
3214 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3217 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3218 Operands.
push_back(AArch64Operand::CreatePrefetch(
3219 prfop, RPRFM ? RPRFM->Name :
"", S,
getContext()));
3224 return TokError(
"prefetch hint expected");
3226 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3228 return TokError(
"prefetch hint expected");
3230 Operands.
push_back(AArch64Operand::CreatePrefetch(
3237template <
bool IsSVEPrefetch>
3238ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3240 const AsmToken &Tok = getTok();
3242 auto LookupByName = [](StringRef
N) {
3243 if (IsSVEPrefetch) {
3244 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3245 return std::optional<unsigned>(Res->Encoding);
3246 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3247 return std::optional<unsigned>(Res->Encoding);
3248 return std::optional<unsigned>();
3251 auto LookupByEncoding = [](
unsigned E) {
3252 if (IsSVEPrefetch) {
3253 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3254 return std::optional<StringRef>(Res->Name);
3255 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3256 return std::optional<StringRef>(Res->Name);
3257 return std::optional<StringRef>();
3259 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3265 const MCExpr *ImmVal;
3266 if (getParser().parseExpression(ImmVal))
3271 return TokError(
"immediate value expected for prefetch operand");
3274 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3277 auto PRFM = LookupByEncoding(MCE->
getValue());
3278 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3284 return TokError(
"prefetch hint expected");
3286 auto PRFM = LookupByName(Tok.
getString());
3288 return TokError(
"prefetch hint expected");
3290 Operands.
push_back(AArch64Operand::CreatePrefetch(
3297ParseStatus AArch64AsmParser::tryParsePSBHint(
OperandVector &Operands) {
3299 const AsmToken &Tok = getTok();
3301 return TokError(
"invalid operand for instruction");
3303 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3305 return TokError(
"invalid operand for instruction");
3307 Operands.
push_back(AArch64Operand::CreatePSBHint(
3313ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3314 SMLoc StartLoc = getLoc();
3320 auto RegTok = getTok();
3321 if (!tryParseScalarRegister(RegNum).isSuccess())
3324 if (RegNum != AArch64::XZR) {
3325 getLexer().UnLex(RegTok);
3332 if (!tryParseScalarRegister(RegNum).isSuccess())
3333 return TokError(
"expected register operand");
3335 if (RegNum != AArch64::XZR)
3336 return TokError(
"xzr must be followed by xzr");
3340 Operands.
push_back(AArch64Operand::CreateReg(
3341 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3347ParseStatus AArch64AsmParser::tryParseBTIHint(
OperandVector &Operands) {
3349 const AsmToken &Tok = getTok();
3351 return TokError(
"invalid operand for instruction");
3353 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3355 return TokError(
"invalid operand for instruction");
3357 Operands.
push_back(AArch64Operand::CreateBTIHint(
3364ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(
OperandVector &Operands) {
3366 const AsmToken &Tok = getTok();
3368 return TokError(
"invalid operand for instruction");
3371 AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.
getString());
3373 return TokError(
"invalid operand for instruction");
3375 Operands.
push_back(AArch64Operand::CreateCMHPriorityHint(
3382ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3384 const AsmToken &Tok = getTok();
3386 return TokError(
"invalid operand for instruction");
3388 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3390 return TokError(
"invalid operand for instruction");
3392 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3400ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3402 const MCExpr *Expr =
nullptr;
3408 if (parseSymbolicImmVal(Expr))
3414 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3423 return Error(S,
"gotpage label reference not allowed an addend");
3435 return Error(S,
"page or gotpage label reference expected");
3450ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3452 const MCExpr *Expr =
nullptr;
3461 if (parseSymbolicImmVal(Expr))
3467 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3479 return Error(S,
"unexpected adr label");
3489template <
bool AddFPZeroAsLiteral>
3490ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3498 const AsmToken &Tok = getTok();
3502 return TokError(
"invalid floating point immediate");
3507 if (Tok.
getIntVal() > 255 || isNegative)
3508 return TokError(
"encoded floating point value out of range");
3512 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3515 APFloat RealVal(APFloat::IEEEdouble());
3517 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3519 return TokError(
"invalid floating point representation");
3522 RealVal.changeSign();
3524 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3528 Operands.
push_back(AArch64Operand::CreateFPImm(
3529 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3540AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3551 return tryParseImmRange(Operands);
3553 const MCExpr *
Imm =
nullptr;
3554 if (parseSymbolicImmVal(Imm))
3558 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3565 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3567 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3569 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3575 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3576 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3584 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3586 int64_t ShiftAmount = getTok().getIntVal();
3588 if (ShiftAmount < 0)
3589 return Error(getLoc(),
"positive shift amount required");
3593 if (ShiftAmount == 0 && Imm !=
nullptr) {
3595 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3599 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3607AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3641 Suggestion =
"nfrst";
3647bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3648 bool invertCondCode) {
3650 const AsmToken &Tok = getTok();
3654 std::string Suggestion;
3657 std::string Msg =
"invalid condition code";
3658 if (!Suggestion.empty())
3659 Msg +=
", did you mean " + Suggestion +
"?";
3660 return TokError(Msg);
3664 if (invertCondCode) {
3666 return TokError(
"condition codes AL and NV are invalid for this instruction");
3671 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3675ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3676 const AsmToken &Tok = getTok();
3680 return TokError(
"invalid operand for instruction");
3682 unsigned PStateImm = -1;
3683 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3686 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3687 PStateImm = SVCR->Encoding;
3695ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3696 const AsmToken &Tok = getTok();
3701 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3703 unsigned ElementWidth = 0;
3704 auto DotPosition =
Name.find(
'.');
3706 const auto &KindRes =
3710 "Expected the register to be followed by element width suffix");
3711 ElementWidth = KindRes->second;
3713 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3714 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3719 if (parseOperand(Operands,
false,
false))
3726 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3730 size_t DotPosition =
Name.find(
'.');
3733 StringRef Head =
Name.take_front(DotPosition);
3734 StringRef
Tail =
Name.drop_front(DotPosition);
3735 StringRef RowOrColumn = Head.
take_back();
3737 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3738 .Case(
"h", MatrixKind::Row)
3739 .Case(
"v", MatrixKind::Col)
3740 .Default(MatrixKind::Tile);
3746 "Expected the register to be followed by element width suffix");
3747 unsigned ElementWidth = KindRes->second;
3751 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3757 if (parseOperand(Operands,
false,
false))
3766AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3767 const AsmToken &Tok = getTok();
3770 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3799 return TokError(
"expected #imm after shift specifier");
3805 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3814 return Error(
E,
"expected integer shift amount");
3816 const MCExpr *ImmVal;
3817 if (getParser().parseExpression(ImmVal))
3822 return Error(
E,
"expected constant '#imm' after shift specifier");
3825 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3834 {
"crc", {AArch64::FeatureCRC}},
3835 {
"sm4", {AArch64::FeatureSM4}},
3836 {
"sha3", {AArch64::FeatureSHA3}},
3837 {
"sha2", {AArch64::FeatureSHA2}},
3838 {
"aes", {AArch64::FeatureAES}},
3839 {
"crypto", {AArch64::FeatureCrypto}},
3840 {
"fp", {AArch64::FeatureFPARMv8}},
3841 {
"simd", {AArch64::FeatureNEON}},
3842 {
"ras", {AArch64::FeatureRAS}},
3843 {
"rasv2", {AArch64::FeatureRASv2}},
3844 {
"lse", {AArch64::FeatureLSE}},
3845 {
"predres", {AArch64::FeaturePredRes}},
3846 {
"predres2", {AArch64::FeatureSPECRES2}},
3847 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3848 {
"mte", {AArch64::FeatureMTE}},
3849 {
"memtag", {AArch64::FeatureMTE}},
3850 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3851 {
"pan", {AArch64::FeaturePAN}},
3852 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3853 {
"ccpp", {AArch64::FeatureCCPP}},
3854 {
"rcpc", {AArch64::FeatureRCPC}},
3855 {
"rng", {AArch64::FeatureRandGen}},
3856 {
"sve", {AArch64::FeatureSVE}},
3857 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3858 {
"sve2", {AArch64::FeatureSVE2}},
3859 {
"sve-aes", {AArch64::FeatureSVEAES}},
3860 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3861 {
"sve-sm4", {AArch64::FeatureSVESM4}},
3862 {
"sve2-sm4", {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3863 {
"sve-sha3", {AArch64::FeatureSVESHA3}},
3864 {
"sve2-sha3", {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3865 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3867 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3868 AArch64::FeatureSVE2}},
3869 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3870 {
"ls64", {AArch64::FeatureLS64}},
3871 {
"xs", {AArch64::FeatureXS}},
3872 {
"pauth", {AArch64::FeaturePAuth}},
3873 {
"flagm", {AArch64::FeatureFlagM}},
3874 {
"rme", {AArch64::FeatureRME}},
3875 {
"sme", {AArch64::FeatureSME}},
3876 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3877 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3878 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3879 {
"sme2", {AArch64::FeatureSME2}},
3880 {
"sme2p1", {AArch64::FeatureSME2p1}},
3881 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3882 {
"hbc", {AArch64::FeatureHBC}},
3883 {
"mops", {AArch64::FeatureMOPS}},
3884 {
"mec", {AArch64::FeatureMEC}},
3885 {
"the", {AArch64::FeatureTHE}},
3886 {
"d128", {AArch64::FeatureD128}},
3887 {
"lse128", {AArch64::FeatureLSE128}},
3888 {
"ite", {AArch64::FeatureITE}},
3889 {
"cssc", {AArch64::FeatureCSSC}},
3890 {
"rcpc3", {AArch64::FeatureRCPC3}},
3891 {
"gcs", {AArch64::FeatureGCS}},
3892 {
"bf16", {AArch64::FeatureBF16}},
3893 {
"compnum", {AArch64::FeatureComplxNum}},
3894 {
"dotprod", {AArch64::FeatureDotProd}},
3895 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3896 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3897 {
"fp16", {AArch64::FeatureFullFP16}},
3898 {
"fp16fml", {AArch64::FeatureFP16FML}},
3899 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3900 {
"lor", {AArch64::FeatureLOR}},
3901 {
"profile", {AArch64::FeatureSPE}},
3905 {
"rdm", {AArch64::FeatureRDM}},
3906 {
"rdma", {AArch64::FeatureRDM}},
3907 {
"sb", {AArch64::FeatureSB}},
3908 {
"ssbs", {AArch64::FeatureSSBS}},
3909 {
"fp8", {AArch64::FeatureFP8}},
3910 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3911 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3912 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3913 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3914 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3915 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3916 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3917 {
"lut", {AArch64::FeatureLUT}},
3918 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3919 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3920 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3921 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3922 {
"cpa", {AArch64::FeatureCPA}},
3923 {
"tlbiw", {AArch64::FeatureTLBIW}},
3924 {
"pops", {AArch64::FeaturePoPS}},
3925 {
"cmpbr", {AArch64::FeatureCMPBR}},
3926 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3927 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3928 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3929 {
"lsfe", {AArch64::FeatureLSFE}},
3930 {
"sme2p2", {AArch64::FeatureSME2p2}},
3931 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3932 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3933 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3934 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3935 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3936 {
"lsui", {AArch64::FeatureLSUI}},
3937 {
"occmo", {AArch64::FeatureOCCMO}},
3938 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3939 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3940 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3941 {
"lscp", {AArch64::FeatureLSCP}},
3942 {
"tlbid", {AArch64::FeatureTLBID}},
3943 {
"mpamv2", {AArch64::FeatureMPAMv2}},
3944 {
"mtetc", {AArch64::FeatureMTETC}},
3945 {
"gcie", {AArch64::FeatureGCIE}},
3946 {
"sme2p3", {AArch64::FeatureSME2p3}},
3947 {
"sve2p3", {AArch64::FeatureSVE2p3}},
3948 {
"sve-b16mm", {AArch64::FeatureSVE_B16MM}},
3949 {
"f16mm", {AArch64::FeatureF16MM}},
3950 {
"f16f32dot", {AArch64::FeatureF16F32DOT}},
3951 {
"f16f32mm", {AArch64::FeatureF16F32MM}},
3952 {
"mops-go", {AArch64::FeatureMOPS_GO}},
3953 {
"poe2", {AArch64::FeatureS1POE2}},
3954 {
"tev", {AArch64::FeatureTEV}},
3955 {
"btie", {AArch64::FeatureBTIE}},
3956 {
"dit", {AArch64::FeatureDIT}},
3957 {
"brbe", {AArch64::FeatureBRBE}},
3958 {
"bti", {AArch64::FeatureBranchTargetId}},
3959 {
"fcma", {AArch64::FeatureComplxNum}},
3960 {
"jscvt", {AArch64::FeatureJS}},
3961 {
"pauth-lr", {AArch64::FeaturePAuthLR}},
3962 {
"ssve-fexpa", {AArch64::FeatureSSVE_FEXPA}},
3963 {
"wfxt", {AArch64::FeatureWFxT}},
3967 if (FBS[AArch64::HasV8_0aOps])
3969 if (FBS[AArch64::HasV8_1aOps])
3971 else if (FBS[AArch64::HasV8_2aOps])
3973 else if (FBS[AArch64::HasV8_3aOps])
3975 else if (FBS[AArch64::HasV8_4aOps])
3977 else if (FBS[AArch64::HasV8_5aOps])
3979 else if (FBS[AArch64::HasV8_6aOps])
3981 else if (FBS[AArch64::HasV8_7aOps])
3983 else if (FBS[AArch64::HasV8_8aOps])
3985 else if (FBS[AArch64::HasV8_9aOps])
3987 else if (FBS[AArch64::HasV9_0aOps])
3989 else if (FBS[AArch64::HasV9_1aOps])
3991 else if (FBS[AArch64::HasV9_2aOps])
3993 else if (FBS[AArch64::HasV9_3aOps])
3995 else if (FBS[AArch64::HasV9_4aOps])
3997 else if (FBS[AArch64::HasV9_5aOps])
3999 else if (FBS[AArch64::HasV9_6aOps])
4001 else if (FBS[AArch64::HasV9_7aOps])
4003 else if (FBS[AArch64::HasV8_0rOps])
4012 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
4016void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
4018 const uint16_t Op2 = Encoding & 7;
4019 const uint16_t Cm = (Encoding & 0x78) >> 3;
4020 const uint16_t Cn = (Encoding & 0x780) >> 7;
4021 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
4026 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4028 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
4030 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
4033 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4039bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
4041 if (
Name.contains(
'.'))
4042 return TokError(
"invalid operand");
4047 const AsmToken &Tok = getTok();
4050 bool ExpectRegister =
true;
4051 bool OptionalRegister =
false;
4052 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
4053 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4055 if (Mnemonic ==
"ic") {
4056 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
4058 return TokError(
"invalid operand for IC instruction");
4059 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
4060 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
4062 return TokError(Str);
4065 createSysAlias(IC->
Encoding, Operands, S);
4066 }
else if (Mnemonic ==
"dc") {
4067 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
4069 return TokError(
"invalid operand for DC instruction");
4070 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
4071 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
4073 return TokError(Str);
4075 createSysAlias(DC->
Encoding, Operands, S);
4076 }
else if (Mnemonic ==
"at") {
4077 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
4079 return TokError(
"invalid operand for AT instruction");
4080 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
4081 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
4083 return TokError(Str);
4085 createSysAlias(AT->
Encoding, Operands, S);
4086 }
else if (Mnemonic ==
"tlbi") {
4087 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
4089 return TokError(
"invalid operand for TLBI instruction");
4090 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
4091 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
4093 return TokError(Str);
4096 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4097 if (hasAll || hasTLBID) {
4100 createSysAlias(TLBI->
Encoding, Operands, S);
4101 }
else if (Mnemonic ==
"mlbi") {
4102 const AArch64MLBI::MLBI *MLBI = AArch64MLBI::lookupMLBIByName(
Op);
4104 return TokError(
"invalid operand for MLBI instruction");
4105 else if (!MLBI->
haveFeatures(getSTI().getFeatureBits())) {
4106 std::string Str(
"MLBI " + std::string(MLBI->
Name) +
" requires: ");
4108 return TokError(Str);
4111 createSysAlias(MLBI->
Encoding, Operands, S);
4112 }
else if (Mnemonic ==
"gic") {
4113 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
4115 return TokError(
"invalid operand for GIC instruction");
4116 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
4117 std::string Str(
"GIC " + std::string(GIC->
Name) +
" requires: ");
4119 return TokError(Str);
4122 createSysAlias(GIC->
Encoding, Operands, S);
4123 }
else if (Mnemonic ==
"gsb") {
4124 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
4126 return TokError(
"invalid operand for GSB instruction");
4127 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
4128 std::string Str(
"GSB " + std::string(GSB->
Name) +
" requires: ");
4130 return TokError(Str);
4132 ExpectRegister =
false;
4133 createSysAlias(GSB->
Encoding, Operands, S);
4134 }
else if (Mnemonic ==
"plbi") {
4135 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
4137 return TokError(
"invalid operand for PLBI instruction");
4138 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
4139 std::string Str(
"PLBI " + std::string(PLBI->
Name) +
" requires: ");
4141 return TokError(Str);
4144 if (hasAll || hasTLBID) {
4147 createSysAlias(PLBI->
Encoding, Operands, S);
4148 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
4149 Mnemonic ==
"cosp") {
4151 if (
Op.lower() !=
"rctx")
4152 return TokError(
"invalid operand for prediction restriction instruction");
4154 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
4155 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
4157 if (Mnemonic ==
"cosp" && !hasSpecres2)
4158 return TokError(
"COSP requires: predres2");
4160 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
4162 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
4163 : Mnemonic ==
"dvp" ? 0b101
4164 : Mnemonic ==
"cosp" ? 0b110
4165 : Mnemonic ==
"cpp" ? 0b111
4168 "Invalid mnemonic for prediction restriction instruction");
4169 const auto SYS_3_7_3 = 0b01101110011;
4170 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
4172 createSysAlias(Encoding, Operands, S);
4177 bool HasRegister =
false;
4182 return TokError(
"expected register operand");
4186 if (!OptionalRegister) {
4187 if (ExpectRegister && !HasRegister)
4188 return TokError(
"specified " + Mnemonic +
" op requires a register");
4189 else if (!ExpectRegister && HasRegister)
4190 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4202bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4207 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4210 SMLoc startLoc = getLoc();
4211 const AsmToken ®Tok = getTok();
4213 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4215 return TokError(
"expected register operand");
4217 Operands.
push_back(AArch64Operand::CreateReg(
4218 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4225 const AsmToken &operandTok = getTok();
4227 SMLoc S2 = operandTok.
getLoc();
4230 if (Mnemonic ==
"gicr") {
4231 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4233 return Error(S2,
"invalid operand for GICR instruction");
4234 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4235 std::string Str(
"GICR " + std::string(GICR->
Name) +
" requires: ");
4237 return Error(S2, Str);
4239 createSysAlias(GICR->
Encoding, Operands, S2);
4250bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4252 if (
Name.contains(
'.'))
4253 return TokError(
"invalid operand");
4257 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4259 const AsmToken &Tok = getTok();
4263 if (Mnemonic ==
"tlbip") {
4264 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4266 return TokError(
"invalid operand for TLBIP instruction");
4267 if (!getSTI().hasFeature(AArch64::FeatureD128) &&
4268 !getSTI().hasFeature(AArch64::FeatureAll))
4269 return TokError(
"instruction requires: d128");
4271 std::string Str(
"instruction requires: ");
4273 return TokError(Str);
4275 createSysAlias(TLBIP->
Encoding, Operands, S);
4284 return TokError(
"expected register identifier");
4285 auto Result = tryParseSyspXzrPair(Operands);
4287 Result = tryParseGPRSeqPair(Operands);
4289 return TokError(
"specified " + Mnemonic +
4290 " op requires a pair of registers");
4298ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4299 MCAsmParser &Parser = getParser();
4300 const AsmToken &Tok = getTok();
4303 return TokError(
"'csync' operand expected");
4306 const MCExpr *ImmVal;
4307 SMLoc ExprLoc = getLoc();
4308 AsmToken IntTok = Tok;
4309 if (getParser().parseExpression(ImmVal))
4313 return Error(ExprLoc,
"immediate value expected for barrier operand");
4315 if (Mnemonic ==
"dsb" &&
Value > 15) {
4323 return Error(ExprLoc,
"barrier operand out of range");
4324 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4325 Operands.
push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4332 return TokError(
"invalid operand for instruction");
4335 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4336 auto DB = AArch64DB::lookupDBByName(Operand);
4338 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4339 return TokError(
"'sy' or #imm operand expected");
4341 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4342 return TokError(
"'csync' operand expected");
4344 if (Mnemonic ==
"dsb") {
4349 return TokError(
"invalid barrier option name");
4352 Operands.
push_back(AArch64Operand::CreateBarrier(
4353 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4361AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4362 const AsmToken &Tok = getTok();
4364 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4365 if (Mnemonic !=
"dsb")
4370 const MCExpr *ImmVal;
4371 SMLoc ExprLoc = getLoc();
4372 if (getParser().parseExpression(ImmVal))
4376 return Error(ExprLoc,
"immediate value expected for barrier operand");
4381 return Error(ExprLoc,
"barrier operand out of range");
4382 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4383 Operands.
push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4390 return TokError(
"invalid operand for instruction");
4393 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4396 return TokError(
"invalid barrier option name");
4399 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4406ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4407 const AsmToken &Tok = getTok();
4412 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4416 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4417 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4418 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4419 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4423 unsigned PStateImm = -1;
4424 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4425 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4426 PStateImm = PState15->Encoding;
4428 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4429 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4430 PStateImm = PState1->Encoding;
4434 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4442AArch64AsmParser::tryParsePHintInstOperand(
OperandVector &Operands) {
4444 const AsmToken &Tok = getTok();
4446 return TokError(
"invalid operand for instruction");
4450 return TokError(
"invalid operand for instruction");
4452 Operands.
push_back(AArch64Operand::CreatePHintInst(
4459bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4467 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4475 unsigned ElementWidth = KindRes->second;
4477 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4485 return tryParseVectorIndex(Operands).isFailure();
4488ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4489 SMLoc SIdx = getLoc();
4491 const MCExpr *ImmVal;
4492 if (getParser().parseExpression(ImmVal))
4496 return TokError(
"immediate value expected for vector index");
4514ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4516 RegKind MatchKind) {
4517 const AsmToken &Tok = getTok();
4526 StringRef Head =
Name.slice(Start,
Next);
4527 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4533 return TokError(
"invalid vector kind qualifier");
4544ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4546 ParseStatus Status =
4547 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4549 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4554template <RegKind RK>
4556AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4558 const SMLoc S = getLoc();
4561 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4569 unsigned ElementWidth = KindRes->second;
4570 Operands.
push_back(AArch64Operand::CreateVectorReg(
4571 RegNum, RK, ElementWidth, S,
4575 if (RK == RegKind::SVEPredicateAsCounter) {
4576 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4582 if (parseOperand(Operands,
false,
false))
4593 return Error(S,
"not expecting size suffix");
4601 auto Pred = getTok().getString().lower();
4602 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4603 return Error(getLoc(),
"expecting 'z' predication");
4605 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4606 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4609 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4617bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4619 if (!tryParseNeonVectorRegister(Operands))
4622 if (tryParseZTOperand(Operands).isSuccess())
4626 if (tryParseGPROperand<false>(Operands).isSuccess())
4632bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4633 bool HasELFModifier =
false;
4635 SMLoc Loc = getLexer().getLoc();
4637 HasELFModifier =
true;
4640 return TokError(
"expect relocation specifier in operand after ':'");
4642 std::string LowerCase = getTok().getIdentifier().lower();
4643 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4697 return TokError(
"expect relocation specifier in operand after ':'");
4701 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4705 if (getParser().parseExpression(ImmVal))
4712 if (
getContext().getAsmInfo()->hasSubsectionsViaSymbols()) {
4713 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4723 if (getParser().parsePrimaryExpr(Term, EndLoc))
4731ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4735 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4736 unsigned &ElementWidth) -> ParseStatus {
4737 StringRef
Name = getTok().getString();
4738 size_t DotPosition =
Name.find(
'.');
4746 StringRef
Tail =
Name.drop_front(DotPosition);
4747 const std::optional<std::pair<int, int>> &KindRes =
4751 "Expected the register to be followed by element width suffix");
4752 ElementWidth = KindRes->second;
4759 auto LCurly = getTok();
4764 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4770 if (getTok().getString().equals_insensitive(
"za")) {
4776 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4781 SMLoc TileLoc = getLoc();
4783 unsigned FirstReg, ElementWidth;
4784 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4785 if (!ParseRes.isSuccess()) {
4786 getLexer().UnLex(LCurly);
4790 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4792 unsigned PrevReg = FirstReg;
4794 SmallSet<unsigned, 8> DRegs;
4795 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4797 SmallSet<unsigned, 8> SeenRegs;
4798 SeenRegs.
insert(FirstReg);
4802 unsigned Reg, NextElementWidth;
4803 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4804 if (!ParseRes.isSuccess())
4808 if (ElementWidth != NextElementWidth)
4809 return Error(TileLoc,
"mismatched register size suffix");
4812 Warning(TileLoc,
"tile list not in ascending order");
4815 Warning(TileLoc,
"duplicate tile in list");
4818 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4827 unsigned RegMask = 0;
4828 for (
auto Reg : DRegs)
4832 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4837template <RegKind VectorKind>
4838ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4840 MCAsmParser &Parser = getParser();
4845 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4846 bool NoMatchIsError) -> ParseStatus {
4847 auto RegTok = getTok();
4848 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4849 if (ParseRes.isSuccess()) {
4856 RegTok.getString().equals_insensitive(
"zt0"))
4860 (ParseRes.isNoMatch() && NoMatchIsError &&
4861 !RegTok.getString().starts_with_insensitive(
"za")))
4862 return Error(Loc,
"vector register expected");
4867 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4869 auto LCurly = getTok();
4873 MCRegister FirstReg;
4874 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4878 if (ParseRes.isNoMatch())
4881 if (!ParseRes.isSuccess())
4884 MCRegister PrevReg = FirstReg;
4887 unsigned Stride = 1;
4889 SMLoc Loc = getLoc();
4893 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4894 if (!ParseRes.isSuccess())
4898 if (Kind != NextKind)
4899 return Error(Loc,
"mismatched register size suffix");
4902 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4904 if (Space == 0 || Space > 3)
4905 return Error(Loc,
"invalid number of vectors");
4910 bool HasCalculatedStride =
false;
4912 SMLoc Loc = getLoc();
4915 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4916 if (!ParseRes.isSuccess())
4920 if (Kind != NextKind)
4921 return Error(Loc,
"mismatched register size suffix");
4923 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4924 unsigned PrevRegVal =
4925 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4926 if (!HasCalculatedStride) {
4927 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4928 : (NumRegs - (PrevRegVal - RegVal));
4929 HasCalculatedStride =
true;
4933 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4934 return Error(Loc,
"registers must have the same sequential stride");
4945 return Error(S,
"invalid number of vectors");
4947 unsigned NumElements = 0;
4948 unsigned ElementWidth = 0;
4949 if (!
Kind.empty()) {
4951 std::tie(NumElements, ElementWidth) = *VK;
4954 Operands.
push_back(AArch64Operand::CreateVectorList(
4955 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4959 ParseStatus Res = tryParseVectorIndex(Operands);
4969bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4970 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4971 if (!ParseRes.isSuccess())
4974 return tryParseVectorIndex(Operands).isFailure();
4977ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4978 SMLoc StartLoc = getLoc();
4981 ParseStatus Res = tryParseScalarRegister(RegNum);
4986 Operands.
push_back(AArch64Operand::CreateReg(
4987 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4994 return Error(getLoc(),
"index must be absent or #0");
4996 const MCExpr *ImmVal;
4999 return Error(getLoc(),
"index must be absent or #0");
5001 Operands.
push_back(AArch64Operand::CreateReg(
5002 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
5006ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
5007 SMLoc StartLoc = getLoc();
5008 const AsmToken &Tok = getTok();
5011 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
5016 Operands.
push_back(AArch64Operand::CreateReg(
5017 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
5023 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5024 const MCExpr *ImmVal;
5025 if (getParser().parseExpression(ImmVal))
5029 return TokError(
"immediate value expected for vector index");
5030 Operands.
push_back(AArch64Operand::CreateImm(
5034 if (parseOptionalMulOperand(Operands))
5039 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5044template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
5045ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
5046 SMLoc StartLoc = getLoc();
5049 ParseStatus Res = tryParseScalarRegister(RegNum);
5055 Operands.
push_back(AArch64Operand::CreateReg(
5056 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
5065 Res = tryParseOptionalShiftExtend(ExtOpnd);
5069 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
5070 Operands.
push_back(AArch64Operand::CreateReg(
5071 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
5072 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
5073 Ext->hasShiftExtendAmount()));
5078bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
5079 MCAsmParser &Parser = getParser();
5087 if (!getTok().getString().equals_insensitive(
"mul") ||
5088 !(NextIsVL || NextIsHash))
5092 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
5097 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
5107 const MCExpr *ImmVal;
5110 Operands.
push_back(AArch64Operand::CreateImm(
5117 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
5120bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
5121 StringRef &VecGroup) {
5122 MCAsmParser &Parser = getParser();
5123 auto Tok = Parser.
getTok();
5128 .Case(
"vgx2",
"vgx2")
5129 .Case(
"vgx4",
"vgx4")
5140bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
5141 auto Tok = getTok();
5159bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
5160 bool invertCondCode) {
5161 MCAsmParser &Parser = getParser();
5164 MatchOperandParserImpl(Operands, Mnemonic,
true);
5178 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
5180 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
5183 getLexer().UnLex(SavedTok);
5187 switch (getLexer().getKind()) {
5191 if (parseSymbolicImmVal(Expr))
5192 return Error(S,
"invalid operand");
5196 return parseOptionalShiftExtend(getTok());
5200 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5205 return parseOperand(Operands,
false,
false);
5208 if (!parseNeonVectorList(Operands))
5212 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5217 return parseOperand(Operands,
false,
false);
5222 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5224 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5229 return parseCondCode(Operands, invertCondCode);
5232 if (!parseRegister(Operands)) {
5234 AsmToken SavedTok = getTok();
5239 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5243 Res = tryParseOptionalShiftExtend(Operands);
5246 getLexer().UnLex(SavedTok);
5253 if (!parseOptionalMulOperand(Operands))
5258 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5260 return parseKeywordOperand(Operands);
5264 const MCExpr *IdVal, *
Term;
5266 if (getParser().parseExpression(IdVal))
5268 if (getParser().parseAtSpecifier(IdVal,
E))
5270 std::optional<MCBinaryExpr::Opcode> Opcode;
5276 if (getParser().parsePrimaryExpr(Term,
E))
5283 return parseOptionalShiftExtend(getTok());
5294 bool isNegative =
false;
5306 const AsmToken &Tok = getTok();
5309 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5310 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5311 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5312 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5313 return TokError(
"unexpected floating point literal");
5314 else if (IntVal != 0 || isNegative)
5315 return TokError(
"expected floating-point constant #0.0");
5323 const MCExpr *ImmVal;
5324 if (parseSymbolicImmVal(ImmVal))
5331 return parseOptionalShiftExtend(Tok);
5334 SMLoc Loc = getLoc();
5335 if (Mnemonic !=
"ldr")
5336 return TokError(
"unexpected token in operand");
5338 const MCExpr *SubExprVal;
5339 if (getParser().parseExpression(SubExprVal))
5342 if (Operands.
size() < 2 ||
5343 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5344 return Error(Loc,
"Only valid when first operand is register");
5347 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5355 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5360 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5361 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5362 Operands.
push_back(AArch64Operand::CreateImm(
5366 ShiftAmt,
true, S,
E, Ctx));
5369 APInt Simm = APInt(64, Imm << ShiftAmt);
5372 return Error(Loc,
"Immediate too large for register");
5375 const MCExpr *CPLoc =
5376 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5377 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5383bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5384 const MCExpr *Expr =
nullptr;
5386 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5389 if (check(!
Value, L,
"expected constant expression"))
5391 Out =
Value->getValue();
5395bool AArch64AsmParser::parseComma() {
5403bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5407 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5412 unsigned RangeEnd =
Last;
5413 if (
Base == AArch64::X0) {
5414 if (
Last == AArch64::FP) {
5415 RangeEnd = AArch64::X28;
5416 if (
Reg == AArch64::FP) {
5421 if (
Last == AArch64::LR) {
5422 RangeEnd = AArch64::X28;
5423 if (
Reg == AArch64::FP) {
5426 }
else if (
Reg == AArch64::LR) {
5434 Twine(
"expected register in range ") +
5442bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5443 const MCParsedAsmOperand &Op2)
const {
5444 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5445 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5447 if (AOp1.isVectorList() && AOp2.isVectorList())
5448 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5449 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5450 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5452 if (!AOp1.isReg() || !AOp2.isReg())
5455 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5456 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5459 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5460 "Testing equality of non-scalar registers not supported");
5463 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5465 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5467 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5469 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5476bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5477 StringRef Name, SMLoc NameLoc,
5479 Name = StringSwitch<StringRef>(
Name.lower())
5480 .Case(
"beq",
"b.eq")
5481 .Case(
"bne",
"b.ne")
5482 .Case(
"bhs",
"b.hs")
5483 .Case(
"bcs",
"b.cs")
5484 .Case(
"blo",
"b.lo")
5485 .Case(
"bcc",
"b.cc")
5486 .Case(
"bmi",
"b.mi")
5487 .Case(
"bpl",
"b.pl")
5488 .Case(
"bvs",
"b.vs")
5489 .Case(
"bvc",
"b.vc")
5490 .Case(
"bhi",
"b.hi")
5491 .Case(
"bls",
"b.ls")
5492 .Case(
"bge",
"b.ge")
5493 .Case(
"blt",
"b.lt")
5494 .Case(
"bgt",
"b.gt")
5495 .Case(
"ble",
"b.le")
5496 .Case(
"bal",
"b.al")
5497 .Case(
"bnv",
"b.nv")
5502 getTok().getIdentifier().lower() ==
".req") {
5503 parseDirectiveReq(Name, NameLoc);
5511 StringRef Head =
Name.slice(Start,
Next);
5515 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5516 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5517 Head ==
"mlbi" || Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5518 return parseSysAlias(Head, NameLoc, Operands);
5522 return parseSyslAlias(Head, NameLoc, Operands);
5525 if (Head ==
"tlbip")
5526 return parseSyspAlias(Head, NameLoc, Operands);
5535 Head =
Name.slice(Start + 1,
Next);
5539 std::string Suggestion;
5542 std::string Msg =
"invalid condition code";
5543 if (!Suggestion.empty())
5544 Msg +=
", did you mean " + Suggestion +
"?";
5545 return Error(SuffixLoc, Msg);
5550 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5560 Operands.
push_back(AArch64Operand::CreateToken(
5566 bool condCodeFourthOperand =
5567 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5568 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5569 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5577 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5578 bool condCodeThirdOperand =
5579 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5587 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5588 (
N == 3 && condCodeThirdOperand) ||
5589 (
N == 2 && condCodeSecondOperand),
5590 condCodeSecondOperand || condCodeThirdOperand)) {
5610 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5613 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5616 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5629 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5630 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5631 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5632 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5633 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5634 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5635 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5641bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5642 SmallVectorImpl<SMLoc> &Loc) {
5643 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5644 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5650 PrefixInfo
Prefix = NextPrefix;
5651 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5663 return Error(IDLoc,
"instruction is unpredictable when following a"
5664 " movprfx, suggest replacing movprfx with mov");
5668 return Error(Loc[0],
"instruction is unpredictable when following a"
5669 " movprfx writing to a different destination");
5676 return Error(Loc[0],
"instruction is unpredictable when following a"
5677 " movprfx and destination also used as non-destructive"
5681 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5682 if (
Prefix.isPredicated()) {
5696 return Error(IDLoc,
"instruction is unpredictable when following a"
5697 " predicated movprfx, suggest using unpredicated movprfx");
5701 return Error(IDLoc,
"instruction is unpredictable when following a"
5702 " predicated movprfx using a different general predicate");
5706 return Error(IDLoc,
"instruction is unpredictable when following a"
5707 " predicated movprfx with a different element size");
5713 if (IsWindowsArm64EC) {
5719 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5720 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5721 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5722 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5723 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5724 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5725 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5726 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5727 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5728 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5730 " is disallowed on ARM64EC.");
5740 case AArch64::LDPSWpre:
5741 case AArch64::LDPWpost:
5742 case AArch64::LDPWpre:
5743 case AArch64::LDPXpost:
5744 case AArch64::LDPXpre: {
5749 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5750 "is also a destination");
5752 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5753 "is also a destination");
5756 case AArch64::LDR_ZA:
5757 case AArch64::STR_ZA: {
5760 return Error(Loc[1],
5761 "unpredictable instruction, immediate and offset mismatch.");
5764 case AArch64::LDPDi:
5765 case AArch64::LDPQi:
5766 case AArch64::LDPSi:
5767 case AArch64::LDPSWi:
5768 case AArch64::LDPWi:
5769 case AArch64::LDPXi: {
5773 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5776 case AArch64::LDPDpost:
5777 case AArch64::LDPDpre:
5778 case AArch64::LDPQpost:
5779 case AArch64::LDPQpre:
5780 case AArch64::LDPSpost:
5781 case AArch64::LDPSpre:
5782 case AArch64::LDPSWpost: {
5786 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5789 case AArch64::STPDpost:
5790 case AArch64::STPDpre:
5791 case AArch64::STPQpost:
5792 case AArch64::STPQpre:
5793 case AArch64::STPSpost:
5794 case AArch64::STPSpre:
5795 case AArch64::STPWpost:
5796 case AArch64::STPWpre:
5797 case AArch64::STPXpost:
5798 case AArch64::STPXpre: {
5803 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5804 "is also a source");
5806 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5807 "is also a source");
5810 case AArch64::LDRBBpre:
5811 case AArch64::LDRBpre:
5812 case AArch64::LDRHHpre:
5813 case AArch64::LDRHpre:
5814 case AArch64::LDRSBWpre:
5815 case AArch64::LDRSBXpre:
5816 case AArch64::LDRSHWpre:
5817 case AArch64::LDRSHXpre:
5818 case AArch64::LDRSWpre:
5819 case AArch64::LDRWpre:
5820 case AArch64::LDRXpre:
5821 case AArch64::LDRBBpost:
5822 case AArch64::LDRBpost:
5823 case AArch64::LDRHHpost:
5824 case AArch64::LDRHpost:
5825 case AArch64::LDRSBWpost:
5826 case AArch64::LDRSBXpost:
5827 case AArch64::LDRSHWpost:
5828 case AArch64::LDRSHXpost:
5829 case AArch64::LDRSWpost:
5830 case AArch64::LDRWpost:
5831 case AArch64::LDRXpost: {
5835 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5836 "is also a source");
5839 case AArch64::STRBBpost:
5840 case AArch64::STRBpost:
5841 case AArch64::STRHHpost:
5842 case AArch64::STRHpost:
5843 case AArch64::STRWpost:
5844 case AArch64::STRXpost:
5845 case AArch64::STRBBpre:
5846 case AArch64::STRBpre:
5847 case AArch64::STRHHpre:
5848 case AArch64::STRHpre:
5849 case AArch64::STRWpre:
5850 case AArch64::STRXpre: {
5854 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5855 "is also a source");
5858 case AArch64::STXRB:
5859 case AArch64::STXRH:
5860 case AArch64::STXRW:
5861 case AArch64::STXRX:
5862 case AArch64::STLXRB:
5863 case AArch64::STLXRH:
5864 case AArch64::STLXRW:
5865 case AArch64::STLXRX: {
5871 return Error(Loc[0],
5872 "unpredictable STXR instruction, status is also a source");
5875 case AArch64::STXPW:
5876 case AArch64::STXPX:
5877 case AArch64::STLXPW:
5878 case AArch64::STLXPX: {
5885 return Error(Loc[0],
5886 "unpredictable STXP instruction, status is also a source");
5889 case AArch64::LDRABwriteback:
5890 case AArch64::LDRAAwriteback: {
5894 return Error(Loc[0],
5895 "unpredictable LDRA instruction, writeback base"
5896 " is also a destination");
5903 case AArch64::CPYFP:
5904 case AArch64::CPYFPWN:
5905 case AArch64::CPYFPRN:
5906 case AArch64::CPYFPN:
5907 case AArch64::CPYFPWT:
5908 case AArch64::CPYFPWTWN:
5909 case AArch64::CPYFPWTRN:
5910 case AArch64::CPYFPWTN:
5911 case AArch64::CPYFPRT:
5912 case AArch64::CPYFPRTWN:
5913 case AArch64::CPYFPRTRN:
5914 case AArch64::CPYFPRTN:
5915 case AArch64::CPYFPT:
5916 case AArch64::CPYFPTWN:
5917 case AArch64::CPYFPTRN:
5918 case AArch64::CPYFPTN:
5919 case AArch64::CPYFM:
5920 case AArch64::CPYFMWN:
5921 case AArch64::CPYFMRN:
5922 case AArch64::CPYFMN:
5923 case AArch64::CPYFMWT:
5924 case AArch64::CPYFMWTWN:
5925 case AArch64::CPYFMWTRN:
5926 case AArch64::CPYFMWTN:
5927 case AArch64::CPYFMRT:
5928 case AArch64::CPYFMRTWN:
5929 case AArch64::CPYFMRTRN:
5930 case AArch64::CPYFMRTN:
5931 case AArch64::CPYFMT:
5932 case AArch64::CPYFMTWN:
5933 case AArch64::CPYFMTRN:
5934 case AArch64::CPYFMTN:
5935 case AArch64::CPYFE:
5936 case AArch64::CPYFEWN:
5937 case AArch64::CPYFERN:
5938 case AArch64::CPYFEN:
5939 case AArch64::CPYFEWT:
5940 case AArch64::CPYFEWTWN:
5941 case AArch64::CPYFEWTRN:
5942 case AArch64::CPYFEWTN:
5943 case AArch64::CPYFERT:
5944 case AArch64::CPYFERTWN:
5945 case AArch64::CPYFERTRN:
5946 case AArch64::CPYFERTN:
5947 case AArch64::CPYFET:
5948 case AArch64::CPYFETWN:
5949 case AArch64::CPYFETRN:
5950 case AArch64::CPYFETN:
5952 case AArch64::CPYPWN:
5953 case AArch64::CPYPRN:
5954 case AArch64::CPYPN:
5955 case AArch64::CPYPWT:
5956 case AArch64::CPYPWTWN:
5957 case AArch64::CPYPWTRN:
5958 case AArch64::CPYPWTN:
5959 case AArch64::CPYPRT:
5960 case AArch64::CPYPRTWN:
5961 case AArch64::CPYPRTRN:
5962 case AArch64::CPYPRTN:
5963 case AArch64::CPYPT:
5964 case AArch64::CPYPTWN:
5965 case AArch64::CPYPTRN:
5966 case AArch64::CPYPTN:
5968 case AArch64::CPYMWN:
5969 case AArch64::CPYMRN:
5970 case AArch64::CPYMN:
5971 case AArch64::CPYMWT:
5972 case AArch64::CPYMWTWN:
5973 case AArch64::CPYMWTRN:
5974 case AArch64::CPYMWTN:
5975 case AArch64::CPYMRT:
5976 case AArch64::CPYMRTWN:
5977 case AArch64::CPYMRTRN:
5978 case AArch64::CPYMRTN:
5979 case AArch64::CPYMT:
5980 case AArch64::CPYMTWN:
5981 case AArch64::CPYMTRN:
5982 case AArch64::CPYMTN:
5984 case AArch64::CPYEWN:
5985 case AArch64::CPYERN:
5986 case AArch64::CPYEN:
5987 case AArch64::CPYEWT:
5988 case AArch64::CPYEWTWN:
5989 case AArch64::CPYEWTRN:
5990 case AArch64::CPYEWTN:
5991 case AArch64::CPYERT:
5992 case AArch64::CPYERTWN:
5993 case AArch64::CPYERTRN:
5994 case AArch64::CPYERTN:
5995 case AArch64::CPYET:
5996 case AArch64::CPYETWN:
5997 case AArch64::CPYETRN:
5998 case AArch64::CPYETN: {
6009 return Error(Loc[0],
"invalid CPY instruction, destination and source"
6010 " registers are the same");
6012 return Error(Loc[0],
"invalid CPY instruction, destination and size"
6013 " registers are the same");
6015 return Error(Loc[0],
"invalid CPY instruction, source and size"
6016 " registers are the same");
6020 case AArch64::SETPT:
6021 case AArch64::SETPN:
6022 case AArch64::SETPTN:
6024 case AArch64::SETMT:
6025 case AArch64::SETMN:
6026 case AArch64::SETMTN:
6028 case AArch64::SETET:
6029 case AArch64::SETEN:
6030 case AArch64::SETETN:
6031 case AArch64::SETGP:
6032 case AArch64::SETGPT:
6033 case AArch64::SETGPN:
6034 case AArch64::SETGPTN:
6035 case AArch64::SETGM:
6036 case AArch64::SETGMT:
6037 case AArch64::SETGMN:
6038 case AArch64::SETGMTN:
6039 case AArch64::MOPSSETGE:
6040 case AArch64::MOPSSETGET:
6041 case AArch64::MOPSSETGEN:
6042 case AArch64::MOPSSETGETN: {
6052 return Error(Loc[0],
"invalid SET instruction, destination and size"
6053 " registers are the same");
6055 return Error(Loc[0],
"invalid SET instruction, destination and source"
6056 " registers are the same");
6058 return Error(Loc[0],
"invalid SET instruction, source and size"
6059 " registers are the same");
6062 case AArch64::SETGOP:
6063 case AArch64::SETGOPT:
6064 case AArch64::SETGOPN:
6065 case AArch64::SETGOPTN:
6066 case AArch64::SETGOM:
6067 case AArch64::SETGOMT:
6068 case AArch64::SETGOMN:
6069 case AArch64::SETGOMTN:
6070 case AArch64::SETGOE:
6071 case AArch64::SETGOET:
6072 case AArch64::SETGOEN:
6073 case AArch64::SETGOETN: {
6082 return Error(Loc[0],
"invalid SET instruction, destination and size"
6083 " registers are the same");
6092 case AArch64::ADDSWri:
6093 case AArch64::ADDSXri:
6094 case AArch64::ADDWri:
6095 case AArch64::ADDXri:
6096 case AArch64::SUBSWri:
6097 case AArch64::SUBSXri:
6098 case AArch64::SUBWri:
6099 case AArch64::SUBXri: {
6107 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
6132 return Error(Loc.
back(),
"invalid immediate expression");
6145 unsigned VariantID = 0);
6147bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
6151 case Match_InvalidTiedOperand: {
6152 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
6153 if (
Op.isVectorList())
6154 return Error(
Loc,
"operand must match destination register list");
6156 assert(
Op.isReg() &&
"Unexpected operand type");
6157 switch (
Op.getRegEqualityTy()) {
6158 case RegConstraintEqualityTy::EqualsSubReg:
6159 return Error(
Loc,
"operand must be 64-bit form of destination register");
6160 case RegConstraintEqualityTy::EqualsSuperReg:
6161 return Error(
Loc,
"operand must be 32-bit form of destination register");
6162 case RegConstraintEqualityTy::EqualsReg:
6163 return Error(
Loc,
"operand must match destination register");
6167 case Match_MissingFeature:
6169 "instruction requires a CPU feature not currently enabled");
6170 case Match_InvalidOperand:
6171 return Error(Loc,
"invalid operand for instruction");
6172 case Match_InvalidSuffix:
6173 return Error(Loc,
"invalid type suffix for instruction");
6174 case Match_InvalidCondCode:
6175 return Error(Loc,
"expected AArch64 condition code");
6176 case Match_AddSubRegExtendSmall:
6178 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
6179 case Match_AddSubRegExtendLarge:
6181 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
6182 case Match_AddSubSecondSource:
6184 "expected compatible register, symbol or integer in range [0, 4095]");
6185 case Match_LogicalSecondSource:
6186 return Error(Loc,
"expected compatible register or logical immediate");
6187 case Match_InvalidMovImm32Shift:
6188 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
6189 case Match_InvalidMovImm64Shift:
6190 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
6191 case Match_AddSubRegShift32:
6193 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
6194 case Match_AddSubRegShift64:
6196 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
6197 case Match_InvalidFPImm:
6199 "expected compatible register or floating-point constant");
6200 case Match_InvalidMemoryIndexedSImm6:
6201 return Error(Loc,
"index must be an integer in range [-32, 31].");
6202 case Match_InvalidMemoryIndexedSImm5:
6203 return Error(Loc,
"index must be an integer in range [-16, 15].");
6204 case Match_InvalidMemoryIndexed1SImm4:
6205 return Error(Loc,
"index must be an integer in range [-8, 7].");
6206 case Match_InvalidMemoryIndexed2SImm4:
6207 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6208 case Match_InvalidMemoryIndexed3SImm4:
6209 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6210 case Match_InvalidMemoryIndexed4SImm4:
6211 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6212 case Match_InvalidMemoryIndexed16SImm4:
6213 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6214 case Match_InvalidMemoryIndexed32SImm4:
6215 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6216 case Match_InvalidMemoryIndexed1SImm6:
6217 return Error(Loc,
"index must be an integer in range [-32, 31].");
6218 case Match_InvalidMemoryIndexedSImm8:
6219 return Error(Loc,
"index must be an integer in range [-128, 127].");
6220 case Match_InvalidMemoryIndexedSImm9:
6221 return Error(Loc,
"index must be an integer in range [-256, 255].");
6222 case Match_InvalidMemoryIndexed16SImm9:
6223 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6224 case Match_InvalidMemoryIndexed8SImm10:
6225 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6226 case Match_InvalidMemoryIndexed4SImm7:
6227 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6228 case Match_InvalidMemoryIndexed8SImm7:
6229 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6230 case Match_InvalidMemoryIndexed16SImm7:
6231 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6232 case Match_InvalidMemoryIndexed8UImm5:
6233 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6234 case Match_InvalidMemoryIndexed8UImm3:
6235 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6236 case Match_InvalidMemoryIndexed4UImm5:
6237 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6238 case Match_InvalidMemoryIndexed2UImm5:
6239 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6240 case Match_InvalidMemoryIndexed8UImm6:
6241 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6242 case Match_InvalidMemoryIndexed16UImm6:
6243 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6244 case Match_InvalidMemoryIndexed4UImm6:
6245 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6246 case Match_InvalidMemoryIndexed2UImm6:
6247 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6248 case Match_InvalidMemoryIndexed1UImm6:
6249 return Error(Loc,
"index must be in range [0, 63].");
6250 case Match_InvalidMemoryWExtend8:
6252 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6253 case Match_InvalidMemoryWExtend16:
6255 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6256 case Match_InvalidMemoryWExtend32:
6258 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6259 case Match_InvalidMemoryWExtend64:
6261 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6262 case Match_InvalidMemoryWExtend128:
6264 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6265 case Match_InvalidMemoryXExtend8:
6267 "expected 'lsl' or 'sxtx' with optional shift of #0");
6268 case Match_InvalidMemoryXExtend16:
6270 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6271 case Match_InvalidMemoryXExtend32:
6273 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6274 case Match_InvalidMemoryXExtend64:
6276 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6277 case Match_InvalidMemoryXExtend128:
6279 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6280 case Match_InvalidMemoryIndexed1:
6281 return Error(Loc,
"index must be an integer in range [0, 4095].");
6282 case Match_InvalidMemoryIndexed2:
6283 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6284 case Match_InvalidMemoryIndexed4:
6285 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6286 case Match_InvalidMemoryIndexed8:
6287 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6288 case Match_InvalidMemoryIndexed16:
6289 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6290 case Match_InvalidImm0_0:
6291 return Error(Loc,
"immediate must be 0.");
6292 case Match_InvalidImm0_1:
6293 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6294 case Match_InvalidImm0_3:
6295 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6296 case Match_InvalidImm0_7:
6297 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6298 case Match_InvalidImm0_15:
6299 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6300 case Match_InvalidImm0_31:
6301 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6302 case Match_InvalidImm0_63:
6303 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6304 case Match_InvalidImm0_127:
6305 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6306 case Match_InvalidImm0_255:
6307 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6308 case Match_InvalidImm0_65535:
6309 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6310 case Match_InvalidImm1_8:
6311 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6312 case Match_InvalidImm1_16:
6313 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6314 case Match_InvalidImm1_32:
6315 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6316 case Match_InvalidImm1_64:
6317 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6318 case Match_InvalidImmM1_62:
6319 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6320 case Match_InvalidMemoryIndexedRange2UImm0:
6321 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6322 case Match_InvalidMemoryIndexedRange2UImm1:
6323 return Error(Loc,
"vector select offset must be an immediate range of the "
6324 "form <immf>:<imml>, where the first "
6325 "immediate is a multiple of 2 in the range [0, 2], and "
6326 "the second immediate is immf + 1.");
6327 case Match_InvalidMemoryIndexedRange2UImm2:
6328 case Match_InvalidMemoryIndexedRange2UImm3:
6331 "vector select offset must be an immediate range of the form "
6333 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6335 "depending on the instruction, and the second immediate is immf + 1.");
6336 case Match_InvalidMemoryIndexedRange4UImm0:
6337 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6338 case Match_InvalidMemoryIndexedRange4UImm1:
6339 case Match_InvalidMemoryIndexedRange4UImm2:
6342 "vector select offset must be an immediate range of the form "
6344 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6346 "depending on the instruction, and the second immediate is immf + 3.");
6347 case Match_InvalidSVEAddSubImm8:
6348 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6349 " with a shift amount of 0");
6350 case Match_InvalidSVEAddSubImm16:
6351 case Match_InvalidSVEAddSubImm32:
6352 case Match_InvalidSVEAddSubImm64:
6353 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6354 "multiple of 256 in range [256, 65280]");
6355 case Match_InvalidSVECpyImm8:
6356 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6357 " with a shift amount of 0");
6358 case Match_InvalidSVECpyImm16:
6359 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6360 "multiple of 256 in range [-32768, 65280]");
6361 case Match_InvalidSVECpyImm32:
6362 case Match_InvalidSVECpyImm64:
6363 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6364 "multiple of 256 in range [-32768, 32512]");
6365 case Match_InvalidIndexRange0_0:
6366 return Error(Loc,
"expected lane specifier '[0]'");
6367 case Match_InvalidIndexRange1_1:
6368 return Error(Loc,
"expected lane specifier '[1]'");
6369 case Match_InvalidIndexRange0_15:
6370 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6371 case Match_InvalidIndexRange0_7:
6372 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6373 case Match_InvalidIndexRange0_3:
6374 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6375 case Match_InvalidIndexRange0_1:
6376 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6377 case Match_InvalidSVEIndexRange0_63:
6378 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6379 case Match_InvalidSVEIndexRange0_31:
6380 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6381 case Match_InvalidSVEIndexRange0_15:
6382 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6383 case Match_InvalidSVEIndexRange0_7:
6384 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6385 case Match_InvalidSVEIndexRange0_3:
6386 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6387 case Match_InvalidLabel:
6388 return Error(Loc,
"expected label or encodable integer pc offset");
6390 return Error(Loc,
"expected readable system register");
6392 case Match_InvalidSVCR:
6393 return Error(Loc,
"expected writable system register or pstate");
6394 case Match_InvalidComplexRotationEven:
6395 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6396 case Match_InvalidComplexRotationOdd:
6397 return Error(Loc,
"complex rotation must be 90 or 270.");
6398 case Match_MnemonicFail: {
6400 ((AArch64Operand &)*Operands[0]).
getToken(),
6401 ComputeAvailableFeatures(STI->getFeatureBits()));
6402 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6404 case Match_InvalidGPR64shifted8:
6405 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6406 case Match_InvalidGPR64shifted16:
6407 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6408 case Match_InvalidGPR64shifted32:
6409 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6410 case Match_InvalidGPR64shifted64:
6411 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6412 case Match_InvalidGPR64shifted128:
6414 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6415 case Match_InvalidGPR64NoXZRshifted8:
6416 return Error(Loc,
"register must be x0..x30 without shift");
6417 case Match_InvalidGPR64NoXZRshifted16:
6418 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6419 case Match_InvalidGPR64NoXZRshifted32:
6420 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6421 case Match_InvalidGPR64NoXZRshifted64:
6422 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6423 case Match_InvalidGPR64NoXZRshifted128:
6424 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6425 case Match_InvalidZPR32UXTW8:
6426 case Match_InvalidZPR32SXTW8:
6427 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6428 case Match_InvalidZPR32UXTW16:
6429 case Match_InvalidZPR32SXTW16:
6430 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6431 case Match_InvalidZPR32UXTW32:
6432 case Match_InvalidZPR32SXTW32:
6433 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6434 case Match_InvalidZPR32UXTW64:
6435 case Match_InvalidZPR32SXTW64:
6436 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6437 case Match_InvalidZPR64UXTW8:
6438 case Match_InvalidZPR64SXTW8:
6439 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6440 case Match_InvalidZPR64UXTW16:
6441 case Match_InvalidZPR64SXTW16:
6442 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6443 case Match_InvalidZPR64UXTW32:
6444 case Match_InvalidZPR64SXTW32:
6445 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6446 case Match_InvalidZPR64UXTW64:
6447 case Match_InvalidZPR64SXTW64:
6448 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6449 case Match_InvalidZPR32LSL8:
6450 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6451 case Match_InvalidZPR32LSL16:
6452 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6453 case Match_InvalidZPR32LSL32:
6454 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6455 case Match_InvalidZPR32LSL64:
6456 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6457 case Match_InvalidZPR64LSL8:
6458 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6459 case Match_InvalidZPR64LSL16:
6460 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6461 case Match_InvalidZPR64LSL32:
6462 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6463 case Match_InvalidZPR64LSL64:
6464 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6465 case Match_InvalidZPR0:
6466 return Error(Loc,
"expected register without element width suffix");
6467 case Match_InvalidZPR8:
6468 case Match_InvalidZPR16:
6469 case Match_InvalidZPR32:
6470 case Match_InvalidZPR64:
6471 case Match_InvalidZPR128:
6472 return Error(Loc,
"invalid element width");
6473 case Match_InvalidZPR_3b8:
6474 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6475 case Match_InvalidZPR_3b16:
6476 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6477 case Match_InvalidZPR_3b32:
6478 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6479 case Match_InvalidZPR_4b8:
6481 "Invalid restricted vector register, expected z0.b..z15.b");
6482 case Match_InvalidZPR_4b16:
6483 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6484 case Match_InvalidZPR_4b32:
6485 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6486 case Match_InvalidZPR_4b64:
6487 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6488 case Match_InvalidZPRMul2_Lo8:
6489 return Error(Loc,
"Invalid restricted vector register, expected even "
6490 "register in z0.b..z14.b");
6491 case Match_InvalidZPRMul2_Hi8:
6492 return Error(Loc,
"Invalid restricted vector register, expected even "
6493 "register in z16.b..z30.b");
6494 case Match_InvalidZPRMul2_Lo16:
6495 return Error(Loc,
"Invalid restricted vector register, expected even "
6496 "register in z0.h..z14.h");
6497 case Match_InvalidZPRMul2_Hi16:
6498 return Error(Loc,
"Invalid restricted vector register, expected even "
6499 "register in z16.h..z30.h");
6500 case Match_InvalidZPRMul2_Lo32:
6501 return Error(Loc,
"Invalid restricted vector register, expected even "
6502 "register in z0.s..z14.s");
6503 case Match_InvalidZPRMul2_Hi32:
6504 return Error(Loc,
"Invalid restricted vector register, expected even "
6505 "register in z16.s..z30.s");
6506 case Match_InvalidZPRMul2_Lo64:
6507 return Error(Loc,
"Invalid restricted vector register, expected even "
6508 "register in z0.d..z14.d");
6509 case Match_InvalidZPRMul2_Hi64:
6510 return Error(Loc,
"Invalid restricted vector register, expected even "
6511 "register in z16.d..z30.d");
6512 case Match_InvalidZPR_K0:
6513 return Error(Loc,
"invalid restricted vector register, expected register "
6514 "in z20..z23 or z28..z31");
6515 case Match_InvalidSVEPattern:
6516 return Error(Loc,
"invalid predicate pattern");
6517 case Match_InvalidSVEPPRorPNRAnyReg:
6518 case Match_InvalidSVEPPRorPNRBReg:
6519 case Match_InvalidSVEPredicateAnyReg:
6520 case Match_InvalidSVEPredicateBReg:
6521 case Match_InvalidSVEPredicateHReg:
6522 case Match_InvalidSVEPredicateSReg:
6523 case Match_InvalidSVEPredicateDReg:
6524 return Error(Loc,
"invalid predicate register.");
6525 case Match_InvalidSVEPredicate3bAnyReg:
6526 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6527 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6528 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6529 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6530 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6531 return Error(Loc,
"Invalid predicate register, expected PN in range "
6532 "pn8..pn15 with element suffix.");
6533 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6534 return Error(Loc,
"invalid restricted predicate-as-counter register "
6535 "expected pn8..pn15");
6536 case Match_InvalidSVEPNPredicateBReg:
6537 case Match_InvalidSVEPNPredicateHReg:
6538 case Match_InvalidSVEPNPredicateSReg:
6539 case Match_InvalidSVEPNPredicateDReg:
6540 return Error(Loc,
"Invalid predicate register, expected PN in range "
6541 "pn0..pn15 with element suffix.");
6542 case Match_InvalidSVEVecLenSpecifier:
6543 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6544 case Match_InvalidSVEPredicateListMul2x8:
6545 case Match_InvalidSVEPredicateListMul2x16:
6546 case Match_InvalidSVEPredicateListMul2x32:
6547 case Match_InvalidSVEPredicateListMul2x64:
6548 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6549 "predicate registers, where the first vector is a multiple of 2 "
6550 "and with correct element type");
6551 case Match_InvalidSVEExactFPImmOperandHalfOne:
6552 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6553 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6554 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6555 case Match_InvalidSVEExactFPImmOperandZeroOne:
6556 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6557 case Match_InvalidMatrixTileVectorH8:
6558 case Match_InvalidMatrixTileVectorV8:
6559 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6560 case Match_InvalidMatrixTileVectorH16:
6561 case Match_InvalidMatrixTileVectorV16:
6563 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6564 case Match_InvalidMatrixTileVectorH32:
6565 case Match_InvalidMatrixTileVectorV32:
6567 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6568 case Match_InvalidMatrixTileVectorH64:
6569 case Match_InvalidMatrixTileVectorV64:
6571 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6572 case Match_InvalidMatrixTileVectorH128:
6573 case Match_InvalidMatrixTileVectorV128:
6575 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6576 case Match_InvalidMatrixTile16:
6577 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6578 case Match_InvalidMatrixTile32:
6579 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6580 case Match_InvalidMatrixTile64:
6581 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6582 case Match_InvalidMatrix:
6583 return Error(Loc,
"invalid matrix operand, expected za");
6584 case Match_InvalidMatrix8:
6585 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6586 case Match_InvalidMatrix16:
6587 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6588 case Match_InvalidMatrix32:
6589 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6590 case Match_InvalidMatrix64:
6591 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6592 case Match_InvalidMatrixIndexGPR32_12_15:
6593 return Error(Loc,
"operand must be a register in range [w12, w15]");
6594 case Match_InvalidMatrixIndexGPR32_8_11:
6595 return Error(Loc,
"operand must be a register in range [w8, w11]");
6596 case Match_InvalidSVEVectorList2x8Mul2:
6597 case Match_InvalidSVEVectorList2x16Mul2:
6598 case Match_InvalidSVEVectorList2x32Mul2:
6599 case Match_InvalidSVEVectorList2x64Mul2:
6600 case Match_InvalidSVEVectorList2x128Mul2:
6601 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6602 "SVE vectors, where the first vector is a multiple of 2 "
6603 "and with matching element types");
6604 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6605 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6606 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6607 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6608 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6609 "SVE vectors in the range z0-z14, where the first vector "
6610 "is a multiple of 2 "
6611 "and with matching element types");
6612 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6613 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6614 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6615 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6617 "Invalid vector list, expected list with 2 consecutive "
6618 "SVE vectors in the range z16-z30, where the first vector "
6619 "is a multiple of 2 "
6620 "and with matching element types");
6621 case Match_InvalidSVEVectorList4x8Mul4:
6622 case Match_InvalidSVEVectorList4x16Mul4:
6623 case Match_InvalidSVEVectorList4x32Mul4:
6624 case Match_InvalidSVEVectorList4x64Mul4:
6625 case Match_InvalidSVEVectorList4x128Mul4:
6626 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6627 "SVE vectors, where the first vector is a multiple of 4 "
6628 "and with matching element types");
6629 case Match_InvalidLookupTable:
6630 return Error(Loc,
"Invalid lookup table, expected zt0");
6631 case Match_InvalidSVEVectorListStrided2x8:
6632 case Match_InvalidSVEVectorListStrided2x16:
6633 case Match_InvalidSVEVectorListStrided2x32:
6634 case Match_InvalidSVEVectorListStrided2x64:
6637 "Invalid vector list, expected list with each SVE vector in the list "
6638 "8 registers apart, and the first register in the range [z0, z7] or "
6639 "[z16, z23] and with correct element type");
6640 case Match_InvalidSVEVectorListStrided4x8:
6641 case Match_InvalidSVEVectorListStrided4x16:
6642 case Match_InvalidSVEVectorListStrided4x32:
6643 case Match_InvalidSVEVectorListStrided4x64:
6646 "Invalid vector list, expected list with each SVE vector in the list "
6647 "4 registers apart, and the first register in the range [z0, z3] or "
6648 "[z16, z19] and with correct element type");
6649 case Match_AddSubLSLImm3ShiftLarge:
6651 "expected 'lsl' with optional integer in range [0, 7]");
6659bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6663 bool MatchingInlineAsm) {
6664 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6665 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6666 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6669 unsigned NumOperands = Operands.
size();
6671 if (NumOperands == 4 && Tok ==
"lsl") {
6672 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6673 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6674 if (Op2.isScalarReg() && Op3.isImm()) {
6680 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6682 NewOp3Val = (32 - Op3Val) & 0x1f;
6683 NewOp4Val = 31 - Op3Val;
6685 NewOp3Val = (64 - Op3Val) & 0x3f;
6686 NewOp4Val = 63 - Op3Val;
6693 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6694 Operands.
push_back(AArch64Operand::CreateImm(
6695 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6696 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6700 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6702 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6703 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6704 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6706 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6710 if (LSBCE && WidthCE) {
6712 uint64_t Width = WidthCE->
getValue();
6714 uint64_t RegWidth = 0;
6715 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6721 if (LSB >= RegWidth)
6722 return Error(LSBOp.getStartLoc(),
6723 "expected integer in range [0, 31]");
6724 if (Width < 1 || Width > RegWidth)
6725 return Error(WidthOp.getStartLoc(),
6726 "expected integer in range [1, 32]");
6730 ImmR = (32 - LSB) & 0x1f;
6732 ImmR = (64 - LSB) & 0x3f;
6734 uint64_t ImmS = Width - 1;
6736 if (ImmR != 0 && ImmS >= ImmR)
6737 return Error(WidthOp.getStartLoc(),
6738 "requested insert overflows register");
6743 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6744 Operands[2] = AArch64Operand::CreateReg(
6745 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6747 Operands[3] = AArch64Operand::CreateImm(
6748 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6750 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6754 }
else if (NumOperands == 5) {
6757 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6758 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6759 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6760 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6762 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6766 if (Op3CE && Op4CE) {
6767 uint64_t Op3Val = Op3CE->
getValue();
6768 uint64_t Op4Val = Op4CE->
getValue();
6770 uint64_t RegWidth = 0;
6771 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6777 if (Op3Val >= RegWidth)
6778 return Error(Op3.getStartLoc(),
6779 "expected integer in range [0, 31]");
6780 if (Op4Val < 1 || Op4Val > RegWidth)
6781 return Error(Op4.getStartLoc(),
6782 "expected integer in range [1, 32]");
6784 uint64_t NewOp3Val = 0;
6786 NewOp3Val = (32 - Op3Val) & 0x1f;
6788 NewOp3Val = (64 - Op3Val) & 0x3f;
6790 uint64_t NewOp4Val = Op4Val - 1;
6792 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6793 return Error(Op4.getStartLoc(),
6794 "requested insert overflows register");
6796 const MCExpr *NewOp3 =
6798 const MCExpr *NewOp4 =
6800 Operands[3] = AArch64Operand::CreateImm(
6801 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6802 Operands[4] = AArch64Operand::CreateImm(
6803 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6805 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6807 else if (Tok ==
"sbfiz")
6808 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6810 else if (Tok ==
"ubfiz")
6811 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6820 }
else if (NumOperands == 5 &&
6821 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6822 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6823 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6824 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6826 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6830 if (Op3CE && Op4CE) {
6831 uint64_t Op3Val = Op3CE->
getValue();
6832 uint64_t Op4Val = Op4CE->
getValue();
6834 uint64_t RegWidth = 0;
6835 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6841 if (Op3Val >= RegWidth)
6842 return Error(Op3.getStartLoc(),
6843 "expected integer in range [0, 31]");
6844 if (Op4Val < 1 || Op4Val > RegWidth)
6845 return Error(Op4.getStartLoc(),
6846 "expected integer in range [1, 32]");
6848 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6850 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6851 return Error(Op4.getStartLoc(),
6852 "requested extract overflows register");
6854 const MCExpr *NewOp4 =
6856 Operands[4] = AArch64Operand::CreateImm(
6857 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6859 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6861 else if (Tok ==
"sbfx")
6862 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6864 else if (Tok ==
"ubfx")
6865 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6878 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6879 NumOperands == 4 && Tok ==
"movi") {
6880 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6881 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6882 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6883 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6884 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6885 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6886 if (Suffix.
lower() ==
".2d" &&
6888 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6889 " correctly on this CPU, converting to equivalent movi.16b");
6891 unsigned Idx = Op1.isToken() ? 1 : 2;
6893 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6901 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6904 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6905 if (
Op.isScalarReg()) {
6907 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6908 Op.getStartLoc(),
Op.getEndLoc(),
6913 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6914 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6915 if (
Op.isScalarReg() &&
6916 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6920 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6921 if (
Op.isScalarReg()) {
6923 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6930 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6931 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6932 if (
Op.isScalarReg() &&
6933 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6937 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6938 if (
Op.isScalarReg()) {
6940 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6948 FeatureBitset MissingFeatures;
6951 unsigned MatchResult =
6952 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6953 MatchingInlineAsm, 1);
6957 if (MatchResult != Match_Success) {
6960 auto ShortFormNEONErrorInfo = ErrorInfo;
6961 auto ShortFormNEONMatchResult = MatchResult;
6962 auto ShortFormNEONMissingFeatures = MissingFeatures;
6965 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6966 MatchingInlineAsm, 0);
6971 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6972 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6973 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6974 MatchResult = ShortFormNEONMatchResult;
6975 ErrorInfo = ShortFormNEONErrorInfo;
6976 MissingFeatures = ShortFormNEONMissingFeatures;
6980 switch (MatchResult) {
6981 case Match_Success: {
6984 NumOperands = Operands.
size();
6985 for (
unsigned i = 1; i < NumOperands; ++i)
6986 OperandLocs.
push_back(Operands[i]->getStartLoc());
6987 if (validateInstruction(Inst, IDLoc, OperandLocs))
6994 case Match_MissingFeature: {
6995 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6998 std::string Msg =
"instruction requires:";
6999 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
7000 if (MissingFeatures[i]) {
7005 return Error(IDLoc, Msg);
7007 case Match_MnemonicFail:
7008 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
7009 case Match_InvalidOperand: {
7010 SMLoc ErrorLoc = IDLoc;
7012 if (ErrorInfo != ~0ULL) {
7013 if (ErrorInfo >= Operands.
size())
7014 return Error(IDLoc,
"too few operands for instruction",
7015 SMRange(IDLoc, getTok().getLoc()));
7017 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7018 if (ErrorLoc == SMLoc())
7023 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
7024 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
7025 MatchResult = Match_InvalidSuffix;
7027 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7029 case Match_InvalidTiedOperand:
7030 case Match_InvalidMemoryIndexed1:
7031 case Match_InvalidMemoryIndexed2:
7032 case Match_InvalidMemoryIndexed4:
7033 case Match_InvalidMemoryIndexed8:
7034 case Match_InvalidMemoryIndexed16:
7035 case Match_InvalidCondCode:
7036 case Match_AddSubLSLImm3ShiftLarge:
7037 case Match_AddSubRegExtendSmall:
7038 case Match_AddSubRegExtendLarge:
7039 case Match_AddSubSecondSource:
7040 case Match_LogicalSecondSource:
7041 case Match_AddSubRegShift32:
7042 case Match_AddSubRegShift64:
7043 case Match_InvalidMovImm32Shift:
7044 case Match_InvalidMovImm64Shift:
7045 case Match_InvalidFPImm:
7046 case Match_InvalidMemoryWExtend8:
7047 case Match_InvalidMemoryWExtend16:
7048 case Match_InvalidMemoryWExtend32:
7049 case Match_InvalidMemoryWExtend64:
7050 case Match_InvalidMemoryWExtend128:
7051 case Match_InvalidMemoryXExtend8:
7052 case Match_InvalidMemoryXExtend16:
7053 case Match_InvalidMemoryXExtend32:
7054 case Match_InvalidMemoryXExtend64:
7055 case Match_InvalidMemoryXExtend128:
7056 case Match_InvalidMemoryIndexed1SImm4:
7057 case Match_InvalidMemoryIndexed2SImm4:
7058 case Match_InvalidMemoryIndexed3SImm4:
7059 case Match_InvalidMemoryIndexed4SImm4:
7060 case Match_InvalidMemoryIndexed1SImm6:
7061 case Match_InvalidMemoryIndexed16SImm4:
7062 case Match_InvalidMemoryIndexed32SImm4:
7063 case Match_InvalidMemoryIndexed4SImm7:
7064 case Match_InvalidMemoryIndexed8SImm7:
7065 case Match_InvalidMemoryIndexed16SImm7:
7066 case Match_InvalidMemoryIndexed8UImm5:
7067 case Match_InvalidMemoryIndexed8UImm3:
7068 case Match_InvalidMemoryIndexed4UImm5:
7069 case Match_InvalidMemoryIndexed2UImm5:
7070 case Match_InvalidMemoryIndexed1UImm6:
7071 case Match_InvalidMemoryIndexed2UImm6:
7072 case Match_InvalidMemoryIndexed4UImm6:
7073 case Match_InvalidMemoryIndexed8UImm6:
7074 case Match_InvalidMemoryIndexed16UImm6:
7075 case Match_InvalidMemoryIndexedSImm6:
7076 case Match_InvalidMemoryIndexedSImm5:
7077 case Match_InvalidMemoryIndexedSImm8:
7078 case Match_InvalidMemoryIndexedSImm9:
7079 case Match_InvalidMemoryIndexed16SImm9:
7080 case Match_InvalidMemoryIndexed8SImm10:
7081 case Match_InvalidImm0_0:
7082 case Match_InvalidImm0_1:
7083 case Match_InvalidImm0_3:
7084 case Match_InvalidImm0_7:
7085 case Match_InvalidImm0_15:
7086 case Match_InvalidImm0_31:
7087 case Match_InvalidImm0_63:
7088 case Match_InvalidImm0_127:
7089 case Match_InvalidImm0_255:
7090 case Match_InvalidImm0_65535:
7091 case Match_InvalidImm1_8:
7092 case Match_InvalidImm1_16:
7093 case Match_InvalidImm1_32:
7094 case Match_InvalidImm1_64:
7095 case Match_InvalidImmM1_62:
7096 case Match_InvalidMemoryIndexedRange2UImm0:
7097 case Match_InvalidMemoryIndexedRange2UImm1:
7098 case Match_InvalidMemoryIndexedRange2UImm2:
7099 case Match_InvalidMemoryIndexedRange2UImm3:
7100 case Match_InvalidMemoryIndexedRange4UImm0:
7101 case Match_InvalidMemoryIndexedRange4UImm1:
7102 case Match_InvalidMemoryIndexedRange4UImm2:
7103 case Match_InvalidSVEAddSubImm8:
7104 case Match_InvalidSVEAddSubImm16:
7105 case Match_InvalidSVEAddSubImm32:
7106 case Match_InvalidSVEAddSubImm64:
7107 case Match_InvalidSVECpyImm8:
7108 case Match_InvalidSVECpyImm16:
7109 case Match_InvalidSVECpyImm32:
7110 case Match_InvalidSVECpyImm64:
7111 case Match_InvalidIndexRange0_0:
7112 case Match_InvalidIndexRange1_1:
7113 case Match_InvalidIndexRange0_15:
7114 case Match_InvalidIndexRange0_7:
7115 case Match_InvalidIndexRange0_3:
7116 case Match_InvalidIndexRange0_1:
7117 case Match_InvalidSVEIndexRange0_63:
7118 case Match_InvalidSVEIndexRange0_31:
7119 case Match_InvalidSVEIndexRange0_15:
7120 case Match_InvalidSVEIndexRange0_7:
7121 case Match_InvalidSVEIndexRange0_3:
7122 case Match_InvalidLabel:
7123 case Match_InvalidComplexRotationEven:
7124 case Match_InvalidComplexRotationOdd:
7125 case Match_InvalidGPR64shifted8:
7126 case Match_InvalidGPR64shifted16:
7127 case Match_InvalidGPR64shifted32:
7128 case Match_InvalidGPR64shifted64:
7129 case Match_InvalidGPR64shifted128:
7130 case Match_InvalidGPR64NoXZRshifted8:
7131 case Match_InvalidGPR64NoXZRshifted16:
7132 case Match_InvalidGPR64NoXZRshifted32:
7133 case Match_InvalidGPR64NoXZRshifted64:
7134 case Match_InvalidGPR64NoXZRshifted128:
7135 case Match_InvalidZPR32UXTW8:
7136 case Match_InvalidZPR32UXTW16:
7137 case Match_InvalidZPR32UXTW32:
7138 case Match_InvalidZPR32UXTW64:
7139 case Match_InvalidZPR32SXTW8:
7140 case Match_InvalidZPR32SXTW16:
7141 case Match_InvalidZPR32SXTW32:
7142 case Match_InvalidZPR32SXTW64:
7143 case Match_InvalidZPR64UXTW8:
7144 case Match_InvalidZPR64SXTW8:
7145 case Match_InvalidZPR64UXTW16:
7146 case Match_InvalidZPR64SXTW16:
7147 case Match_InvalidZPR64UXTW32:
7148 case Match_InvalidZPR64SXTW32:
7149 case Match_InvalidZPR64UXTW64:
7150 case Match_InvalidZPR64SXTW64:
7151 case Match_InvalidZPR32LSL8:
7152 case Match_InvalidZPR32LSL16:
7153 case Match_InvalidZPR32LSL32:
7154 case Match_InvalidZPR32LSL64:
7155 case Match_InvalidZPR64LSL8:
7156 case Match_InvalidZPR64LSL16:
7157 case Match_InvalidZPR64LSL32:
7158 case Match_InvalidZPR64LSL64:
7159 case Match_InvalidZPR0:
7160 case Match_InvalidZPR8:
7161 case Match_InvalidZPR16:
7162 case Match_InvalidZPR32:
7163 case Match_InvalidZPR64:
7164 case Match_InvalidZPR128:
7165 case Match_InvalidZPR_3b8:
7166 case Match_InvalidZPR_3b16:
7167 case Match_InvalidZPR_3b32:
7168 case Match_InvalidZPR_4b8:
7169 case Match_InvalidZPR_4b16:
7170 case Match_InvalidZPR_4b32:
7171 case Match_InvalidZPR_4b64:
7172 case Match_InvalidSVEPPRorPNRAnyReg:
7173 case Match_InvalidSVEPPRorPNRBReg:
7174 case Match_InvalidSVEPredicateAnyReg:
7175 case Match_InvalidSVEPattern:
7176 case Match_InvalidSVEVecLenSpecifier:
7177 case Match_InvalidSVEPredicateBReg:
7178 case Match_InvalidSVEPredicateHReg:
7179 case Match_InvalidSVEPredicateSReg:
7180 case Match_InvalidSVEPredicateDReg:
7181 case Match_InvalidSVEPredicate3bAnyReg:
7182 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7183 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7184 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7185 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7186 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7187 case Match_InvalidSVEPNPredicateBReg:
7188 case Match_InvalidSVEPNPredicateHReg:
7189 case Match_InvalidSVEPNPredicateSReg:
7190 case Match_InvalidSVEPNPredicateDReg:
7191 case Match_InvalidSVEPredicateListMul2x8:
7192 case Match_InvalidSVEPredicateListMul2x16:
7193 case Match_InvalidSVEPredicateListMul2x32:
7194 case Match_InvalidSVEPredicateListMul2x64:
7195 case Match_InvalidSVEExactFPImmOperandHalfOne:
7196 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7197 case Match_InvalidSVEExactFPImmOperandZeroOne:
7198 case Match_InvalidMatrixTile16:
7199 case Match_InvalidMatrixTile32:
7200 case Match_InvalidMatrixTile64:
7201 case Match_InvalidMatrix:
7202 case Match_InvalidMatrix8:
7203 case Match_InvalidMatrix16:
7204 case Match_InvalidMatrix32:
7205 case Match_InvalidMatrix64:
7206 case Match_InvalidMatrixTileVectorH8:
7207 case Match_InvalidMatrixTileVectorH16:
7208 case Match_InvalidMatrixTileVectorH32:
7209 case Match_InvalidMatrixTileVectorH64:
7210 case Match_InvalidMatrixTileVectorH128:
7211 case Match_InvalidMatrixTileVectorV8:
7212 case Match_InvalidMatrixTileVectorV16:
7213 case Match_InvalidMatrixTileVectorV32:
7214 case Match_InvalidMatrixTileVectorV64:
7215 case Match_InvalidMatrixTileVectorV128:
7216 case Match_InvalidSVCR:
7217 case Match_InvalidMatrixIndexGPR32_12_15:
7218 case Match_InvalidMatrixIndexGPR32_8_11:
7219 case Match_InvalidLookupTable:
7220 case Match_InvalidZPRMul2_Lo8:
7221 case Match_InvalidZPRMul2_Hi8:
7222 case Match_InvalidZPRMul2_Lo16:
7223 case Match_InvalidZPRMul2_Hi16:
7224 case Match_InvalidZPRMul2_Lo32:
7225 case Match_InvalidZPRMul2_Hi32:
7226 case Match_InvalidZPRMul2_Lo64:
7227 case Match_InvalidZPRMul2_Hi64:
7228 case Match_InvalidZPR_K0:
7229 case Match_InvalidSVEVectorList2x8Mul2:
7230 case Match_InvalidSVEVectorList2x16Mul2:
7231 case Match_InvalidSVEVectorList2x32Mul2:
7232 case Match_InvalidSVEVectorList2x64Mul2:
7233 case Match_InvalidSVEVectorList2x128Mul2:
7234 case Match_InvalidSVEVectorList4x8Mul4:
7235 case Match_InvalidSVEVectorList4x16Mul4:
7236 case Match_InvalidSVEVectorList4x32Mul4:
7237 case Match_InvalidSVEVectorList4x64Mul4:
7238 case Match_InvalidSVEVectorList4x128Mul4:
7239 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7240 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7241 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7242 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7243 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7244 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7245 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7246 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7247 case Match_InvalidSVEVectorListStrided2x8:
7248 case Match_InvalidSVEVectorListStrided2x16:
7249 case Match_InvalidSVEVectorListStrided2x32:
7250 case Match_InvalidSVEVectorListStrided2x64:
7251 case Match_InvalidSVEVectorListStrided4x8:
7252 case Match_InvalidSVEVectorListStrided4x16:
7253 case Match_InvalidSVEVectorListStrided4x32:
7254 case Match_InvalidSVEVectorListStrided4x64:
7257 if (ErrorInfo >= Operands.
size())
7258 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7261 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7262 if (ErrorLoc == SMLoc())
7264 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7272bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7279 SMLoc Loc = DirectiveID.
getLoc();
7280 if (IDVal ==
".arch")
7281 parseDirectiveArch(Loc);
7282 else if (IDVal ==
".cpu")
7283 parseDirectiveCPU(Loc);
7284 else if (IDVal ==
".tlsdesccall")
7285 parseDirectiveTLSDescCall(Loc);
7286 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7287 parseDirectiveLtorg(Loc);
7288 else if (IDVal ==
".unreq")
7289 parseDirectiveUnreq(Loc);
7290 else if (IDVal ==
".inst")
7291 parseDirectiveInst(Loc);
7292 else if (IDVal ==
".cfi_negate_ra_state")
7293 parseDirectiveCFINegateRAState();
7294 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7295 parseDirectiveCFINegateRAStateWithPC();
7296 else if (IDVal ==
".cfi_b_key_frame")
7297 parseDirectiveCFIBKeyFrame();
7298 else if (IDVal ==
".cfi_mte_tagged_frame")
7299 parseDirectiveCFIMTETaggedFrame();
7300 else if (IDVal ==
".arch_extension")
7301 parseDirectiveArchExtension(Loc);
7302 else if (IDVal ==
".variant_pcs")
7303 parseDirectiveVariantPCS(Loc);
7306 parseDirectiveLOH(IDVal, Loc);
7309 }
else if (IsCOFF) {
7310 if (IDVal ==
".seh_stackalloc")
7311 parseDirectiveSEHAllocStack(Loc);
7312 else if (IDVal ==
".seh_endprologue")
7313 parseDirectiveSEHPrologEnd(Loc);
7314 else if (IDVal ==
".seh_save_r19r20_x")
7315 parseDirectiveSEHSaveR19R20X(Loc);
7316 else if (IDVal ==
".seh_save_fplr")
7317 parseDirectiveSEHSaveFPLR(Loc);
7318 else if (IDVal ==
".seh_save_fplr_x")
7319 parseDirectiveSEHSaveFPLRX(Loc);
7320 else if (IDVal ==
".seh_save_reg")
7321 parseDirectiveSEHSaveReg(Loc);
7322 else if (IDVal ==
".seh_save_reg_x")
7323 parseDirectiveSEHSaveRegX(Loc);
7324 else if (IDVal ==
".seh_save_regp")
7325 parseDirectiveSEHSaveRegP(Loc);
7326 else if (IDVal ==
".seh_save_regp_x")
7327 parseDirectiveSEHSaveRegPX(Loc);
7328 else if (IDVal ==
".seh_save_lrpair")
7329 parseDirectiveSEHSaveLRPair(Loc);
7330 else if (IDVal ==
".seh_save_freg")
7331 parseDirectiveSEHSaveFReg(Loc);
7332 else if (IDVal ==
".seh_save_freg_x")
7333 parseDirectiveSEHSaveFRegX(Loc);
7334 else if (IDVal ==
".seh_save_fregp")
7335 parseDirectiveSEHSaveFRegP(Loc);
7336 else if (IDVal ==
".seh_save_fregp_x")
7337 parseDirectiveSEHSaveFRegPX(Loc);
7338 else if (IDVal ==
".seh_set_fp")
7339 parseDirectiveSEHSetFP(Loc);
7340 else if (IDVal ==
".seh_add_fp")
7341 parseDirectiveSEHAddFP(Loc);
7342 else if (IDVal ==
".seh_nop")
7343 parseDirectiveSEHNop(Loc);
7344 else if (IDVal ==
".seh_save_next")
7345 parseDirectiveSEHSaveNext(Loc);
7346 else if (IDVal ==
".seh_startepilogue")
7347 parseDirectiveSEHEpilogStart(Loc);
7348 else if (IDVal ==
".seh_endepilogue")
7349 parseDirectiveSEHEpilogEnd(Loc);
7350 else if (IDVal ==
".seh_trap_frame")
7351 parseDirectiveSEHTrapFrame(Loc);
7352 else if (IDVal ==
".seh_pushframe")
7353 parseDirectiveSEHMachineFrame(Loc);
7354 else if (IDVal ==
".seh_context")
7355 parseDirectiveSEHContext(Loc);
7356 else if (IDVal ==
".seh_ec_context")
7357 parseDirectiveSEHECContext(Loc);
7358 else if (IDVal ==
".seh_clear_unwound_to_call")
7359 parseDirectiveSEHClearUnwoundToCall(Loc);
7360 else if (IDVal ==
".seh_pac_sign_lr")
7361 parseDirectiveSEHPACSignLR(Loc);
7362 else if (IDVal ==
".seh_save_any_reg")
7363 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7364 else if (IDVal ==
".seh_save_any_reg_p")
7365 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7366 else if (IDVal ==
".seh_save_any_reg_x")
7367 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7368 else if (IDVal ==
".seh_save_any_reg_px")
7369 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7370 else if (IDVal ==
".seh_allocz")
7371 parseDirectiveSEHAllocZ(Loc);
7372 else if (IDVal ==
".seh_save_zreg")
7373 parseDirectiveSEHSaveZReg(Loc);
7374 else if (IDVal ==
".seh_save_preg")
7375 parseDirectiveSEHSavePReg(Loc);
7379 if (IDVal ==
".aeabi_subsection")
7380 parseDirectiveAeabiSubSectionHeader(Loc);
7381 else if (IDVal ==
".aeabi_attribute")
7382 parseDirectiveAeabiAArch64Attr(Loc);
7395 if (!NoCrypto && Crypto) {
7398 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7399 ArchInfo == AArch64::ARMV8_3A) {
7403 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7404 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7405 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7406 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7407 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7408 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7414 }
else if (NoCrypto) {
7417 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7418 ArchInfo == AArch64::ARMV8_3A) {
7419 RequestedExtensions.
push_back(
"nosha2");
7422 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7423 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7424 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7425 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7426 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7427 ArchInfo == AArch64::ARMV9_4A) {
7429 RequestedExtensions.
push_back(
"nosha3");
7430 RequestedExtensions.
push_back(
"nosha2");
7442bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7443 SMLoc CurLoc = getLoc();
7445 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7446 StringRef Arch, ExtensionString;
7447 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7451 return Error(CurLoc,
"unknown arch name");
7457 std::vector<StringRef> AArch64Features;
7461 MCSubtargetInfo &STI = copySTI();
7462 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7464 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7467 if (!ExtensionString.
empty())
7468 ExtensionString.
split(RequestedExtensions,
'+');
7473 for (
auto Name : RequestedExtensions) {
7477 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7484 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7492 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7493 setAvailableFeatures(Features);
7495 getTargetStreamer().emitDirectiveArch(Name);
7501bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7502 SMLoc ExtLoc = getLoc();
7504 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7509 bool EnableFeature =
true;
7510 StringRef
Name = FullName;
7511 if (
Name.starts_with_insensitive(
"no")) {
7512 EnableFeature =
false;
7521 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7523 MCSubtargetInfo &STI = copySTI();
7528 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7529 setAvailableFeatures(Features);
7531 getTargetStreamer().emitDirectiveArchExtension(FullName);
7537bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7538 SMLoc CurLoc = getLoc();
7540 StringRef CPU, ExtensionString;
7541 std::tie(CPU, ExtensionString) =
7542 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7548 if (!ExtensionString.
empty())
7549 ExtensionString.
split(RequestedExtensions,
'+');
7553 Error(CurLoc,
"unknown CPU name");
7558 MCSubtargetInfo &STI = copySTI();
7562 for (
auto Name : RequestedExtensions) {
7566 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7573 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7581 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7582 setAvailableFeatures(Features);
7588bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7590 return Error(Loc,
"expected expression following '.inst' directive");
7592 auto parseOp = [&]() ->
bool {
7594 const MCExpr *Expr =
nullptr;
7595 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7598 if (check(!
Value, L,
"expected constant expression"))
7600 getTargetStreamer().emitInst(
Value->getValue());
7604 return parseMany(parseOp);
7609bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7611 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7623 getParser().getStreamer().emitInstruction(Inst, getSTI());
7629bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7633 return TokError(
"expected an identifier or a number in directive");
7636 int64_t
Id = getTok().getIntVal();
7638 return TokError(
"invalid numeric identifier in directive");
7641 StringRef
Name = getTok().getIdentifier();
7647 return TokError(
"invalid identifier in directive");
7655 assert(NbArgs != -1 &&
"Invalid number of arguments");
7658 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7660 if (getParser().parseIdentifier(Name))
7661 return TokError(
"expected identifier in directive");
7664 if (Idx + 1 == NbArgs)
7672 getStreamer().emitLOHDirective(Kind, Args);
7678bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7681 getTargetStreamer().emitCurrentConstantPool();
7687bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7689 SMLoc SRegLoc = getLoc();
7690 RegKind RegisterKind = RegKind::Scalar;
7692 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7696 RegisterKind = RegKind::NeonVector;
7697 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7703 return Error(SRegLoc,
"vector register without type specifier expected");
7708 RegisterKind = RegKind::SVEDataVector;
7710 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7716 return Error(SRegLoc,
7717 "sve vector register without type specifier expected");
7722 RegisterKind = RegKind::SVEPredicateVector;
7723 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7729 return Error(SRegLoc,
7730 "sve predicate register without type specifier expected");
7734 return Error(SRegLoc,
"register name or alias expected");
7740 auto pair = std::make_pair(RegisterKind, RegNum);
7741 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7742 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7749bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7751 return TokError(
"unexpected input in .unreq directive.");
7752 RegisterReqs.
erase(getTok().getIdentifier().lower());
7757bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7760 getStreamer().emitCFINegateRAState();
7764bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7767 getStreamer().emitCFINegateRAStateWithPC();
7773bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7776 getStreamer().emitCFIBKeyFrame();
7782bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7785 getStreamer().emitCFIMTETaggedFrame();
7791bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7793 if (getParser().parseIdentifier(Name))
7794 return TokError(
"expected symbol name");
7797 getTargetStreamer().emitDirectiveVariantPCS(
7804bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7806 if (parseImmExpr(
Size))
7808 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7814bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7815 getTargetStreamer().emitARM64WinCFIPrologEnd();
7821bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7823 if (parseImmExpr(
Offset))
7825 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7831bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7833 if (parseImmExpr(
Offset))
7835 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7841bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7843 if (parseImmExpr(
Offset))
7845 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7851bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7854 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7855 parseComma() || parseImmExpr(
Offset))
7857 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7863bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7866 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7867 parseComma() || parseImmExpr(
Offset))
7869 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7875bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7878 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7879 parseComma() || parseImmExpr(
Offset))
7881 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7887bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7890 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7891 parseComma() || parseImmExpr(
Offset))
7893 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7899bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7903 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7904 parseComma() || parseImmExpr(
Offset))
7906 if (check(((
Reg - 19) % 2 != 0), L,
7907 "expected register with even offset from x19"))
7909 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7915bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7918 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7919 parseComma() || parseImmExpr(
Offset))
7921 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7927bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7930 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7931 parseComma() || parseImmExpr(
Offset))
7933 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7939bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7942 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7943 parseComma() || parseImmExpr(
Offset))
7945 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7951bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7954 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7955 parseComma() || parseImmExpr(
Offset))
7957 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7963bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7964 getTargetStreamer().emitARM64WinCFISetFP();
7970bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7972 if (parseImmExpr(
Size))
7974 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7980bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7981 getTargetStreamer().emitARM64WinCFINop();
7987bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7988 getTargetStreamer().emitARM64WinCFISaveNext();
7994bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7995 getTargetStreamer().emitARM64WinCFIEpilogStart();
8001bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
8002 getTargetStreamer().emitARM64WinCFIEpilogEnd();
8008bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
8009 getTargetStreamer().emitARM64WinCFITrapFrame();
8015bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
8016 getTargetStreamer().emitARM64WinCFIMachineFrame();
8022bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
8023 getTargetStreamer().emitARM64WinCFIContext();
8029bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
8030 getTargetStreamer().emitARM64WinCFIECContext();
8036bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
8037 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
8043bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
8044 getTargetStreamer().emitARM64WinCFIPACSignLR();
8053bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
8058 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
8059 parseComma() || parseImmExpr(
Offset))
8062 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
8063 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
8064 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8065 return Error(L,
"invalid save_any_reg offset");
8066 unsigned EncodedReg;
8067 if (
Reg == AArch64::FP)
8069 else if (
Reg == AArch64::LR)
8072 EncodedReg =
Reg - AArch64::X0;
8074 if (
Reg == AArch64::LR)
8075 return Error(Start,
"lr cannot be paired with another register");
8077 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
8079 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
8082 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
8084 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
8086 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
8087 unsigned EncodedReg =
Reg - AArch64::D0;
8088 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8089 return Error(L,
"invalid save_any_reg offset");
8091 if (
Reg == AArch64::D31)
8092 return Error(Start,
"d31 cannot be paired with another register");
8094 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
8096 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
8099 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
8101 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
8103 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
8104 unsigned EncodedReg =
Reg - AArch64::Q0;
8106 return Error(L,
"invalid save_any_reg offset");
8108 if (
Reg == AArch64::Q31)
8109 return Error(Start,
"q31 cannot be paired with another register");
8111 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
8113 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
8116 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
8118 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
8121 return Error(Start,
"save_any_reg register must be x, q or d register");
8128bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8130 if (parseImmExpr(
Offset))
8132 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8138bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8143 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8146 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8147 "expected register in range z8 to z23"))
8149 if (parseComma() || parseImmExpr(
Offset))
8151 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8157bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8162 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8165 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8166 "expected register in range p4 to p15"))
8168 if (parseComma() || parseImmExpr(
Offset))
8170 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8174bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8180 MCAsmParser &Parser = getParser();
8183 StringRef SubsectionName;
8194 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8195 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8200 if (SubsectionExists) {
8201 getTargetStreamer().emitAttributesSubsection(
8204 SubsectionExists->IsOptional),
8206 SubsectionExists->ParameterType));
8212 "Could not switch to subsection '" + SubsectionName +
8213 "' using subsection name, subsection has not been defined");
8236 if (SubsectionExists) {
8237 if (IsOptional != SubsectionExists->IsOptional) {
8239 "optionality mismatch! subsection '" + SubsectionName +
8240 "' already exists with optionality defined as '" +
8242 SubsectionExists->IsOptional) +
8250 "optionality parameter not found, expected required|optional");
8257 "aeabi_feature_and_bits must be marked as optional");
8264 "aeabi_pauthabi must be marked as required");
8284 if (SubsectionExists) {
8285 if (
Type != SubsectionExists->ParameterType) {
8287 "type mismatch! subsection '" + SubsectionName +
8288 "' already exists with type defined as '" +
8290 SubsectionExists->ParameterType) +
8298 "type parameter not found, expected uleb128|ntbs");
8306 SubsectionName +
" must be marked as ULEB128");
8315 "attributes subsection header directive");
8319 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8324bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8328 MCAsmParser &Parser = getParser();
8330 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8331 getTargetStreamer().getActiveAttributesSubsection();
8332 if (
nullptr == ActiveSubsection) {
8334 "no active subsection, build attribute can not be added");
8337 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8338 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8346 ActiveSubsectionName)
8349 StringRef TagStr =
"";
8352 Tag = getTok().getIntVal();
8355 switch (ActiveSubsectionID) {
8360 "' \nExcept for public subsections, "
8361 "tags have to be an unsigned int.");
8368 TagStr +
"' for subsection '" +
8369 ActiveSubsectionName +
"'");
8377 TagStr +
"' for subsection '" +
8378 ActiveSubsectionName +
"'");
8396 unsigned ValueInt = unsigned(-1);
8397 std::string ValueStr =
"";
8402 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8405 ValueInt = getTok().getIntVal();
8410 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8418 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8429 if (0 != ValueInt && 1 != ValueInt) {
8431 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8432 "' options are 0|1");
8441 "unexpected token for AArch64 build attributes tag and value "
8442 "attribute directive");
8446 if (
unsigned(-1) != ValueInt) {
8447 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8449 if (
"" != ValueStr) {
8450 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8456bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8457 SMLoc Loc = getLoc();
8459 return TokError(
"expected '%' relocation specifier");
8460 StringRef
Identifier = getParser().getTok().getIdentifier();
8463 return TokError(
"invalid relocation specifier");
8469 const MCExpr *SubExpr;
8470 if (getParser().parseParenExpression(SubExpr,
E))
8477bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8480 return parseExprWithSpecifier(Res, EndLoc);
8482 if (getParser().parseExpression(Res))
8484 MCAsmParser &Parser = getParser();
8488 return Error(getLoc(),
"expected relocation specifier");
8491 SMLoc Loc = getLoc();
8493 if (Identifier ==
"auth")
8494 return parseAuthExpr(Res, EndLoc);
8498 if (Identifier ==
"got")
8502 return Error(Loc,
"invalid relocation specifier");
8507 return Error(Loc,
"@ specifier only allowed after a symbol");
8510 std::optional<MCBinaryExpr::Opcode> Opcode;
8518 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8529bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8530 MCAsmParser &Parser = getParser();
8532 AsmToken Tok = Parser.
getTok();
8539 return TokError(
"expected key name");
8544 return TokError(
"invalid key '" + KeyStr +
"'");
8551 return TokError(
"expected integer discriminator");
8555 return TokError(
"integer discriminator " + Twine(Discriminator) +
8556 " out of range [0, 0xFFFF]");
8559 bool UseAddressDiversity =
false;
8564 return TokError(
"expected 'addr'");
8565 UseAddressDiversity =
true;
8574 UseAddressDiversity, Ctx, Res->
getLoc());
8578bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8587 ELFSpec = AE->getSpecifier();
8588 Expr = AE->getSubExpr();
8628#define GET_REGISTER_MATCHER
8629#define GET_SUBTARGET_FEATURE_NAME
8630#define GET_MATCHER_IMPLEMENTATION
8631#define GET_MNEMONIC_SPELL_CHECKER
8632#include "AArch64GenAsmMatcher.inc"
8638 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8640 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8642 return Match_InvalidOperand;
8645 return Match_InvalidOperand;
8646 if (CE->getValue() == ExpectedVal)
8647 return Match_Success;
8648 return Match_InvalidOperand;
8653 return Match_InvalidOperand;
8659 if (
Op.isTokenEqual(
"za"))
8660 return Match_Success;
8661 return Match_InvalidOperand;
8667#define MATCH_HASH(N) \
8668 case MCK__HASH_##N: \
8669 return MatchesOpImmediate(N);
8695#define MATCH_HASH_MINUS(N) \
8696 case MCK__HASH__MINUS_##N: \
8697 return MatchesOpImmediate(-N);
8701#undef MATCH_HASH_MINUS
8705ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8710 return Error(S,
"expected register");
8712 MCRegister FirstReg;
8713 ParseStatus Res = tryParseScalarRegister(FirstReg);
8715 return Error(S,
"expected first even register of a consecutive same-size "
8716 "even/odd register pair");
8718 const MCRegisterClass &WRegClass =
8719 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8720 const MCRegisterClass &XRegClass =
8721 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8723 bool isXReg = XRegClass.
contains(FirstReg),
8724 isWReg = WRegClass.
contains(FirstReg);
8725 if (!isXReg && !isWReg)
8726 return Error(S,
"expected first even register of a consecutive same-size "
8727 "even/odd register pair");
8729 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8732 if (FirstEncoding & 0x1)
8733 return Error(S,
"expected first even register of a consecutive same-size "
8734 "even/odd register pair");
8737 return Error(getLoc(),
"expected comma");
8742 MCRegister SecondReg;
8743 Res = tryParseScalarRegister(SecondReg);
8745 return Error(
E,
"expected second odd register of a consecutive same-size "
8746 "even/odd register pair");
8749 (isXReg && !XRegClass.
contains(SecondReg)) ||
8750 (isWReg && !WRegClass.
contains(SecondReg)))
8751 return Error(
E,
"expected second odd register of a consecutive same-size "
8752 "even/odd register pair");
8757 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8760 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8763 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8769template <
bool ParseShiftExtend,
bool ParseSuffix>
8770ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8771 const SMLoc S = getLoc();
8777 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8782 if (ParseSuffix &&
Kind.empty())
8789 unsigned ElementWidth = KindRes->second;
8793 Operands.
push_back(AArch64Operand::CreateVectorReg(
8794 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8796 ParseStatus Res = tryParseVectorIndex(Operands);
8807 Res = tryParseOptionalShiftExtend(ExtOpnd);
8811 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8812 Operands.
push_back(AArch64Operand::CreateVectorReg(
8813 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8814 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8815 Ext->hasShiftExtendAmount()));
8820ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8821 MCAsmParser &Parser = getParser();
8823 SMLoc
SS = getLoc();
8824 const AsmToken &TokE = getTok();
8835 const MCExpr *ImmVal;
8842 return TokError(
"invalid operand for instruction");
8847 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8852 Pattern = Pat->Encoding;
8853 assert(Pattern >= 0 && Pattern < 32);
8864AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8866 SMLoc
SS = getLoc();
8867 const AsmToken &TokE = getTok();
8869 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8875 Pattern = Pat->Encoding;
8876 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8885ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8886 SMLoc
SS = getLoc();
8889 if (!tryParseScalarRegister(XReg).isSuccess())
8895 XReg, AArch64::x8sub_0,
8896 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8899 "expected an even-numbered x-register in the range [x0,x22]");
8902 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8906ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8916 if (getParser().parseExpression(ImmF))
8926 SMLoc
E = getTok().getLoc();
8928 if (getParser().parseExpression(ImmL))
8935 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8940ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8950 if (getParser().parseExpression(Ex))
8960 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8967 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")
#define LLVM_EXTERNAL_VISIBILITY
Value * getPointer(Value *Ptr)
loop data Loop Data Prefetch
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static 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.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
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 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
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