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 parseDataExpr(
const MCExpr *&Res)
override;
186 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
188 bool parseDirectiveArch(SMLoc L);
189 bool parseDirectiveArchExtension(SMLoc L);
190 bool parseDirectiveCPU(SMLoc L);
191 bool parseDirectiveInst(SMLoc L);
193 bool parseDirectiveTLSDescCall(SMLoc L);
195 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
196 bool parseDirectiveLtorg(SMLoc L);
198 bool parseDirectiveReq(StringRef Name, SMLoc L);
199 bool parseDirectiveUnreq(SMLoc L);
200 bool parseDirectiveCFINegateRAState();
201 bool parseDirectiveCFINegateRAStateWithPC();
202 bool parseDirectiveCFIBKeyFrame();
203 bool parseDirectiveCFIMTETaggedFrame();
205 bool parseDirectiveVariantPCS(SMLoc L);
207 bool parseDirectiveSEHAllocStack(SMLoc L);
208 bool parseDirectiveSEHPrologEnd(SMLoc L);
209 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
210 bool parseDirectiveSEHSaveFPLR(SMLoc L);
211 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
212 bool parseDirectiveSEHSaveReg(SMLoc L);
213 bool parseDirectiveSEHSaveRegX(SMLoc L);
214 bool parseDirectiveSEHSaveRegP(SMLoc L);
215 bool parseDirectiveSEHSaveRegPX(SMLoc L);
216 bool parseDirectiveSEHSaveLRPair(SMLoc L);
217 bool parseDirectiveSEHSaveFReg(SMLoc L);
218 bool parseDirectiveSEHSaveFRegX(SMLoc L);
219 bool parseDirectiveSEHSaveFRegP(SMLoc L);
220 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
221 bool parseDirectiveSEHSetFP(SMLoc L);
222 bool parseDirectiveSEHAddFP(SMLoc L);
223 bool parseDirectiveSEHNop(SMLoc L);
224 bool parseDirectiveSEHSaveNext(SMLoc L);
225 bool parseDirectiveSEHEpilogStart(SMLoc L);
226 bool parseDirectiveSEHEpilogEnd(SMLoc L);
227 bool parseDirectiveSEHTrapFrame(SMLoc L);
228 bool parseDirectiveSEHMachineFrame(SMLoc L);
229 bool parseDirectiveSEHContext(SMLoc L);
230 bool parseDirectiveSEHECContext(SMLoc L);
231 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
232 bool parseDirectiveSEHPACSignLR(SMLoc L);
233 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
234 bool parseDirectiveSEHAllocZ(SMLoc L);
235 bool parseDirectiveSEHSaveZReg(SMLoc L);
236 bool parseDirectiveSEHSavePReg(SMLoc L);
237 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
238 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
240 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
241 SmallVectorImpl<SMLoc> &Loc);
242 unsigned getNumRegsForRegKind(RegKind K);
243 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
246 bool MatchingInlineAsm)
override;
250#define GET_ASSEMBLER_HEADER
251#include "AArch64GenAsmMatcher.inc"
265 template <
bool IsSVEPrefetch = false>
274 template <
bool AddFPZeroAsLiteral>
282 template <
bool ParseShiftExtend,
283 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
286 template <
bool ParseShiftExtend,
bool ParseSuffix>
288 template <RegKind RK>
291 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
292 template <RegKind VectorKind>
294 bool ExpectMatch =
false);
304 enum AArch64MatchResultTy {
305 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
306#define GET_OPERAND_DIAGNOSTIC_TYPES
307#include "AArch64GenAsmMatcher.inc"
310 bool IsWindowsArm64EC;
312 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
313 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
314 : MCTargetAsmParser(
Options, STI, MII) {
318 MCStreamer &S = getParser().getStreamer();
320 new AArch64TargetStreamer(S);
332 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
335 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
336 const MCParsedAsmOperand &Op2)
const override;
337 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
339 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
340 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
341 SMLoc &EndLoc)
override;
342 bool ParseDirective(AsmToken DirectiveID)
override;
343 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
344 unsigned Kind)
override;
380 SMLoc StartLoc, EndLoc;
389 struct ShiftExtendOp {
392 bool HasExplicitAmount;
402 RegConstraintEqualityTy EqualityTy;
418 ShiftExtendOp ShiftExtend;
423 unsigned ElementWidth;
427 struct MatrixTileListOp {
428 unsigned RegMask = 0;
431 struct VectorListOp {
435 unsigned NumElements;
436 unsigned ElementWidth;
437 RegKind RegisterKind;
440 struct VectorIndexOp {
448 struct ShiftedImmOp {
450 unsigned ShiftAmount;
479 uint32_t PStateField;
507 struct CMHPriorityHintOp {
512 struct TIndexHintOp {
521 unsigned PStateField;
527 struct MatrixRegOp MatrixReg;
528 struct MatrixTileListOp MatrixTileList;
529 struct VectorListOp VectorList;
530 struct VectorIndexOp VectorIndex;
532 struct ShiftedImmOp ShiftedImm;
533 struct ImmRangeOp ImmRange;
535 struct FPImmOp FPImm;
537 struct SysRegOp SysReg;
538 struct SysCRImmOp SysCRImm;
540 struct PSBHintOp PSBHint;
541 struct PHintOp PHint;
542 struct BTIHintOp BTIHint;
543 struct CMHPriorityHintOp CMHPriorityHint;
544 struct TIndexHintOp TIndexHint;
545 struct ShiftExtendOp ShiftExtend;
554 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
556 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
558 StartLoc =
o.StartLoc;
568 ShiftedImm =
o.ShiftedImm;
571 ImmRange =
o.ImmRange;
585 case k_MatrixRegister:
586 MatrixReg =
o.MatrixReg;
588 case k_MatrixTileList:
589 MatrixTileList =
o.MatrixTileList;
592 VectorList =
o.VectorList;
595 VectorIndex =
o.VectorIndex;
601 SysCRImm =
o.SysCRImm;
615 case k_CMHPriorityHint:
616 CMHPriorityHint =
o.CMHPriorityHint;
619 TIndexHint =
o.TIndexHint;
622 ShiftExtend =
o.ShiftExtend;
631 SMLoc getStartLoc()
const override {
return StartLoc; }
633 SMLoc getEndLoc()
const override {
return EndLoc; }
636 assert(Kind == k_Token &&
"Invalid access!");
637 return StringRef(Tok.Data, Tok.Length);
640 bool isTokenSuffix()
const {
641 assert(Kind == k_Token &&
"Invalid access!");
645 const MCExpr *
getImm()
const {
646 assert(Kind == k_Immediate &&
"Invalid access!");
650 const MCExpr *getShiftedImmVal()
const {
651 assert(Kind == k_ShiftedImm &&
"Invalid access!");
652 return ShiftedImm.Val;
655 unsigned getShiftedImmShift()
const {
656 assert(Kind == k_ShiftedImm &&
"Invalid access!");
657 return ShiftedImm.ShiftAmount;
660 unsigned getFirstImmVal()
const {
661 assert(Kind == k_ImmRange &&
"Invalid access!");
662 return ImmRange.First;
665 unsigned getLastImmVal()
const {
666 assert(Kind == k_ImmRange &&
"Invalid access!");
667 return ImmRange.Last;
671 assert(Kind == k_CondCode &&
"Invalid access!");
676 assert (Kind == k_FPImm &&
"Invalid access!");
677 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
680 bool getFPImmIsExact()
const {
681 assert (Kind == k_FPImm &&
"Invalid access!");
682 return FPImm.IsExact;
685 unsigned getBarrier()
const {
686 assert(Kind == k_Barrier &&
"Invalid access!");
690 StringRef getBarrierName()
const {
691 assert(Kind == k_Barrier &&
"Invalid access!");
695 bool getBarriernXSModifier()
const {
696 assert(Kind == k_Barrier &&
"Invalid access!");
700 MCRegister
getReg()
const override {
701 assert(Kind == k_Register &&
"Invalid access!");
705 MCRegister getMatrixReg()
const {
706 assert(Kind == k_MatrixRegister &&
"Invalid access!");
707 return MatrixReg.Reg;
710 unsigned getMatrixElementWidth()
const {
711 assert(Kind == k_MatrixRegister &&
"Invalid access!");
712 return MatrixReg.ElementWidth;
715 MatrixKind getMatrixKind()
const {
716 assert(Kind == k_MatrixRegister &&
"Invalid access!");
717 return MatrixReg.Kind;
720 unsigned getMatrixTileListRegMask()
const {
721 assert(isMatrixTileList() &&
"Invalid access!");
722 return MatrixTileList.RegMask;
725 RegConstraintEqualityTy getRegEqualityTy()
const {
726 assert(Kind == k_Register &&
"Invalid access!");
727 return Reg.EqualityTy;
730 MCRegister getVectorListStart()
const {
731 assert(Kind == k_VectorList &&
"Invalid access!");
732 return VectorList.Reg;
735 unsigned getVectorListCount()
const {
736 assert(Kind == k_VectorList &&
"Invalid access!");
737 return VectorList.Count;
740 unsigned getVectorListStride()
const {
741 assert(Kind == k_VectorList &&
"Invalid access!");
742 return VectorList.Stride;
745 int getVectorIndex()
const {
746 assert(Kind == k_VectorIndex &&
"Invalid access!");
747 return VectorIndex.Val;
750 StringRef getSysReg()
const {
751 assert(Kind == k_SysReg &&
"Invalid access!");
752 return StringRef(SysReg.Data, SysReg.Length);
755 unsigned getSysCR()
const {
756 assert(Kind == k_SysCR &&
"Invalid access!");
760 unsigned getPrefetch()
const {
761 assert(Kind == k_Prefetch &&
"Invalid access!");
765 unsigned getPSBHint()
const {
766 assert(Kind == k_PSBHint &&
"Invalid access!");
770 unsigned getPHint()
const {
771 assert(Kind == k_PHint &&
"Invalid access!");
775 StringRef getPSBHintName()
const {
776 assert(Kind == k_PSBHint &&
"Invalid access!");
777 return StringRef(PSBHint.Data, PSBHint.Length);
780 StringRef getPHintName()
const {
781 assert(Kind == k_PHint &&
"Invalid access!");
782 return StringRef(PHint.Data, PHint.Length);
785 unsigned getBTIHint()
const {
786 assert(Kind == k_BTIHint &&
"Invalid access!");
790 StringRef getBTIHintName()
const {
791 assert(Kind == k_BTIHint &&
"Invalid access!");
792 return StringRef(BTIHint.Data, BTIHint.Length);
795 unsigned getCMHPriorityHint()
const {
796 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
797 return CMHPriorityHint.Val;
800 StringRef getCMHPriorityHintName()
const {
801 assert(Kind == k_CMHPriorityHint &&
"Invalid access!");
802 return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
805 unsigned getTIndexHint()
const {
806 assert(Kind == k_TIndexHint &&
"Invalid access!");
807 return TIndexHint.Val;
810 StringRef getTIndexHintName()
const {
811 assert(Kind == k_TIndexHint &&
"Invalid access!");
812 return StringRef(TIndexHint.Data, TIndexHint.Length);
815 StringRef getSVCR()
const {
816 assert(Kind == k_SVCR &&
"Invalid access!");
817 return StringRef(SVCR.Data, SVCR.Length);
820 StringRef getPrefetchName()
const {
821 assert(Kind == k_Prefetch &&
"Invalid access!");
826 if (Kind == k_ShiftExtend)
827 return ShiftExtend.Type;
828 if (Kind == k_Register)
829 return Reg.ShiftExtend.Type;
833 unsigned getShiftExtendAmount()
const {
834 if (Kind == k_ShiftExtend)
835 return ShiftExtend.Amount;
836 if (Kind == k_Register)
837 return Reg.ShiftExtend.Amount;
841 bool hasShiftExtendAmount()
const {
842 if (Kind == k_ShiftExtend)
843 return ShiftExtend.HasExplicitAmount;
844 if (Kind == k_Register)
845 return Reg.ShiftExtend.HasExplicitAmount;
849 bool isImm()
const override {
return Kind == k_Immediate; }
850 bool isMem()
const override {
return false; }
852 bool isUImm6()
const {
859 return (Val >= 0 && Val < 64);
862 template <
int W
idth>
bool isSImm()
const {
863 return bool(isSImmScaled<Width, 1>());
866 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
867 return isImmScaled<Bits, Scale>(
true);
870 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
871 DiagnosticPredicate isUImmScaled()
const {
872 if (IsRange && isImmRange() &&
873 (getLastImmVal() != getFirstImmVal() +
Offset))
876 return isImmScaled<Bits, Scale, IsRange>(
false);
879 template <
int Bits,
int Scale,
bool IsRange = false>
880 DiagnosticPredicate isImmScaled(
bool Signed)
const {
881 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
882 (isImmRange() && !IsRange))
887 Val = getFirstImmVal();
895 int64_t MinVal, MaxVal;
897 int64_t Shift =
Bits - 1;
898 MinVal = (int64_t(1) << Shift) * -Scale;
899 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
902 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
905 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
911 DiagnosticPredicate isSVEPattern()
const {
918 if (Val >= 0 && Val < 32)
923 DiagnosticPredicate isSVEVecLenSpecifier()
const {
930 if (Val >= 0 && Val <= 1)
935 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
939 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
968 template <
int Scale>
bool isUImm12Offset()
const {
974 return isSymbolicUImm12Offset(
getImm());
977 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
980 template <
int N,
int M>
981 bool isImmInRange()
const {
988 return (Val >=
N && Val <= M);
993 template <
typename T>
994 bool isLogicalImm()
const {
1003 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
1011 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
1013 bool isImmRange()
const {
return Kind == k_ImmRange; }
1018 template <
unsigned W
idth>
1019 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
1020 if (isShiftedImm() && Width == getShiftedImmShift())
1022 return std::make_pair(
CE->getValue(), Width);
1026 int64_t Val =
CE->getValue();
1027 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
1028 return std::make_pair(Val >> Width, Width);
1030 return std::make_pair(Val, 0u);
1036 bool isAddSubImm()
const {
1037 if (!isShiftedImm() && !isImm())
1043 if (isShiftedImm()) {
1044 unsigned Shift = ShiftedImm.ShiftAmount;
1045 Expr = ShiftedImm.Val;
1046 if (Shift != 0 && Shift != 12)
1055 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1071 if (
auto ShiftedVal = getShiftedVal<12>())
1072 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1079 bool isAddSubImmNeg()
const {
1080 if (!isShiftedImm() && !isImm())
1084 if (
auto ShiftedVal = getShiftedVal<12>())
1085 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1095 template <
typename T>
1096 DiagnosticPredicate isSVECpyImm()
const {
1100 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1101 std::is_same<int8_t, T>::value;
1102 if (
auto ShiftedImm = getShiftedVal<8>())
1103 if (!(IsByte && ShiftedImm->second) &&
1105 << ShiftedImm->second))
1114 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1118 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1119 std::is_same<int8_t, T>::value;
1120 if (
auto ShiftedImm = getShiftedVal<8>())
1121 if (!(IsByte && ShiftedImm->second) &&
1123 << ShiftedImm->second))
1129 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1130 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1135 bool isCondCode()
const {
return Kind == k_CondCode; }
1137 bool isSIMDImmType10()
const {
1147 bool isBranchTarget()
const {
1156 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1157 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1167 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1177 bool isMovWSymbolG3()
const {
1181 bool isMovWSymbolG2()
const {
1188 bool isMovWSymbolG1()
const {
1196 bool isMovWSymbolG0()
const {
1204 template<
int RegW
idth,
int Shift>
1205 bool isMOVZMovAlias()
const {
1206 if (!isImm())
return false;
1210 uint64_t
Value =
CE->getValue();
1219 template<
int RegW
idth,
int Shift>
1220 bool isMOVNMovAlias()
const {
1221 if (!isImm())
return false;
1224 if (!CE)
return false;
1225 uint64_t
Value =
CE->getValue();
1230 bool isFPImm()
const {
1231 return Kind == k_FPImm &&
1235 bool isBarrier()
const {
1236 return Kind == k_Barrier && !getBarriernXSModifier();
1238 bool isBarriernXS()
const {
1239 return Kind == k_Barrier && getBarriernXSModifier();
1241 bool isSysReg()
const {
return Kind == k_SysReg; }
1243 bool isMRSSystemRegister()
const {
1244 if (!isSysReg())
return false;
1246 return SysReg.MRSReg != -1U;
1249 bool isMSRSystemRegister()
const {
1250 if (!isSysReg())
return false;
1251 return SysReg.MSRReg != -1U;
1254 bool isSystemPStateFieldWithImm0_1()
const {
1255 if (!isSysReg())
return false;
1256 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1259 bool isSystemPStateFieldWithImm0_15()
const {
1262 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1265 bool isSVCR()
const {
1268 return SVCR.PStateField != -1U;
1271 bool isReg()
const override {
1272 return Kind == k_Register;
1275 bool isVectorList()
const {
return Kind == k_VectorList; }
1277 bool isScalarReg()
const {
1278 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1281 bool isNeonVectorReg()
const {
1282 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1285 bool isNeonVectorRegLo()
const {
1286 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1287 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1289 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1293 bool isNeonVectorReg0to7()
const {
1294 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1295 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1299 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1300 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1302 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1305 case AArch64::PPRRegClassID:
1306 case AArch64::PPR_3bRegClassID:
1307 case AArch64::PPR_p8to15RegClassID:
1308 case AArch64::PNRRegClassID:
1309 case AArch64::PNR_p8to15RegClassID:
1310 case AArch64::PPRorPNRRegClassID:
1311 RK = RegKind::SVEPredicateAsCounter;
1317 return (Kind == k_Register &&
Reg.Kind == RK) &&
1318 AArch64MCRegisterClasses[
Class].contains(
getReg());
1321 template <
unsigned Class>
bool isSVEVectorReg()
const {
1324 case AArch64::ZPRRegClassID:
1325 case AArch64::ZPR_3bRegClassID:
1326 case AArch64::ZPR_4bRegClassID:
1327 case AArch64::ZPRMul2_LoRegClassID:
1328 case AArch64::ZPRMul2_HiRegClassID:
1329 case AArch64::ZPR_KRegClassID:
1330 RK = RegKind::SVEDataVector;
1332 case AArch64::PPRRegClassID:
1333 case AArch64::PPR_3bRegClassID:
1334 case AArch64::PPR_p8to15RegClassID:
1335 case AArch64::PNRRegClassID:
1336 case AArch64::PNR_p8to15RegClassID:
1337 case AArch64::PPRorPNRRegClassID:
1338 RK = RegKind::SVEPredicateVector;
1344 return (Kind == k_Register &&
Reg.Kind == RK) &&
1345 AArch64MCRegisterClasses[
Class].contains(
getReg());
1348 template <
unsigned Class>
bool isFPRasZPR()
const {
1349 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1350 AArch64MCRegisterClasses[
Class].contains(
getReg());
1353 template <
int ElementW
idth,
unsigned Class>
1354 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1355 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1358 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1364 template <
int ElementW
idth,
unsigned Class>
1365 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1366 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1367 Reg.Kind != RegKind::SVEPredicateVector))
1370 if ((isSVEPredicateAsCounterReg<Class>() ||
1371 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1372 Reg.ElementWidth == ElementWidth)
1378 template <
int ElementW
idth,
unsigned Class>
1379 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1380 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1383 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1389 template <
int ElementW
idth,
unsigned Class>
1390 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1391 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1394 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1400 template <
int ElementWidth,
unsigned Class,
1402 bool ShiftWidthAlwaysSame>
1403 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1404 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1405 if (!VectorMatch.isMatch())
1411 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1414 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1417 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1423 bool isGPR32as64()
const {
1424 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1425 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.Reg);
1428 bool isGPR64as32()
const {
1429 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1430 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.Reg);
1433 bool isGPR64x8()
const {
1434 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1435 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1439 bool isWSeqPair()
const {
1440 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1441 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1445 bool isXSeqPair()
const {
1446 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1447 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1451 bool isSyspXzrPair()
const {
1452 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.Reg == AArch64::XZR;
1455 template<
int64_t Angle,
int64_t Remainder>
1456 DiagnosticPredicate isComplexRotation()
const {
1463 uint64_t
Value =
CE->getValue();
1465 if (
Value % Angle == Remainder &&
Value <= 270)
1470 template <
unsigned RegClassID>
bool isGPR64()
const {
1471 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1472 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1475 template <
unsigned RegClassID,
int ExtW
idth>
1476 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1477 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1480 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1481 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1488 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1489 bool isImplicitlyTypedVectorList()
const {
1490 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1491 VectorList.NumElements == 0 &&
1492 VectorList.RegisterKind == VectorKind &&
1493 (!IsConsecutive || (VectorList.Stride == 1));
1496 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1497 unsigned ElementWidth,
unsigned Stride = 1>
1498 bool isTypedVectorList()
const {
1499 if (Kind != k_VectorList)
1501 if (VectorList.Count != NumRegs)
1503 if (VectorList.RegisterKind != VectorKind)
1505 if (VectorList.ElementWidth != ElementWidth)
1507 if (VectorList.Stride != Stride)
1509 return VectorList.NumElements == NumElements;
1512 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1513 unsigned ElementWidth,
unsigned RegClass>
1514 DiagnosticPredicate isTypedVectorListMultiple()
const {
1516 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1519 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.Reg))
1524 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1525 unsigned ElementWidth>
1526 DiagnosticPredicate isTypedVectorListStrided()
const {
1527 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1528 ElementWidth, Stride>();
1531 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1532 ((VectorList.Reg >= AArch64::Z16) &&
1533 (VectorList.Reg < (AArch64::Z16 + Stride))))
1538 template <
int Min,
int Max>
1539 DiagnosticPredicate isVectorIndex()
const {
1540 if (Kind != k_VectorIndex)
1542 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1547 bool isToken()
const override {
return Kind == k_Token; }
1549 bool isTokenEqual(StringRef Str)
const {
1550 return Kind == k_Token &&
getToken() == Str;
1552 bool isSysCR()
const {
return Kind == k_SysCR; }
1553 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1554 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1555 bool isPHint()
const {
return Kind == k_PHint; }
1556 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1557 bool isCMHPriorityHint()
const {
return Kind == k_CMHPriorityHint; }
1558 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1559 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1560 bool isShifter()
const {
1561 if (!isShiftExtend())
1570 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1571 if (Kind != k_FPImm)
1574 if (getFPImmIsExact()) {
1576 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1580 APFloat RealVal(APFloat::IEEEdouble());
1582 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1583 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1586 if (
getFPImm().bitwiseIsEqual(RealVal))
1593 template <
unsigned ImmA,
unsigned ImmB>
1594 DiagnosticPredicate isExactFPImm()
const {
1596 if ((Res = isExactFPImm<ImmA>()))
1598 if ((Res = isExactFPImm<ImmB>()))
1603 bool isExtend()
const {
1604 if (!isShiftExtend())
1613 getShiftExtendAmount() <= 4;
1616 bool isExtend64()
const {
1626 bool isExtendLSL64()
const {
1632 getShiftExtendAmount() <= 4;
1635 bool isLSLImm3Shift()
const {
1636 if (!isShiftExtend())
1642 template<
int W
idth>
bool isMemXExtend()
const {
1647 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1648 getShiftExtendAmount() == 0);
1651 template<
int W
idth>
bool isMemWExtend()
const {
1656 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1657 getShiftExtendAmount() == 0);
1660 template <
unsigned w
idth>
1661 bool isArithmeticShifter()
const {
1671 template <
unsigned w
idth>
1672 bool isLogicalShifter()
const {
1680 getShiftExtendAmount() < width;
1683 bool isMovImm32Shifter()
const {
1691 uint64_t Val = getShiftExtendAmount();
1692 return (Val == 0 || Val == 16);
1695 bool isMovImm64Shifter()
const {
1703 uint64_t Val = getShiftExtendAmount();
1704 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1707 bool isLogicalVecShifter()
const {
1712 unsigned Shift = getShiftExtendAmount();
1714 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1717 bool isLogicalVecHalfWordShifter()
const {
1718 if (!isLogicalVecShifter())
1722 unsigned Shift = getShiftExtendAmount();
1724 (Shift == 0 || Shift == 8);
1727 bool isMoveVecShifter()
const {
1728 if (!isShiftExtend())
1732 unsigned Shift = getShiftExtendAmount();
1734 (Shift == 8 || Shift == 16);
1743 bool isSImm9OffsetFB()
const {
1744 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1747 bool isAdrpLabel()
const {
1754 int64_t Val =
CE->getValue();
1755 int64_t Min = - (4096 * (1LL << (21 - 1)));
1756 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1757 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1763 bool isAdrLabel()
const {
1770 int64_t Val =
CE->getValue();
1771 int64_t Min = - (1LL << (21 - 1));
1772 int64_t
Max = ((1LL << (21 - 1)) - 1);
1773 return Val >= Min && Val <=
Max;
1779 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1780 DiagnosticPredicate isMatrixRegOperand()
const {
1783 if (getMatrixKind() != Kind ||
1784 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1785 EltSize != getMatrixElementWidth())
1790 bool isPAuthPCRelLabel16Operand()
const {
1802 return (Val <= 0) && (Val > -(1 << 18));
1805 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1815 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1816 assert(
N == 1 &&
"Invalid number of operands!");
1820 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1821 assert(
N == 1 &&
"Invalid number of operands!");
1825 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1826 assert(
N == 1 &&
"Invalid number of operands!");
1828 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1830 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1837 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1838 assert(
N == 1 &&
"Invalid number of operands!");
1840 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1842 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1849 template <
int W
idth>
1850 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1853 case 8:
Base = AArch64::B0;
break;
1854 case 16:
Base = AArch64::H0;
break;
1855 case 32:
Base = AArch64::S0;
break;
1856 case 64:
Base = AArch64::D0;
break;
1857 case 128:
Base = AArch64::Q0;
break;
1864 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1865 assert(
N == 1 &&
"Invalid number of operands!");
1868 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1869 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1873 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1874 assert(
N == 1 &&
"Invalid number of operands!");
1879 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1880 assert(
N == 1 &&
"Invalid number of operands!");
1882 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1886 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1887 assert(
N == 1 &&
"Invalid number of operands!");
1889 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1893 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1894 assert(
N == 1 &&
"Invalid number of operands!");
1898 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1899 assert(
N == 1 &&
"Invalid number of operands!");
1903 enum VecListIndexType {
1904 VecListIdx_DReg = 0,
1905 VecListIdx_QReg = 1,
1906 VecListIdx_ZReg = 2,
1907 VecListIdx_PReg = 3,
1910 template <VecListIndexType RegTy,
unsigned NumRegs,
1911 bool IsConsecutive =
false>
1912 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1913 assert(
N == 1 &&
"Invalid number of operands!");
1914 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1915 "Expected consecutive registers");
1916 static const unsigned FirstRegs[][5] = {
1918 AArch64::D0, AArch64::D0_D1,
1919 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1921 AArch64::Q0, AArch64::Q0_Q1,
1922 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1924 AArch64::Z0, AArch64::Z0_Z1,
1925 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1927 AArch64::P0, AArch64::P0_P1 }
1930 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1931 " NumRegs must be <= 4 for ZRegs");
1933 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1934 " NumRegs must be <= 2 for PRegs");
1936 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1938 FirstRegs[(
unsigned)RegTy][0]));
1941 template <
unsigned NumRegs>
1942 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1943 assert(
N == 1 &&
"Invalid number of operands!");
1944 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1948 if (getVectorListStart() < AArch64::Z16) {
1949 assert((getVectorListStart() < AArch64::Z8) &&
1950 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1952 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1954 assert((getVectorListStart() < AArch64::Z24) &&
1955 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1957 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1961 if (getVectorListStart() < AArch64::Z16) {
1962 assert((getVectorListStart() < AArch64::Z4) &&
1963 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1965 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1967 assert((getVectorListStart() < AArch64::Z20) &&
1968 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1970 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1978 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1979 assert(
N == 1 &&
"Invalid number of operands!");
1980 unsigned RegMask = getMatrixTileListRegMask();
1981 assert(RegMask <= 0xFF &&
"Invalid mask!");
1985 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1986 assert(
N == 1 &&
"Invalid number of operands!");
1990 template <
unsigned ImmIs0,
unsigned ImmIs1>
1991 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1992 assert(
N == 1 &&
"Invalid number of operands!");
1993 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1997 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1998 assert(
N == 1 &&
"Invalid number of operands!");
2005 template <
int Shift>
2006 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2007 assert(
N == 2 &&
"Invalid number of operands!");
2008 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2011 }
else if (isShiftedImm()) {
2012 addExpr(Inst, getShiftedImmVal());
2020 template <
int Shift>
2021 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
2022 assert(
N == 2 &&
"Invalid number of operands!");
2023 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
2030 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2031 assert(
N == 1 &&
"Invalid number of operands!");
2035 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
2036 assert(
N == 1 &&
"Invalid number of operands!");
2044 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2045 addImmOperands(Inst,
N);
2049 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
2050 assert(
N == 1 &&
"Invalid number of operands!");
2060 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2061 assert(
N == 1 &&
"Invalid number of operands!");
2066 template <
int Scale>
2067 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2068 assert(
N == 1 &&
"Invalid number of operands!");
2073 template <
int Scale>
2074 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2075 assert(
N == 1 &&
"Invalid number of operands!");
2079 template <
typename T>
2080 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2081 assert(
N == 1 &&
"Invalid number of operands!");
2083 std::make_unsigned_t<T> Val = MCE->
getValue();
2088 template <
typename T>
2089 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2090 assert(
N == 1 &&
"Invalid number of operands!");
2092 std::make_unsigned_t<T> Val = ~MCE->getValue();
2097 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2098 assert(
N == 1 &&
"Invalid number of operands!");
2104 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2108 assert(
N == 1 &&
"Invalid number of operands!");
2114 assert(MCE &&
"Invalid constant immediate operand!");
2118 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2122 assert(
N == 1 &&
"Invalid number of operands!");
2131 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2135 assert(
N == 1 &&
"Invalid number of operands!");
2141 assert(MCE &&
"Invalid constant immediate operand!");
2145 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2149 assert(
N == 1 &&
"Invalid number of operands!");
2155 assert(MCE &&
"Invalid constant immediate operand!");
2159 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2169 assert(MCE &&
"Invalid constant immediate operand!");
2173 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2174 assert(
N == 1 &&
"Invalid number of operands!");
2179 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2184 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2185 assert(
N == 1 &&
"Invalid number of operands!");
2189 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2190 assert(
N == 1 &&
"Invalid number of operands!");
2195 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2196 assert(
N == 1 &&
"Invalid number of operands!");
2201 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2202 assert(
N == 1 &&
"Invalid number of operands!");
2207 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2208 assert(
N == 1 &&
"Invalid number of operands!");
2213 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2214 assert(
N == 1 &&
"Invalid number of operands!");
2219 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2220 assert(
N == 1 &&
"Invalid number of operands!");
2224 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2225 assert(
N == 1 &&
"Invalid number of operands!");
2229 void addPSBHintOperands(MCInst &Inst,
unsigned N)
const {
2230 assert(
N == 1 &&
"Invalid number of operands!");
2234 void addPHintOperands(MCInst &Inst,
unsigned N)
const {
2235 assert(
N == 1 &&
"Invalid number of operands!");
2239 void addBTIHintOperands(MCInst &Inst,
unsigned N)
const {
2240 assert(
N == 1 &&
"Invalid number of operands!");
2244 void addCMHPriorityHintOperands(MCInst &Inst,
unsigned N)
const {
2245 assert(
N == 1 &&
"Invalid number of operands!");
2249 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2250 assert(
N == 1 &&
"Invalid number of operands!");
2254 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2255 assert(
N == 1 &&
"Invalid number of operands!");
2261 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2262 assert(
N == 1 &&
"Invalid number of operands!");
2263 unsigned Imm = getShiftExtendAmount();
2267 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2268 assert(
N == 1 &&
"Invalid number of operands!");
2273 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2276 if (
Reg != AArch64::XZR)
2282 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2283 assert(
N == 1 &&
"Invalid number of operands!");
2290 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2291 assert(
N == 1 &&
"Invalid number of operands!");
2298 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2299 assert(
N == 2 &&
"Invalid number of operands!");
2310 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2311 assert(
N == 2 &&
"Invalid number of operands!");
2319 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2320 assert(
N == 1 &&
"Invalid number of operands!");
2324 uint64_t
Value =
CE->getValue();
2332 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2333 assert(
N == 1 &&
"Invalid number of operands!");
2336 uint64_t
Value =
CE->getValue();
2340 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2341 assert(
N == 1 &&
"Invalid number of operands!");
2346 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2347 assert(
N == 1 &&
"Invalid number of operands!");
2352 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2354 static std::unique_ptr<AArch64Operand>
2355 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2356 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2357 Op->Tok.Data = Str.data();
2358 Op->Tok.Length = Str.size();
2359 Op->Tok.IsSuffix = IsSuffix;
2365 static std::unique_ptr<AArch64Operand>
2366 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2367 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2369 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2370 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2372 Op->Reg.Kind = Kind;
2373 Op->Reg.ElementWidth = 0;
2374 Op->Reg.EqualityTy = EqTy;
2375 Op->Reg.ShiftExtend.Type = ExtTy;
2376 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2377 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2383 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2384 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2386 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2387 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2388 Kind == RegKind::SVEPredicateVector ||
2389 Kind == RegKind::SVEPredicateAsCounter) &&
2390 "Invalid vector kind");
2391 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2393 Op->Reg.ElementWidth = ElementWidth;
2397 static std::unique_ptr<AArch64Operand>
2398 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2399 unsigned NumElements,
unsigned ElementWidth,
2400 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2401 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2402 Op->VectorList.Reg =
Reg;
2404 Op->VectorList.Stride = Stride;
2405 Op->VectorList.NumElements = NumElements;
2406 Op->VectorList.ElementWidth = ElementWidth;
2407 Op->VectorList.RegisterKind = RegisterKind;
2413 static std::unique_ptr<AArch64Operand>
2414 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2415 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2416 Op->VectorIndex.Val = Idx;
2422 static std::unique_ptr<AArch64Operand>
2423 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2424 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2425 Op->MatrixTileList.RegMask = RegMask;
2431 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2432 const unsigned ElementWidth) {
2433 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2435 {{0, AArch64::ZAB0},
2436 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2437 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2438 {{8, AArch64::ZAB0},
2439 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2440 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2441 {{16, AArch64::ZAH0},
2442 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2443 {{16, AArch64::ZAH1},
2444 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2445 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2446 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2447 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2448 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2451 if (ElementWidth == 64)
2454 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2455 assert(!Regs.empty() &&
"Invalid tile or element width!");
2460 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2461 SMLoc
E, MCContext &Ctx) {
2462 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2469 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2470 unsigned ShiftAmount,
2473 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2474 Op->ShiftedImm .Val = Val;
2475 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2481 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2482 unsigned Last, SMLoc S,
2485 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2487 Op->ImmRange.Last =
Last;
2492 static std::unique_ptr<AArch64Operand>
2494 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2495 Op->CondCode.Code =
Code;
2501 static std::unique_ptr<AArch64Operand>
2502 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2503 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2505 Op->FPImm.IsExact = IsExact;
2511 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2515 bool HasnXSModifier) {
2516 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2517 Op->Barrier.Val = Val;
2518 Op->Barrier.Data = Str.data();
2519 Op->Barrier.Length = Str.size();
2520 Op->Barrier.HasnXSModifier = HasnXSModifier;
2526 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2529 uint32_t PStateField,
2531 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2532 Op->SysReg.Data = Str.data();
2533 Op->SysReg.Length = Str.size();
2534 Op->SysReg.MRSReg = MRSReg;
2535 Op->SysReg.MSRReg = MSRReg;
2536 Op->SysReg.PStateField = PStateField;
2542 static std::unique_ptr<AArch64Operand>
2543 CreatePHintInst(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2544 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2545 Op->PHint.Val = Val;
2546 Op->PHint.Data = Str.data();
2547 Op->PHint.Length = Str.size();
2553 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2554 SMLoc
E, MCContext &Ctx) {
2555 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2556 Op->SysCRImm.Val = Val;
2562 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2566 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2567 Op->Prefetch.Val = Val;
2568 Op->Barrier.Data = Str.data();
2569 Op->Barrier.Length = Str.size();
2575 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2579 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2580 Op->PSBHint.Val = Val;
2581 Op->PSBHint.Data = Str.data();
2582 Op->PSBHint.Length = Str.size();
2588 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2592 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2593 Op->BTIHint.Val = Val | 32;
2594 Op->BTIHint.Data = Str.data();
2595 Op->BTIHint.Length = Str.size();
2601 static std::unique_ptr<AArch64Operand>
2602 CreateCMHPriorityHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2603 auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
2604 Op->CMHPriorityHint.Val = Val;
2605 Op->CMHPriorityHint.Data = Str.data();
2606 Op->CMHPriorityHint.Length = Str.size();
2612 static std::unique_ptr<AArch64Operand>
2613 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2614 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2615 Op->TIndexHint.Val = Val;
2616 Op->TIndexHint.Data = Str.data();
2617 Op->TIndexHint.Length = Str.size();
2623 static std::unique_ptr<AArch64Operand>
2624 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2625 SMLoc S, SMLoc
E, MCContext &Ctx) {
2626 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2627 Op->MatrixReg.Reg =
Reg;
2628 Op->MatrixReg.ElementWidth = ElementWidth;
2629 Op->MatrixReg.Kind = Kind;
2635 static std::unique_ptr<AArch64Operand>
2636 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2637 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2638 Op->SVCR.PStateField = PStateField;
2639 Op->SVCR.Data = Str.data();
2640 Op->SVCR.Length = Str.size();
2646 static std::unique_ptr<AArch64Operand>
2648 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2649 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2650 Op->ShiftExtend.Type = ShOp;
2651 Op->ShiftExtend.Amount = Val;
2652 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2664 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2665 if (!getFPImmIsExact())
2670 StringRef
Name = getBarrierName();
2672 OS <<
"<barrier " <<
Name <<
">";
2674 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2680 case k_ShiftedImm: {
2681 unsigned Shift = getShiftedImmShift();
2682 OS <<
"<shiftedimm ";
2689 OS << getFirstImmVal();
2690 OS <<
":" << getLastImmVal() <<
">";
2696 case k_VectorList: {
2697 OS <<
"<vectorlist ";
2698 MCRegister
Reg = getVectorListStart();
2699 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2700 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2705 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2708 OS <<
"<sysreg: " << getSysReg() <<
'>';
2714 OS <<
"c" << getSysCR();
2717 StringRef
Name = getPrefetchName();
2719 OS <<
"<prfop " <<
Name <<
">";
2721 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2725 OS << getPSBHintName();
2728 OS << getPHintName();
2731 OS << getBTIHintName();
2733 case k_CMHPriorityHint:
2734 OS << getCMHPriorityHintName();
2737 OS << getTIndexHintName();
2739 case k_MatrixRegister:
2740 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2742 case k_MatrixTileList: {
2743 OS <<
"<matrixlist ";
2744 unsigned RegMask = getMatrixTileListRegMask();
2745 unsigned MaxBits = 8;
2746 for (
unsigned I = MaxBits;
I > 0; --
I)
2747 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2756 OS <<
"<register " <<
getReg().
id() <<
">";
2757 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2762 << getShiftExtendAmount();
2763 if (!hasShiftExtendAmount())
2779 .
Case(
"v0", AArch64::Q0)
2780 .
Case(
"v1", AArch64::Q1)
2781 .
Case(
"v2", AArch64::Q2)
2782 .
Case(
"v3", AArch64::Q3)
2783 .
Case(
"v4", AArch64::Q4)
2784 .
Case(
"v5", AArch64::Q5)
2785 .
Case(
"v6", AArch64::Q6)
2786 .
Case(
"v7", AArch64::Q7)
2787 .
Case(
"v8", AArch64::Q8)
2788 .
Case(
"v9", AArch64::Q9)
2789 .
Case(
"v10", AArch64::Q10)
2790 .
Case(
"v11", AArch64::Q11)
2791 .
Case(
"v12", AArch64::Q12)
2792 .
Case(
"v13", AArch64::Q13)
2793 .
Case(
"v14", AArch64::Q14)
2794 .
Case(
"v15", AArch64::Q15)
2795 .
Case(
"v16", AArch64::Q16)
2796 .
Case(
"v17", AArch64::Q17)
2797 .
Case(
"v18", AArch64::Q18)
2798 .
Case(
"v19", AArch64::Q19)
2799 .
Case(
"v20", AArch64::Q20)
2800 .
Case(
"v21", AArch64::Q21)
2801 .
Case(
"v22", AArch64::Q22)
2802 .
Case(
"v23", AArch64::Q23)
2803 .
Case(
"v24", AArch64::Q24)
2804 .
Case(
"v25", AArch64::Q25)
2805 .
Case(
"v26", AArch64::Q26)
2806 .
Case(
"v27", AArch64::Q27)
2807 .
Case(
"v28", AArch64::Q28)
2808 .
Case(
"v29", AArch64::Q29)
2809 .
Case(
"v30", AArch64::Q30)
2810 .
Case(
"v31", AArch64::Q31)
2819 RegKind VectorKind) {
2820 std::pair<int, int> Res = {-1, -1};
2822 switch (VectorKind) {
2823 case RegKind::NeonVector:
2826 .Case(
".1d", {1, 64})
2827 .Case(
".1q", {1, 128})
2829 .Case(
".2h", {2, 16})
2830 .Case(
".2b", {2, 8})
2831 .Case(
".2s", {2, 32})
2832 .Case(
".2d", {2, 64})
2835 .Case(
".4b", {4, 8})
2836 .Case(
".4h", {4, 16})
2837 .Case(
".4s", {4, 32})
2838 .Case(
".8b", {8, 8})
2839 .Case(
".8h", {8, 16})
2840 .Case(
".16b", {16, 8})
2845 .Case(
".h", {0, 16})
2846 .Case(
".s", {0, 32})
2847 .Case(
".d", {0, 64})
2850 case RegKind::SVEPredicateAsCounter:
2851 case RegKind::SVEPredicateVector:
2852 case RegKind::SVEDataVector:
2853 case RegKind::Matrix:
2857 .Case(
".h", {0, 16})
2858 .Case(
".s", {0, 32})
2859 .Case(
".d", {0, 64})
2860 .Case(
".q", {0, 128})
2867 if (Res == std::make_pair(-1, -1))
2868 return std::nullopt;
2870 return std::optional<std::pair<int, int>>(Res);
2879 .
Case(
"z0", AArch64::Z0)
2880 .
Case(
"z1", AArch64::Z1)
2881 .
Case(
"z2", AArch64::Z2)
2882 .
Case(
"z3", AArch64::Z3)
2883 .
Case(
"z4", AArch64::Z4)
2884 .
Case(
"z5", AArch64::Z5)
2885 .
Case(
"z6", AArch64::Z6)
2886 .
Case(
"z7", AArch64::Z7)
2887 .
Case(
"z8", AArch64::Z8)
2888 .
Case(
"z9", AArch64::Z9)
2889 .
Case(
"z10", AArch64::Z10)
2890 .
Case(
"z11", AArch64::Z11)
2891 .
Case(
"z12", AArch64::Z12)
2892 .
Case(
"z13", AArch64::Z13)
2893 .
Case(
"z14", AArch64::Z14)
2894 .
Case(
"z15", AArch64::Z15)
2895 .
Case(
"z16", AArch64::Z16)
2896 .
Case(
"z17", AArch64::Z17)
2897 .
Case(
"z18", AArch64::Z18)
2898 .
Case(
"z19", AArch64::Z19)
2899 .
Case(
"z20", AArch64::Z20)
2900 .
Case(
"z21", AArch64::Z21)
2901 .
Case(
"z22", AArch64::Z22)
2902 .
Case(
"z23", AArch64::Z23)
2903 .
Case(
"z24", AArch64::Z24)
2904 .
Case(
"z25", AArch64::Z25)
2905 .
Case(
"z26", AArch64::Z26)
2906 .
Case(
"z27", AArch64::Z27)
2907 .
Case(
"z28", AArch64::Z28)
2908 .
Case(
"z29", AArch64::Z29)
2909 .
Case(
"z30", AArch64::Z30)
2910 .
Case(
"z31", AArch64::Z31)
2916 .
Case(
"p0", AArch64::P0)
2917 .
Case(
"p1", AArch64::P1)
2918 .
Case(
"p2", AArch64::P2)
2919 .
Case(
"p3", AArch64::P3)
2920 .
Case(
"p4", AArch64::P4)
2921 .
Case(
"p5", AArch64::P5)
2922 .
Case(
"p6", AArch64::P6)
2923 .
Case(
"p7", AArch64::P7)
2924 .
Case(
"p8", AArch64::P8)
2925 .
Case(
"p9", AArch64::P9)
2926 .
Case(
"p10", AArch64::P10)
2927 .
Case(
"p11", AArch64::P11)
2928 .
Case(
"p12", AArch64::P12)
2929 .
Case(
"p13", AArch64::P13)
2930 .
Case(
"p14", AArch64::P14)
2931 .
Case(
"p15", AArch64::P15)
2937 .
Case(
"pn0", AArch64::PN0)
2938 .
Case(
"pn1", AArch64::PN1)
2939 .
Case(
"pn2", AArch64::PN2)
2940 .
Case(
"pn3", AArch64::PN3)
2941 .
Case(
"pn4", AArch64::PN4)
2942 .
Case(
"pn5", AArch64::PN5)
2943 .
Case(
"pn6", AArch64::PN6)
2944 .
Case(
"pn7", AArch64::PN7)
2945 .
Case(
"pn8", AArch64::PN8)
2946 .
Case(
"pn9", AArch64::PN9)
2947 .
Case(
"pn10", AArch64::PN10)
2948 .
Case(
"pn11", AArch64::PN11)
2949 .
Case(
"pn12", AArch64::PN12)
2950 .
Case(
"pn13", AArch64::PN13)
2951 .
Case(
"pn14", AArch64::PN14)
2952 .
Case(
"pn15", AArch64::PN15)
2958 .
Case(
"za0.d", AArch64::ZAD0)
2959 .
Case(
"za1.d", AArch64::ZAD1)
2960 .
Case(
"za2.d", AArch64::ZAD2)
2961 .
Case(
"za3.d", AArch64::ZAD3)
2962 .
Case(
"za4.d", AArch64::ZAD4)
2963 .
Case(
"za5.d", AArch64::ZAD5)
2964 .
Case(
"za6.d", AArch64::ZAD6)
2965 .
Case(
"za7.d", AArch64::ZAD7)
2966 .
Case(
"za0.s", AArch64::ZAS0)
2967 .
Case(
"za1.s", AArch64::ZAS1)
2968 .
Case(
"za2.s", AArch64::ZAS2)
2969 .
Case(
"za3.s", AArch64::ZAS3)
2970 .
Case(
"za0.h", AArch64::ZAH0)
2971 .
Case(
"za1.h", AArch64::ZAH1)
2972 .
Case(
"za0.b", AArch64::ZAB0)
2978 .
Case(
"za", AArch64::ZA)
2979 .
Case(
"za0.q", AArch64::ZAQ0)
2980 .
Case(
"za1.q", AArch64::ZAQ1)
2981 .
Case(
"za2.q", AArch64::ZAQ2)
2982 .
Case(
"za3.q", AArch64::ZAQ3)
2983 .
Case(
"za4.q", AArch64::ZAQ4)
2984 .
Case(
"za5.q", AArch64::ZAQ5)
2985 .
Case(
"za6.q", AArch64::ZAQ6)
2986 .
Case(
"za7.q", AArch64::ZAQ7)
2987 .
Case(
"za8.q", AArch64::ZAQ8)
2988 .
Case(
"za9.q", AArch64::ZAQ9)
2989 .
Case(
"za10.q", AArch64::ZAQ10)
2990 .
Case(
"za11.q", AArch64::ZAQ11)
2991 .
Case(
"za12.q", AArch64::ZAQ12)
2992 .
Case(
"za13.q", AArch64::ZAQ13)
2993 .
Case(
"za14.q", AArch64::ZAQ14)
2994 .
Case(
"za15.q", AArch64::ZAQ15)
2995 .
Case(
"za0.d", AArch64::ZAD0)
2996 .
Case(
"za1.d", AArch64::ZAD1)
2997 .
Case(
"za2.d", AArch64::ZAD2)
2998 .
Case(
"za3.d", AArch64::ZAD3)
2999 .
Case(
"za4.d", AArch64::ZAD4)
3000 .
Case(
"za5.d", AArch64::ZAD5)
3001 .
Case(
"za6.d", AArch64::ZAD6)
3002 .
Case(
"za7.d", AArch64::ZAD7)
3003 .
Case(
"za0.s", AArch64::ZAS0)
3004 .
Case(
"za1.s", AArch64::ZAS1)
3005 .
Case(
"za2.s", AArch64::ZAS2)
3006 .
Case(
"za3.s", AArch64::ZAS3)
3007 .
Case(
"za0.h", AArch64::ZAH0)
3008 .
Case(
"za1.h", AArch64::ZAH1)
3009 .
Case(
"za0.b", AArch64::ZAB0)
3010 .
Case(
"za0h.q", AArch64::ZAQ0)
3011 .
Case(
"za1h.q", AArch64::ZAQ1)
3012 .
Case(
"za2h.q", AArch64::ZAQ2)
3013 .
Case(
"za3h.q", AArch64::ZAQ3)
3014 .
Case(
"za4h.q", AArch64::ZAQ4)
3015 .
Case(
"za5h.q", AArch64::ZAQ5)
3016 .
Case(
"za6h.q", AArch64::ZAQ6)
3017 .
Case(
"za7h.q", AArch64::ZAQ7)
3018 .
Case(
"za8h.q", AArch64::ZAQ8)
3019 .
Case(
"za9h.q", AArch64::ZAQ9)
3020 .
Case(
"za10h.q", AArch64::ZAQ10)
3021 .
Case(
"za11h.q", AArch64::ZAQ11)
3022 .
Case(
"za12h.q", AArch64::ZAQ12)
3023 .
Case(
"za13h.q", AArch64::ZAQ13)
3024 .
Case(
"za14h.q", AArch64::ZAQ14)
3025 .
Case(
"za15h.q", AArch64::ZAQ15)
3026 .
Case(
"za0h.d", AArch64::ZAD0)
3027 .
Case(
"za1h.d", AArch64::ZAD1)
3028 .
Case(
"za2h.d", AArch64::ZAD2)
3029 .
Case(
"za3h.d", AArch64::ZAD3)
3030 .
Case(
"za4h.d", AArch64::ZAD4)
3031 .
Case(
"za5h.d", AArch64::ZAD5)
3032 .
Case(
"za6h.d", AArch64::ZAD6)
3033 .
Case(
"za7h.d", AArch64::ZAD7)
3034 .
Case(
"za0h.s", AArch64::ZAS0)
3035 .
Case(
"za1h.s", AArch64::ZAS1)
3036 .
Case(
"za2h.s", AArch64::ZAS2)
3037 .
Case(
"za3h.s", AArch64::ZAS3)
3038 .
Case(
"za0h.h", AArch64::ZAH0)
3039 .
Case(
"za1h.h", AArch64::ZAH1)
3040 .
Case(
"za0h.b", AArch64::ZAB0)
3041 .
Case(
"za0v.q", AArch64::ZAQ0)
3042 .
Case(
"za1v.q", AArch64::ZAQ1)
3043 .
Case(
"za2v.q", AArch64::ZAQ2)
3044 .
Case(
"za3v.q", AArch64::ZAQ3)
3045 .
Case(
"za4v.q", AArch64::ZAQ4)
3046 .
Case(
"za5v.q", AArch64::ZAQ5)
3047 .
Case(
"za6v.q", AArch64::ZAQ6)
3048 .
Case(
"za7v.q", AArch64::ZAQ7)
3049 .
Case(
"za8v.q", AArch64::ZAQ8)
3050 .
Case(
"za9v.q", AArch64::ZAQ9)
3051 .
Case(
"za10v.q", AArch64::ZAQ10)
3052 .
Case(
"za11v.q", AArch64::ZAQ11)
3053 .
Case(
"za12v.q", AArch64::ZAQ12)
3054 .
Case(
"za13v.q", AArch64::ZAQ13)
3055 .
Case(
"za14v.q", AArch64::ZAQ14)
3056 .
Case(
"za15v.q", AArch64::ZAQ15)
3057 .
Case(
"za0v.d", AArch64::ZAD0)
3058 .
Case(
"za1v.d", AArch64::ZAD1)
3059 .
Case(
"za2v.d", AArch64::ZAD2)
3060 .
Case(
"za3v.d", AArch64::ZAD3)
3061 .
Case(
"za4v.d", AArch64::ZAD4)
3062 .
Case(
"za5v.d", AArch64::ZAD5)
3063 .
Case(
"za6v.d", AArch64::ZAD6)
3064 .
Case(
"za7v.d", AArch64::ZAD7)
3065 .
Case(
"za0v.s", AArch64::ZAS0)
3066 .
Case(
"za1v.s", AArch64::ZAS1)
3067 .
Case(
"za2v.s", AArch64::ZAS2)
3068 .
Case(
"za3v.s", AArch64::ZAS3)
3069 .
Case(
"za0v.h", AArch64::ZAH0)
3070 .
Case(
"za1v.h", AArch64::ZAH1)
3071 .
Case(
"za0v.b", AArch64::ZAB0)
3075bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3077 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3080ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3082 StartLoc = getLoc();
3083 ParseStatus Res = tryParseScalarRegister(
Reg);
3089MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
3091 MCRegister
Reg = MCRegister();
3093 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
3096 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
3099 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
3102 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
3105 return Kind == RegKind::Matrix ?
Reg : MCRegister();
3107 if (
Name.equals_insensitive(
"zt0"))
3108 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
3112 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
3116 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
3117 .Case(
"fp", AArch64::FP)
3118 .Case(
"lr", AArch64::LR)
3119 .Case(
"x31", AArch64::XZR)
3120 .Case(
"w31", AArch64::WZR)
3122 return Kind == RegKind::Scalar ?
Reg : MCRegister();
3128 if (Entry == RegisterReqs.
end())
3129 return MCRegister();
3132 if (Kind ==
Entry->getValue().first)
3138unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3140 case RegKind::Scalar:
3141 case RegKind::NeonVector:
3142 case RegKind::SVEDataVector:
3144 case RegKind::Matrix:
3145 case RegKind::SVEPredicateVector:
3146 case RegKind::SVEPredicateAsCounter:
3148 case RegKind::LookupTable:
3157ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3158 const AsmToken &Tok = getTok();
3163 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3173ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3177 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3180 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3181 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3185 if (BadNum || CRNum > 15)
3186 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3190 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3195ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3197 const AsmToken &Tok = getTok();
3199 unsigned MaxVal = 63;
3204 const MCExpr *ImmVal;
3205 if (getParser().parseExpression(ImmVal))
3210 return TokError(
"immediate value expected for prefetch operand");
3213 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3216 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3217 Operands.
push_back(AArch64Operand::CreatePrefetch(
3218 prfop, RPRFM ? RPRFM->Name :
"", S,
getContext()));
3223 return TokError(
"prefetch hint expected");
3225 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3227 return TokError(
"prefetch hint expected");
3229 Operands.
push_back(AArch64Operand::CreatePrefetch(
3236template <
bool IsSVEPrefetch>
3237ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3239 const AsmToken &Tok = getTok();
3241 auto LookupByName = [](StringRef
N) {
3242 if (IsSVEPrefetch) {
3243 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3244 return std::optional<unsigned>(Res->Encoding);
3245 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3246 return std::optional<unsigned>(Res->Encoding);
3247 return std::optional<unsigned>();
3250 auto LookupByEncoding = [](
unsigned E) {
3251 if (IsSVEPrefetch) {
3252 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3253 return std::optional<StringRef>(Res->Name);
3254 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3255 return std::optional<StringRef>(Res->Name);
3256 return std::optional<StringRef>();
3258 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3264 const MCExpr *ImmVal;
3265 if (getParser().parseExpression(ImmVal))
3270 return TokError(
"immediate value expected for prefetch operand");
3273 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3276 auto PRFM = LookupByEncoding(MCE->
getValue());
3277 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3283 return TokError(
"prefetch hint expected");
3285 auto PRFM = LookupByName(Tok.
getString());
3287 return TokError(
"prefetch hint expected");
3289 Operands.
push_back(AArch64Operand::CreatePrefetch(
3296ParseStatus AArch64AsmParser::tryParsePSBHint(
OperandVector &Operands) {
3298 const AsmToken &Tok = getTok();
3300 return TokError(
"invalid operand for instruction");
3302 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3304 return TokError(
"invalid operand for instruction");
3306 Operands.
push_back(AArch64Operand::CreatePSBHint(
3312ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3313 SMLoc StartLoc = getLoc();
3319 auto RegTok = getTok();
3320 if (!tryParseScalarRegister(RegNum).isSuccess())
3323 if (RegNum != AArch64::XZR) {
3324 getLexer().UnLex(RegTok);
3331 if (!tryParseScalarRegister(RegNum).isSuccess())
3332 return TokError(
"expected register operand");
3334 if (RegNum != AArch64::XZR)
3335 return TokError(
"xzr must be followed by xzr");
3339 Operands.
push_back(AArch64Operand::CreateReg(
3340 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3346ParseStatus AArch64AsmParser::tryParseBTIHint(
OperandVector &Operands) {
3348 const AsmToken &Tok = getTok();
3350 return TokError(
"invalid operand for instruction");
3352 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3354 return TokError(
"invalid operand for instruction");
3356 Operands.
push_back(AArch64Operand::CreateBTIHint(
3363ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(
OperandVector &Operands) {
3365 const AsmToken &Tok = getTok();
3367 return TokError(
"invalid operand for instruction");
3370 AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.
getString());
3372 return TokError(
"invalid operand for instruction");
3374 Operands.
push_back(AArch64Operand::CreateCMHPriorityHint(
3381ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3383 const AsmToken &Tok = getTok();
3385 return TokError(
"invalid operand for instruction");
3387 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3389 return TokError(
"invalid operand for instruction");
3391 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3399ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3401 const MCExpr *Expr =
nullptr;
3407 if (parseSymbolicImmVal(Expr))
3413 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3422 return Error(S,
"gotpage label reference not allowed an addend");
3434 return Error(S,
"page or gotpage label reference expected");
3449ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3451 const MCExpr *Expr =
nullptr;
3460 if (parseSymbolicImmVal(Expr))
3466 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3478 return Error(S,
"unexpected adr label");
3488template <
bool AddFPZeroAsLiteral>
3489ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3497 const AsmToken &Tok = getTok();
3501 return TokError(
"invalid floating point immediate");
3506 if (Tok.
getIntVal() > 255 || isNegative)
3507 return TokError(
"encoded floating point value out of range");
3511 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3514 APFloat RealVal(APFloat::IEEEdouble());
3516 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3518 return TokError(
"invalid floating point representation");
3521 RealVal.changeSign();
3523 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3527 Operands.
push_back(AArch64Operand::CreateFPImm(
3528 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3539AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3550 return tryParseImmRange(Operands);
3552 const MCExpr *
Imm =
nullptr;
3553 if (parseSymbolicImmVal(Imm))
3557 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3564 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3566 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3568 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3574 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3575 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3583 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3585 int64_t ShiftAmount = getTok().getIntVal();
3587 if (ShiftAmount < 0)
3588 return Error(getLoc(),
"positive shift amount required");
3592 if (ShiftAmount == 0 && Imm !=
nullptr) {
3594 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3598 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3606AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3640 Suggestion =
"nfrst";
3646bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3647 bool invertCondCode) {
3649 const AsmToken &Tok = getTok();
3653 std::string Suggestion;
3656 std::string Msg =
"invalid condition code";
3657 if (!Suggestion.empty())
3658 Msg +=
", did you mean " + Suggestion +
"?";
3659 return TokError(Msg);
3663 if (invertCondCode) {
3665 return TokError(
"condition codes AL and NV are invalid for this instruction");
3670 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3674ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3675 const AsmToken &Tok = getTok();
3679 return TokError(
"invalid operand for instruction");
3681 unsigned PStateImm = -1;
3682 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3685 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3686 PStateImm = SVCR->Encoding;
3694ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3695 const AsmToken &Tok = getTok();
3700 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3702 unsigned ElementWidth = 0;
3703 auto DotPosition =
Name.find(
'.');
3705 const auto &KindRes =
3709 "Expected the register to be followed by element width suffix");
3710 ElementWidth = KindRes->second;
3712 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3713 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3718 if (parseOperand(Operands,
false,
false))
3725 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3729 size_t DotPosition =
Name.find(
'.');
3732 StringRef Head =
Name.take_front(DotPosition);
3733 StringRef
Tail =
Name.drop_front(DotPosition);
3734 StringRef RowOrColumn = Head.
take_back();
3736 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3737 .Case(
"h", MatrixKind::Row)
3738 .Case(
"v", MatrixKind::Col)
3739 .Default(MatrixKind::Tile);
3745 "Expected the register to be followed by element width suffix");
3746 unsigned ElementWidth = KindRes->second;
3750 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3756 if (parseOperand(Operands,
false,
false))
3765AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3766 const AsmToken &Tok = getTok();
3769 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3798 return TokError(
"expected #imm after shift specifier");
3804 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3813 return Error(
E,
"expected integer shift amount");
3815 const MCExpr *ImmVal;
3816 if (getParser().parseExpression(ImmVal))
3821 return Error(
E,
"expected constant '#imm' after shift specifier");
3824 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3833 {
"crc", {AArch64::FeatureCRC}},
3834 {
"sm4", {AArch64::FeatureSM4}},
3835 {
"sha3", {AArch64::FeatureSHA3}},
3836 {
"sha2", {AArch64::FeatureSHA2}},
3837 {
"aes", {AArch64::FeatureAES}},
3838 {
"crypto", {AArch64::FeatureCrypto}},
3839 {
"fp", {AArch64::FeatureFPARMv8}},
3840 {
"simd", {AArch64::FeatureNEON}},
3841 {
"ras", {AArch64::FeatureRAS}},
3842 {
"rasv2", {AArch64::FeatureRASv2}},
3843 {
"lse", {AArch64::FeatureLSE}},
3844 {
"predres", {AArch64::FeaturePredRes}},
3845 {
"predres2", {AArch64::FeatureSPECRES2}},
3846 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3847 {
"mte", {AArch64::FeatureMTE}},
3848 {
"memtag", {AArch64::FeatureMTE}},
3849 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3850 {
"pan", {AArch64::FeaturePAN}},
3851 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3852 {
"ccpp", {AArch64::FeatureCCPP}},
3853 {
"rcpc", {AArch64::FeatureRCPC}},
3854 {
"rng", {AArch64::FeatureRandGen}},
3855 {
"sve", {AArch64::FeatureSVE}},
3856 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3857 {
"sve2", {AArch64::FeatureSVE2}},
3858 {
"sve-aes", {AArch64::FeatureSVEAES}},
3859 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3860 {
"sve-sm4", {AArch64::FeatureSVESM4}},
3861 {
"sve2-sm4", {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3862 {
"sve-sha3", {AArch64::FeatureSVESHA3}},
3863 {
"sve2-sha3", {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3864 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3866 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3867 AArch64::FeatureSVE2}},
3868 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3869 {
"ls64", {AArch64::FeatureLS64}},
3870 {
"xs", {AArch64::FeatureXS}},
3871 {
"pauth", {AArch64::FeaturePAuth}},
3872 {
"flagm", {AArch64::FeatureFlagM}},
3873 {
"rme", {AArch64::FeatureRME}},
3874 {
"sme", {AArch64::FeatureSME}},
3875 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3876 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3877 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3878 {
"sme2", {AArch64::FeatureSME2}},
3879 {
"sme2p1", {AArch64::FeatureSME2p1}},
3880 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3881 {
"hbc", {AArch64::FeatureHBC}},
3882 {
"mops", {AArch64::FeatureMOPS}},
3883 {
"mec", {AArch64::FeatureMEC}},
3884 {
"the", {AArch64::FeatureTHE}},
3885 {
"d128", {AArch64::FeatureD128}},
3886 {
"lse128", {AArch64::FeatureLSE128}},
3887 {
"ite", {AArch64::FeatureITE}},
3888 {
"cssc", {AArch64::FeatureCSSC}},
3889 {
"rcpc3", {AArch64::FeatureRCPC3}},
3890 {
"gcs", {AArch64::FeatureGCS}},
3891 {
"bf16", {AArch64::FeatureBF16}},
3892 {
"compnum", {AArch64::FeatureComplxNum}},
3893 {
"dotprod", {AArch64::FeatureDotProd}},
3894 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3895 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3896 {
"fp16", {AArch64::FeatureFullFP16}},
3897 {
"fp16fml", {AArch64::FeatureFP16FML}},
3898 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3899 {
"lor", {AArch64::FeatureLOR}},
3900 {
"profile", {AArch64::FeatureSPE}},
3904 {
"rdm", {AArch64::FeatureRDM}},
3905 {
"rdma", {AArch64::FeatureRDM}},
3906 {
"sb", {AArch64::FeatureSB}},
3907 {
"ssbs", {AArch64::FeatureSSBS}},
3908 {
"fp8", {AArch64::FeatureFP8}},
3909 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3910 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3911 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3912 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3913 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3914 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3915 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3916 {
"lut", {AArch64::FeatureLUT}},
3917 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3918 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3919 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3920 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3921 {
"cpa", {AArch64::FeatureCPA}},
3922 {
"tlbiw", {AArch64::FeatureTLBIW}},
3923 {
"pops", {AArch64::FeaturePoPS}},
3924 {
"cmpbr", {AArch64::FeatureCMPBR}},
3925 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3926 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3927 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3928 {
"lsfe", {AArch64::FeatureLSFE}},
3929 {
"sme2p2", {AArch64::FeatureSME2p2}},
3930 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3931 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3932 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3933 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3934 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3935 {
"lsui", {AArch64::FeatureLSUI}},
3936 {
"occmo", {AArch64::FeatureOCCMO}},
3937 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3938 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3939 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3940 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3941 {
"cmh", {AArch64::FeatureCMH}},
3942 {
"lscp", {AArch64::FeatureLSCP}},
3943 {
"tlbid", {AArch64::FeatureTLBID}},
3944 {
"mpamv2", {AArch64::FeatureMPAMv2}},
3945 {
"mtetc", {AArch64::FeatureMTETC}},
3946 {
"gcie", {AArch64::FeatureGCIE}},
3947 {
"sme2p3", {AArch64::FeatureSME2p3}},
3948 {
"sve2p3", {AArch64::FeatureSVE2p3}},
3949 {
"sve-b16mm", {AArch64::FeatureSVE_B16MM}},
3950 {
"f16mm", {AArch64::FeatureF16MM}},
3951 {
"f16f32dot", {AArch64::FeatureF16F32DOT}},
3952 {
"f16f32mm", {AArch64::FeatureF16F32MM}},
3953 {
"mops-go", {AArch64::FeatureMOPS_GO}},
3954 {
"poe2", {AArch64::FeatureS1POE2}},
3955 {
"tev", {AArch64::FeatureTEV}},
3956 {
"btie", {AArch64::FeatureBTIE}},
3957 {
"dit", {AArch64::FeatureDIT}},
3958 {
"brbe", {AArch64::FeatureBRBE}},
3959 {
"bti", {AArch64::FeatureBranchTargetId}},
3960 {
"fcma", {AArch64::FeatureComplxNum}},
3961 {
"jscvt", {AArch64::FeatureJS}},
3962 {
"pauth-lr", {AArch64::FeaturePAuthLR}},
3963 {
"ssve-fexpa", {AArch64::FeatureSSVE_FEXPA}},
3964 {
"wfxt", {AArch64::FeatureWFxT}},
3968 if (FBS[AArch64::HasV8_0aOps])
3970 if (FBS[AArch64::HasV8_1aOps])
3972 else if (FBS[AArch64::HasV8_2aOps])
3974 else if (FBS[AArch64::HasV8_3aOps])
3976 else if (FBS[AArch64::HasV8_4aOps])
3978 else if (FBS[AArch64::HasV8_5aOps])
3980 else if (FBS[AArch64::HasV8_6aOps])
3982 else if (FBS[AArch64::HasV8_7aOps])
3984 else if (FBS[AArch64::HasV8_8aOps])
3986 else if (FBS[AArch64::HasV8_9aOps])
3988 else if (FBS[AArch64::HasV9_0aOps])
3990 else if (FBS[AArch64::HasV9_1aOps])
3992 else if (FBS[AArch64::HasV9_2aOps])
3994 else if (FBS[AArch64::HasV9_3aOps])
3996 else if (FBS[AArch64::HasV9_4aOps])
3998 else if (FBS[AArch64::HasV9_5aOps])
4000 else if (FBS[AArch64::HasV9_6aOps])
4002 else if (FBS[AArch64::HasV9_7aOps])
4004 else if (FBS[AArch64::HasV8_0rOps])
4013 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
4017void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
4019 const uint16_t Op2 = Encoding & 7;
4020 const uint16_t Cm = (Encoding & 0x78) >> 3;
4021 const uint16_t Cn = (Encoding & 0x780) >> 7;
4022 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
4027 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4029 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
4031 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
4034 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
4040bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
4042 if (
Name.contains(
'.'))
4043 return TokError(
"invalid operand");
4048 const AsmToken &Tok = getTok();
4051 bool ExpectRegister =
true;
4052 bool OptionalRegister =
false;
4053 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
4054 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4056 if (Mnemonic ==
"ic") {
4057 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
4059 return TokError(
"invalid operand for IC instruction");
4060 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
4061 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
4063 return TokError(Str);
4066 createSysAlias(IC->
Encoding, Operands, S);
4067 }
else if (Mnemonic ==
"dc") {
4068 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
4070 return TokError(
"invalid operand for DC instruction");
4071 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
4072 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
4074 return TokError(Str);
4076 createSysAlias(DC->
Encoding, Operands, S);
4077 }
else if (Mnemonic ==
"at") {
4078 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
4080 return TokError(
"invalid operand for AT instruction");
4081 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
4082 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
4084 return TokError(Str);
4086 createSysAlias(AT->
Encoding, Operands, S);
4087 }
else if (Mnemonic ==
"tlbi") {
4088 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
4090 return TokError(
"invalid operand for TLBI instruction");
4091 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
4092 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
4094 return TokError(Str);
4097 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
4098 if (hasAll || hasTLBID) {
4101 createSysAlias(TLBI->
Encoding, Operands, S);
4102 }
else if (Mnemonic ==
"mlbi") {
4103 const AArch64MLBI::MLBI *MLBI = AArch64MLBI::lookupMLBIByName(
Op);
4105 return TokError(
"invalid operand for MLBI instruction");
4106 else if (!MLBI->
haveFeatures(getSTI().getFeatureBits())) {
4107 std::string Str(
"MLBI " + std::string(MLBI->
Name) +
" requires: ");
4109 return TokError(Str);
4112 createSysAlias(MLBI->
Encoding, Operands, S);
4113 }
else if (Mnemonic ==
"gic") {
4114 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
4116 return TokError(
"invalid operand for GIC instruction");
4117 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
4118 std::string Str(
"GIC " + std::string(GIC->
Name) +
" requires: ");
4120 return TokError(Str);
4123 createSysAlias(GIC->
Encoding, Operands, S);
4124 }
else if (Mnemonic ==
"gsb") {
4125 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
4127 return TokError(
"invalid operand for GSB instruction");
4128 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
4129 std::string Str(
"GSB " + std::string(GSB->
Name) +
" requires: ");
4131 return TokError(Str);
4133 ExpectRegister =
false;
4134 createSysAlias(GSB->
Encoding, Operands, S);
4135 }
else if (Mnemonic ==
"plbi") {
4136 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
4138 return TokError(
"invalid operand for PLBI instruction");
4139 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
4140 std::string Str(
"PLBI " + std::string(PLBI->
Name) +
" requires: ");
4142 return TokError(Str);
4145 if (hasAll || hasTLBID) {
4148 createSysAlias(PLBI->
Encoding, Operands, S);
4149 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
4150 Mnemonic ==
"cosp") {
4152 if (
Op.lower() !=
"rctx")
4153 return TokError(
"invalid operand for prediction restriction instruction");
4155 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
4156 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
4158 if (Mnemonic ==
"cosp" && !hasSpecres2)
4159 return TokError(
"COSP requires: predres2");
4161 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
4163 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
4164 : Mnemonic ==
"dvp" ? 0b101
4165 : Mnemonic ==
"cosp" ? 0b110
4166 : Mnemonic ==
"cpp" ? 0b111
4169 "Invalid mnemonic for prediction restriction instruction");
4170 const auto SYS_3_7_3 = 0b01101110011;
4171 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
4173 createSysAlias(Encoding, Operands, S);
4178 bool HasRegister =
false;
4183 return TokError(
"expected register operand");
4187 if (!OptionalRegister) {
4188 if (ExpectRegister && !HasRegister)
4189 return TokError(
"specified " + Mnemonic +
" op requires a register");
4190 else if (!ExpectRegister && HasRegister)
4191 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4203bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4208 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4211 SMLoc startLoc = getLoc();
4212 const AsmToken ®Tok = getTok();
4214 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4216 return TokError(
"expected register operand");
4218 Operands.
push_back(AArch64Operand::CreateReg(
4219 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4226 const AsmToken &operandTok = getTok();
4228 SMLoc S2 = operandTok.
getLoc();
4231 if (Mnemonic ==
"gicr") {
4232 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4234 return Error(S2,
"invalid operand for GICR instruction");
4235 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4236 std::string Str(
"GICR " + std::string(GICR->
Name) +
" requires: ");
4238 return Error(S2, Str);
4240 createSysAlias(GICR->
Encoding, Operands, S2);
4251bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4253 if (
Name.contains(
'.'))
4254 return TokError(
"invalid operand");
4258 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4260 const AsmToken &Tok = getTok();
4264 if (Mnemonic ==
"tlbip") {
4265 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4266 if (HasnXSQualifier) {
4267 Op =
Op.drop_back(3);
4269 const AArch64TLBIP::TLBIP *TLBIPorig = AArch64TLBIP::lookupTLBIPByName(
Op);
4271 return TokError(
"invalid operand for TLBIP instruction");
4272 const AArch64TLBIP::TLBIP TLBIP(
4273 TLBIPorig->
Name, TLBIPorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4278 if (!TLBIP.haveFeatures(getSTI().getFeatureBits())) {
4280 std::string(TLBIP.Name) + (HasnXSQualifier ?
"nXS" :
"");
4281 std::string Str(
"TLBIP " + Name +
" requires: ");
4283 return TokError(Str);
4285 createSysAlias(TLBIP.Encoding, Operands, S);
4294 return TokError(
"expected register identifier");
4295 auto Result = tryParseSyspXzrPair(Operands);
4297 Result = tryParseGPRSeqPair(Operands);
4299 return TokError(
"specified " + Mnemonic +
4300 " op requires a pair of registers");
4308ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4309 MCAsmParser &Parser = getParser();
4310 const AsmToken &Tok = getTok();
4313 return TokError(
"'csync' operand expected");
4316 const MCExpr *ImmVal;
4317 SMLoc ExprLoc = getLoc();
4318 AsmToken IntTok = Tok;
4319 if (getParser().parseExpression(ImmVal))
4323 return Error(ExprLoc,
"immediate value expected for barrier operand");
4325 if (Mnemonic ==
"dsb" &&
Value > 15) {
4333 return Error(ExprLoc,
"barrier operand out of range");
4334 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4335 Operands.
push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4342 return TokError(
"invalid operand for instruction");
4345 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4346 auto DB = AArch64DB::lookupDBByName(Operand);
4348 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4349 return TokError(
"'sy' or #imm operand expected");
4351 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4352 return TokError(
"'csync' operand expected");
4354 if (Mnemonic ==
"dsb") {
4359 return TokError(
"invalid barrier option name");
4362 Operands.
push_back(AArch64Operand::CreateBarrier(
4363 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4371AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4372 const AsmToken &Tok = getTok();
4374 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4375 if (Mnemonic !=
"dsb")
4380 const MCExpr *ImmVal;
4381 SMLoc ExprLoc = getLoc();
4382 if (getParser().parseExpression(ImmVal))
4386 return Error(ExprLoc,
"immediate value expected for barrier operand");
4391 return Error(ExprLoc,
"barrier operand out of range");
4392 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4393 Operands.
push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4400 return TokError(
"invalid operand for instruction");
4403 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4406 return TokError(
"invalid barrier option name");
4409 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4416ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4417 const AsmToken &Tok = getTok();
4422 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4426 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4427 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4428 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4429 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4433 unsigned PStateImm = -1;
4434 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4435 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4436 PStateImm = PState15->Encoding;
4438 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4439 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4440 PStateImm = PState1->Encoding;
4444 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4452AArch64AsmParser::tryParsePHintInstOperand(
OperandVector &Operands) {
4454 const AsmToken &Tok = getTok();
4456 return TokError(
"invalid operand for instruction");
4460 return TokError(
"invalid operand for instruction");
4462 Operands.
push_back(AArch64Operand::CreatePHintInst(
4469bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4477 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4485 unsigned ElementWidth = KindRes->second;
4487 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4495 return tryParseVectorIndex(Operands).isFailure();
4498ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4499 SMLoc SIdx = getLoc();
4501 const MCExpr *ImmVal;
4502 if (getParser().parseExpression(ImmVal))
4506 return TokError(
"immediate value expected for vector index");
4524ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4526 RegKind MatchKind) {
4527 const AsmToken &Tok = getTok();
4536 StringRef Head =
Name.slice(Start,
Next);
4537 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4543 return TokError(
"invalid vector kind qualifier");
4554ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4556 ParseStatus Status =
4557 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4559 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4564template <RegKind RK>
4566AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4568 const SMLoc S = getLoc();
4571 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4579 unsigned ElementWidth = KindRes->second;
4580 Operands.
push_back(AArch64Operand::CreateVectorReg(
4581 RegNum, RK, ElementWidth, S,
4585 if (RK == RegKind::SVEPredicateAsCounter) {
4586 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4592 if (parseOperand(Operands,
false,
false))
4603 return Error(S,
"not expecting size suffix");
4611 auto Pred = getTok().getString().lower();
4612 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4613 return Error(getLoc(),
"expecting 'z' predication");
4615 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4616 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4619 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4627bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4629 if (!tryParseNeonVectorRegister(Operands))
4632 if (tryParseZTOperand(Operands).isSuccess())
4636 if (tryParseGPROperand<false>(Operands).isSuccess())
4642bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4643 bool HasELFModifier =
false;
4645 SMLoc Loc = getLexer().getLoc();
4647 HasELFModifier =
true;
4650 return TokError(
"expect relocation specifier in operand after ':'");
4652 std::string LowerCase = getTok().getIdentifier().lower();
4653 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4707 return TokError(
"expect relocation specifier in operand after ':'");
4711 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4715 if (getParser().parseExpression(ImmVal))
4722 if (
getContext().getAsmInfo()->hasSubsectionsViaSymbols()) {
4723 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4733 if (getParser().parsePrimaryExpr(Term, EndLoc))
4741ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4745 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4746 unsigned &ElementWidth) -> ParseStatus {
4747 StringRef
Name = getTok().getString();
4748 size_t DotPosition =
Name.find(
'.');
4756 StringRef
Tail =
Name.drop_front(DotPosition);
4757 const std::optional<std::pair<int, int>> &KindRes =
4761 "Expected the register to be followed by element width suffix");
4762 ElementWidth = KindRes->second;
4769 auto LCurly = getTok();
4774 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4780 if (getTok().getString().equals_insensitive(
"za")) {
4786 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4791 SMLoc TileLoc = getLoc();
4793 unsigned FirstReg, ElementWidth;
4794 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4795 if (!ParseRes.isSuccess()) {
4796 getLexer().UnLex(LCurly);
4800 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4802 unsigned PrevReg = FirstReg;
4804 SmallSet<unsigned, 8> DRegs;
4805 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4807 SmallSet<unsigned, 8> SeenRegs;
4808 SeenRegs.
insert(FirstReg);
4812 unsigned Reg, NextElementWidth;
4813 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4814 if (!ParseRes.isSuccess())
4818 if (ElementWidth != NextElementWidth)
4819 return Error(TileLoc,
"mismatched register size suffix");
4822 Warning(TileLoc,
"tile list not in ascending order");
4825 Warning(TileLoc,
"duplicate tile in list");
4828 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4837 unsigned RegMask = 0;
4838 for (
auto Reg : DRegs)
4842 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4847template <RegKind VectorKind>
4848ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4850 MCAsmParser &Parser = getParser();
4855 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4856 bool NoMatchIsError) -> ParseStatus {
4857 auto RegTok = getTok();
4858 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4859 if (ParseRes.isSuccess()) {
4866 RegTok.getString().equals_insensitive(
"zt0"))
4870 (ParseRes.isNoMatch() && NoMatchIsError &&
4871 !RegTok.getString().starts_with_insensitive(
"za")))
4872 return Error(Loc,
"vector register expected");
4877 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4879 auto LCurly = getTok();
4883 MCRegister FirstReg;
4884 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4888 if (ParseRes.isNoMatch())
4891 if (!ParseRes.isSuccess())
4894 MCRegister PrevReg = FirstReg;
4897 unsigned Stride = 1;
4899 SMLoc Loc = getLoc();
4903 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4904 if (!ParseRes.isSuccess())
4908 if (Kind != NextKind)
4909 return Error(Loc,
"mismatched register size suffix");
4912 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4914 if (Space == 0 || Space > 3)
4915 return Error(Loc,
"invalid number of vectors");
4920 bool HasCalculatedStride =
false;
4922 SMLoc Loc = getLoc();
4925 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4926 if (!ParseRes.isSuccess())
4930 if (Kind != NextKind)
4931 return Error(Loc,
"mismatched register size suffix");
4933 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4934 unsigned PrevRegVal =
4935 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4936 if (!HasCalculatedStride) {
4937 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4938 : (NumRegs - (PrevRegVal - RegVal));
4939 HasCalculatedStride =
true;
4943 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4944 return Error(Loc,
"registers must have the same sequential stride");
4955 return Error(S,
"invalid number of vectors");
4957 unsigned NumElements = 0;
4958 unsigned ElementWidth = 0;
4959 if (!
Kind.empty()) {
4961 std::tie(NumElements, ElementWidth) = *VK;
4964 Operands.
push_back(AArch64Operand::CreateVectorList(
4965 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4969 ParseStatus Res = tryParseVectorIndex(Operands);
4979bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4980 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4981 if (!ParseRes.isSuccess())
4984 return tryParseVectorIndex(Operands).isFailure();
4987ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4988 SMLoc StartLoc = getLoc();
4991 ParseStatus Res = tryParseScalarRegister(RegNum);
4996 Operands.
push_back(AArch64Operand::CreateReg(
4997 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
5004 return Error(getLoc(),
"index must be absent or #0");
5006 const MCExpr *ImmVal;
5009 return Error(getLoc(),
"index must be absent or #0");
5011 Operands.
push_back(AArch64Operand::CreateReg(
5012 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
5016ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
5017 SMLoc StartLoc = getLoc();
5018 const AsmToken &Tok = getTok();
5021 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
5026 Operands.
push_back(AArch64Operand::CreateReg(
5027 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
5033 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5034 const MCExpr *ImmVal;
5035 if (getParser().parseExpression(ImmVal))
5039 return TokError(
"immediate value expected for vector index");
5040 Operands.
push_back(AArch64Operand::CreateImm(
5044 if (parseOptionalMulOperand(Operands))
5049 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5054template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
5055ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
5056 SMLoc StartLoc = getLoc();
5059 ParseStatus Res = tryParseScalarRegister(RegNum);
5065 Operands.
push_back(AArch64Operand::CreateReg(
5066 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
5075 Res = tryParseOptionalShiftExtend(ExtOpnd);
5079 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
5080 Operands.
push_back(AArch64Operand::CreateReg(
5081 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
5082 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
5083 Ext->hasShiftExtendAmount()));
5088bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
5089 MCAsmParser &Parser = getParser();
5097 if (!getTok().getString().equals_insensitive(
"mul") ||
5098 !(NextIsVL || NextIsHash))
5102 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
5107 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
5117 const MCExpr *ImmVal;
5120 Operands.
push_back(AArch64Operand::CreateImm(
5127 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
5130bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
5131 StringRef &VecGroup) {
5132 MCAsmParser &Parser = getParser();
5133 auto Tok = Parser.
getTok();
5138 .Case(
"vgx2",
"vgx2")
5139 .Case(
"vgx4",
"vgx4")
5150bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
5151 auto Tok = getTok();
5169bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
5170 bool invertCondCode) {
5171 MCAsmParser &Parser = getParser();
5174 MatchOperandParserImpl(Operands, Mnemonic,
true);
5188 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
5190 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
5193 getLexer().UnLex(SavedTok);
5197 switch (getLexer().getKind()) {
5201 if (parseSymbolicImmVal(Expr))
5202 return Error(S,
"invalid operand");
5206 return parseOptionalShiftExtend(getTok());
5210 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5215 return parseOperand(Operands,
false,
false);
5218 if (!parseNeonVectorList(Operands))
5222 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5227 return parseOperand(Operands,
false,
false);
5232 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5234 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5239 return parseCondCode(Operands, invertCondCode);
5242 if (!parseRegister(Operands)) {
5244 AsmToken SavedTok = getTok();
5249 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5253 Res = tryParseOptionalShiftExtend(Operands);
5256 getLexer().UnLex(SavedTok);
5263 if (!parseOptionalMulOperand(Operands))
5268 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5270 return parseKeywordOperand(Operands);
5274 const MCExpr *IdVal, *
Term;
5276 if (getParser().parseExpression(IdVal))
5278 if (getParser().parseAtSpecifier(IdVal,
E))
5280 std::optional<MCBinaryExpr::Opcode> Opcode;
5286 if (getParser().parsePrimaryExpr(Term,
E))
5293 return parseOptionalShiftExtend(getTok());
5304 bool isNegative =
false;
5316 const AsmToken &Tok = getTok();
5319 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5320 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5321 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5322 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5323 return TokError(
"unexpected floating point literal");
5324 else if (IntVal != 0 || isNegative)
5325 return TokError(
"expected floating-point constant #0.0");
5333 const MCExpr *ImmVal;
5334 if (parseSymbolicImmVal(ImmVal))
5341 return parseOptionalShiftExtend(Tok);
5344 SMLoc Loc = getLoc();
5345 if (Mnemonic !=
"ldr")
5346 return TokError(
"unexpected token in operand");
5348 const MCExpr *SubExprVal;
5349 if (getParser().parseExpression(SubExprVal))
5352 if (Operands.
size() < 2 ||
5353 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5354 return Error(Loc,
"Only valid when first operand is register");
5357 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5365 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5370 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5371 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5372 Operands.
push_back(AArch64Operand::CreateImm(
5376 ShiftAmt,
true, S,
E, Ctx));
5379 APInt Simm = APInt(64, Imm << ShiftAmt);
5382 return Error(Loc,
"Immediate too large for register");
5385 const MCExpr *CPLoc =
5386 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5387 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5393bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5394 const MCExpr *Expr =
nullptr;
5396 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5399 if (check(!
Value, L,
"expected constant expression"))
5401 Out =
Value->getValue();
5405bool AArch64AsmParser::parseComma() {
5413bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5417 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5422 unsigned RangeEnd =
Last;
5423 if (
Base == AArch64::X0) {
5424 if (
Last == AArch64::FP) {
5425 RangeEnd = AArch64::X28;
5426 if (
Reg == AArch64::FP) {
5431 if (
Last == AArch64::LR) {
5432 RangeEnd = AArch64::X28;
5433 if (
Reg == AArch64::FP) {
5436 }
else if (
Reg == AArch64::LR) {
5444 Twine(
"expected register in range ") +
5452bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5453 const MCParsedAsmOperand &Op2)
const {
5454 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5455 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5457 if (AOp1.isVectorList() && AOp2.isVectorList())
5458 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5459 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5460 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5462 if (!AOp1.isReg() || !AOp2.isReg())
5465 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5466 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5469 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5470 "Testing equality of non-scalar registers not supported");
5473 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5475 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5477 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5479 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5486bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &
Info,
5487 StringRef Name, SMLoc NameLoc,
5489 Name = StringSwitch<StringRef>(
Name.lower())
5490 .Case(
"beq",
"b.eq")
5491 .Case(
"bne",
"b.ne")
5492 .Case(
"bhs",
"b.hs")
5493 .Case(
"bcs",
"b.cs")
5494 .Case(
"blo",
"b.lo")
5495 .Case(
"bcc",
"b.cc")
5496 .Case(
"bmi",
"b.mi")
5497 .Case(
"bpl",
"b.pl")
5498 .Case(
"bvs",
"b.vs")
5499 .Case(
"bvc",
"b.vc")
5500 .Case(
"bhi",
"b.hi")
5501 .Case(
"bls",
"b.ls")
5502 .Case(
"bge",
"b.ge")
5503 .Case(
"blt",
"b.lt")
5504 .Case(
"bgt",
"b.gt")
5505 .Case(
"ble",
"b.le")
5506 .Case(
"bal",
"b.al")
5507 .Case(
"bnv",
"b.nv")
5512 getTok().getIdentifier().lower() ==
".req") {
5513 parseDirectiveReq(Name, NameLoc);
5521 StringRef Head =
Name.slice(Start,
Next);
5525 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5526 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5527 Head ==
"mlbi" || Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5528 return parseSysAlias(Head, NameLoc, Operands);
5532 return parseSyslAlias(Head, NameLoc, Operands);
5535 if (Head ==
"tlbip")
5536 return parseSyspAlias(Head, NameLoc, Operands);
5545 Head =
Name.slice(Start + 1,
Next);
5549 std::string Suggestion;
5552 std::string Msg =
"invalid condition code";
5553 if (!Suggestion.empty())
5554 Msg +=
", did you mean " + Suggestion +
"?";
5555 return Error(SuffixLoc, Msg);
5560 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5570 Operands.
push_back(AArch64Operand::CreateToken(
5576 bool condCodeFourthOperand =
5577 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5578 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5579 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5587 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5588 bool condCodeThirdOperand =
5589 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5597 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5598 (
N == 3 && condCodeThirdOperand) ||
5599 (
N == 2 && condCodeSecondOperand),
5600 condCodeSecondOperand || condCodeThirdOperand)) {
5620 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5623 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5626 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5639 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5640 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5641 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5642 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5643 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5644 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5645 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5651bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5652 SmallVectorImpl<SMLoc> &Loc) {
5653 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5654 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5660 PrefixInfo
Prefix = NextPrefix;
5661 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5673 return Error(IDLoc,
"instruction is unpredictable when following a"
5674 " movprfx, suggest replacing movprfx with mov");
5678 return Error(Loc[0],
"instruction is unpredictable when following a"
5679 " movprfx writing to a different destination");
5686 return Error(Loc[0],
"instruction is unpredictable when following a"
5687 " movprfx and destination also used as non-destructive"
5691 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5692 if (
Prefix.isPredicated()) {
5706 return Error(IDLoc,
"instruction is unpredictable when following a"
5707 " predicated movprfx, suggest using unpredicated movprfx");
5711 return Error(IDLoc,
"instruction is unpredictable when following a"
5712 " predicated movprfx using a different general predicate");
5716 return Error(IDLoc,
"instruction is unpredictable when following a"
5717 " predicated movprfx with a different element size");
5723 if (IsWindowsArm64EC) {
5729 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5730 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5731 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5732 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5733 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5734 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5735 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5736 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5737 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5738 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5740 " is disallowed on ARM64EC.");
5750 case AArch64::LDPSWpre:
5751 case AArch64::LDPWpost:
5752 case AArch64::LDPWpre:
5753 case AArch64::LDPXpost:
5754 case AArch64::LDPXpre: {
5759 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5760 "is also a destination");
5762 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5763 "is also a destination");
5766 case AArch64::LDR_ZA:
5767 case AArch64::STR_ZA: {
5770 return Error(Loc[1],
5771 "unpredictable instruction, immediate and offset mismatch.");
5774 case AArch64::LDPDi:
5775 case AArch64::LDPQi:
5776 case AArch64::LDPSi:
5777 case AArch64::LDPSWi:
5778 case AArch64::LDPWi:
5779 case AArch64::LDPXi: {
5783 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5786 case AArch64::LDPDpost:
5787 case AArch64::LDPDpre:
5788 case AArch64::LDPQpost:
5789 case AArch64::LDPQpre:
5790 case AArch64::LDPSpost:
5791 case AArch64::LDPSpre:
5792 case AArch64::LDPSWpost: {
5796 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5799 case AArch64::STPDpost:
5800 case AArch64::STPDpre:
5801 case AArch64::STPQpost:
5802 case AArch64::STPQpre:
5803 case AArch64::STPSpost:
5804 case AArch64::STPSpre:
5805 case AArch64::STPWpost:
5806 case AArch64::STPWpre:
5807 case AArch64::STPXpost:
5808 case AArch64::STPXpre: {
5813 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5814 "is also a source");
5816 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5817 "is also a source");
5820 case AArch64::LDRBBpre:
5821 case AArch64::LDRBpre:
5822 case AArch64::LDRHHpre:
5823 case AArch64::LDRHpre:
5824 case AArch64::LDRSBWpre:
5825 case AArch64::LDRSBXpre:
5826 case AArch64::LDRSHWpre:
5827 case AArch64::LDRSHXpre:
5828 case AArch64::LDRSWpre:
5829 case AArch64::LDRWpre:
5830 case AArch64::LDRXpre:
5831 case AArch64::LDRBBpost:
5832 case AArch64::LDRBpost:
5833 case AArch64::LDRHHpost:
5834 case AArch64::LDRHpost:
5835 case AArch64::LDRSBWpost:
5836 case AArch64::LDRSBXpost:
5837 case AArch64::LDRSHWpost:
5838 case AArch64::LDRSHXpost:
5839 case AArch64::LDRSWpost:
5840 case AArch64::LDRWpost:
5841 case AArch64::LDRXpost: {
5845 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5846 "is also a source");
5849 case AArch64::STRBBpost:
5850 case AArch64::STRBpost:
5851 case AArch64::STRHHpost:
5852 case AArch64::STRHpost:
5853 case AArch64::STRWpost:
5854 case AArch64::STRXpost:
5855 case AArch64::STRBBpre:
5856 case AArch64::STRBpre:
5857 case AArch64::STRHHpre:
5858 case AArch64::STRHpre:
5859 case AArch64::STRWpre:
5860 case AArch64::STRXpre: {
5864 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5865 "is also a source");
5868 case AArch64::STXRB:
5869 case AArch64::STXRH:
5870 case AArch64::STXRW:
5871 case AArch64::STXRX:
5872 case AArch64::STLXRB:
5873 case AArch64::STLXRH:
5874 case AArch64::STLXRW:
5875 case AArch64::STLXRX: {
5881 return Error(Loc[0],
5882 "unpredictable STXR instruction, status is also a source");
5885 case AArch64::STXPW:
5886 case AArch64::STXPX:
5887 case AArch64::STLXPW:
5888 case AArch64::STLXPX: {
5895 return Error(Loc[0],
5896 "unpredictable STXP instruction, status is also a source");
5899 case AArch64::LDRABwriteback:
5900 case AArch64::LDRAAwriteback: {
5904 return Error(Loc[0],
5905 "unpredictable LDRA instruction, writeback base"
5906 " is also a destination");
5913 case AArch64::CPYFP:
5914 case AArch64::CPYFPWN:
5915 case AArch64::CPYFPRN:
5916 case AArch64::CPYFPN:
5917 case AArch64::CPYFPWT:
5918 case AArch64::CPYFPWTWN:
5919 case AArch64::CPYFPWTRN:
5920 case AArch64::CPYFPWTN:
5921 case AArch64::CPYFPRT:
5922 case AArch64::CPYFPRTWN:
5923 case AArch64::CPYFPRTRN:
5924 case AArch64::CPYFPRTN:
5925 case AArch64::CPYFPT:
5926 case AArch64::CPYFPTWN:
5927 case AArch64::CPYFPTRN:
5928 case AArch64::CPYFPTN:
5929 case AArch64::CPYFM:
5930 case AArch64::CPYFMWN:
5931 case AArch64::CPYFMRN:
5932 case AArch64::CPYFMN:
5933 case AArch64::CPYFMWT:
5934 case AArch64::CPYFMWTWN:
5935 case AArch64::CPYFMWTRN:
5936 case AArch64::CPYFMWTN:
5937 case AArch64::CPYFMRT:
5938 case AArch64::CPYFMRTWN:
5939 case AArch64::CPYFMRTRN:
5940 case AArch64::CPYFMRTN:
5941 case AArch64::CPYFMT:
5942 case AArch64::CPYFMTWN:
5943 case AArch64::CPYFMTRN:
5944 case AArch64::CPYFMTN:
5945 case AArch64::CPYFE:
5946 case AArch64::CPYFEWN:
5947 case AArch64::CPYFERN:
5948 case AArch64::CPYFEN:
5949 case AArch64::CPYFEWT:
5950 case AArch64::CPYFEWTWN:
5951 case AArch64::CPYFEWTRN:
5952 case AArch64::CPYFEWTN:
5953 case AArch64::CPYFERT:
5954 case AArch64::CPYFERTWN:
5955 case AArch64::CPYFERTRN:
5956 case AArch64::CPYFERTN:
5957 case AArch64::CPYFET:
5958 case AArch64::CPYFETWN:
5959 case AArch64::CPYFETRN:
5960 case AArch64::CPYFETN:
5962 case AArch64::CPYPWN:
5963 case AArch64::CPYPRN:
5964 case AArch64::CPYPN:
5965 case AArch64::CPYPWT:
5966 case AArch64::CPYPWTWN:
5967 case AArch64::CPYPWTRN:
5968 case AArch64::CPYPWTN:
5969 case AArch64::CPYPRT:
5970 case AArch64::CPYPRTWN:
5971 case AArch64::CPYPRTRN:
5972 case AArch64::CPYPRTN:
5973 case AArch64::CPYPT:
5974 case AArch64::CPYPTWN:
5975 case AArch64::CPYPTRN:
5976 case AArch64::CPYPTN:
5978 case AArch64::CPYMWN:
5979 case AArch64::CPYMRN:
5980 case AArch64::CPYMN:
5981 case AArch64::CPYMWT:
5982 case AArch64::CPYMWTWN:
5983 case AArch64::CPYMWTRN:
5984 case AArch64::CPYMWTN:
5985 case AArch64::CPYMRT:
5986 case AArch64::CPYMRTWN:
5987 case AArch64::CPYMRTRN:
5988 case AArch64::CPYMRTN:
5989 case AArch64::CPYMT:
5990 case AArch64::CPYMTWN:
5991 case AArch64::CPYMTRN:
5992 case AArch64::CPYMTN:
5994 case AArch64::CPYEWN:
5995 case AArch64::CPYERN:
5996 case AArch64::CPYEN:
5997 case AArch64::CPYEWT:
5998 case AArch64::CPYEWTWN:
5999 case AArch64::CPYEWTRN:
6000 case AArch64::CPYEWTN:
6001 case AArch64::CPYERT:
6002 case AArch64::CPYERTWN:
6003 case AArch64::CPYERTRN:
6004 case AArch64::CPYERTN:
6005 case AArch64::CPYET:
6006 case AArch64::CPYETWN:
6007 case AArch64::CPYETRN:
6008 case AArch64::CPYETN: {
6019 return Error(Loc[0],
"invalid CPY instruction, destination and source"
6020 " registers are the same");
6022 return Error(Loc[0],
"invalid CPY instruction, destination and size"
6023 " registers are the same");
6025 return Error(Loc[0],
"invalid CPY instruction, source and size"
6026 " registers are the same");
6030 case AArch64::SETPT:
6031 case AArch64::SETPN:
6032 case AArch64::SETPTN:
6034 case AArch64::SETMT:
6035 case AArch64::SETMN:
6036 case AArch64::SETMTN:
6038 case AArch64::SETET:
6039 case AArch64::SETEN:
6040 case AArch64::SETETN:
6041 case AArch64::SETGP:
6042 case AArch64::SETGPT:
6043 case AArch64::SETGPN:
6044 case AArch64::SETGPTN:
6045 case AArch64::SETGM:
6046 case AArch64::SETGMT:
6047 case AArch64::SETGMN:
6048 case AArch64::SETGMTN:
6049 case AArch64::MOPSSETGE:
6050 case AArch64::MOPSSETGET:
6051 case AArch64::MOPSSETGEN:
6052 case AArch64::MOPSSETGETN: {
6062 return Error(Loc[0],
"invalid SET instruction, destination and size"
6063 " registers are the same");
6065 return Error(Loc[0],
"invalid SET instruction, destination and source"
6066 " registers are the same");
6068 return Error(Loc[0],
"invalid SET instruction, source and size"
6069 " registers are the same");
6072 case AArch64::SETGOP:
6073 case AArch64::SETGOPT:
6074 case AArch64::SETGOPN:
6075 case AArch64::SETGOPTN:
6076 case AArch64::SETGOM:
6077 case AArch64::SETGOMT:
6078 case AArch64::SETGOMN:
6079 case AArch64::SETGOMTN:
6080 case AArch64::SETGOE:
6081 case AArch64::SETGOET:
6082 case AArch64::SETGOEN:
6083 case AArch64::SETGOETN: {
6092 return Error(Loc[0],
"invalid SET instruction, destination and size"
6093 " registers are the same");
6102 case AArch64::ADDSWri:
6103 case AArch64::ADDSXri:
6104 case AArch64::ADDWri:
6105 case AArch64::ADDXri:
6106 case AArch64::SUBSWri:
6107 case AArch64::SUBSXri:
6108 case AArch64::SUBWri:
6109 case AArch64::SUBXri: {
6117 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
6142 return Error(Loc.
back(),
"invalid immediate expression");
6155 unsigned VariantID = 0);
6157bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
6161 case Match_InvalidTiedOperand: {
6162 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
6163 if (
Op.isVectorList())
6164 return Error(
Loc,
"operand must match destination register list");
6166 assert(
Op.isReg() &&
"Unexpected operand type");
6167 switch (
Op.getRegEqualityTy()) {
6168 case RegConstraintEqualityTy::EqualsSubReg:
6169 return Error(
Loc,
"operand must be 64-bit form of destination register");
6170 case RegConstraintEqualityTy::EqualsSuperReg:
6171 return Error(
Loc,
"operand must be 32-bit form of destination register");
6172 case RegConstraintEqualityTy::EqualsReg:
6173 return Error(
Loc,
"operand must match destination register");
6177 case Match_MissingFeature:
6179 "instruction requires a CPU feature not currently enabled");
6180 case Match_InvalidOperand:
6181 return Error(Loc,
"invalid operand for instruction");
6182 case Match_InvalidSuffix:
6183 return Error(Loc,
"invalid type suffix for instruction");
6184 case Match_InvalidCondCode:
6185 return Error(Loc,
"expected AArch64 condition code");
6186 case Match_AddSubRegExtendSmall:
6188 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
6189 case Match_AddSubRegExtendLarge:
6191 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
6192 case Match_AddSubSecondSource:
6194 "expected compatible register, symbol or integer in range [0, 4095]");
6195 case Match_LogicalSecondSource:
6196 return Error(Loc,
"expected compatible register or logical immediate");
6197 case Match_InvalidMovImm32Shift:
6198 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
6199 case Match_InvalidMovImm64Shift:
6200 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
6201 case Match_AddSubRegShift32:
6203 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
6204 case Match_AddSubRegShift64:
6206 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
6207 case Match_InvalidFPImm:
6209 "expected compatible register or floating-point constant");
6210 case Match_InvalidMemoryIndexedSImm6:
6211 return Error(Loc,
"index must be an integer in range [-32, 31].");
6212 case Match_InvalidMemoryIndexedSImm5:
6213 return Error(Loc,
"index must be an integer in range [-16, 15].");
6214 case Match_InvalidMemoryIndexed1SImm4:
6215 return Error(Loc,
"index must be an integer in range [-8, 7].");
6216 case Match_InvalidMemoryIndexed2SImm4:
6217 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6218 case Match_InvalidMemoryIndexed3SImm4:
6219 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6220 case Match_InvalidMemoryIndexed4SImm4:
6221 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6222 case Match_InvalidMemoryIndexed16SImm4:
6223 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6224 case Match_InvalidMemoryIndexed32SImm4:
6225 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6226 case Match_InvalidMemoryIndexed1SImm6:
6227 return Error(Loc,
"index must be an integer in range [-32, 31].");
6228 case Match_InvalidMemoryIndexedSImm8:
6229 return Error(Loc,
"index must be an integer in range [-128, 127].");
6230 case Match_InvalidMemoryIndexedSImm9:
6231 return Error(Loc,
"index must be an integer in range [-256, 255].");
6232 case Match_InvalidMemoryIndexed16SImm9:
6233 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6234 case Match_InvalidMemoryIndexed8SImm10:
6235 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6236 case Match_InvalidMemoryIndexed4SImm7:
6237 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6238 case Match_InvalidMemoryIndexed8SImm7:
6239 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6240 case Match_InvalidMemoryIndexed16SImm7:
6241 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6242 case Match_InvalidMemoryIndexed8UImm5:
6243 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6244 case Match_InvalidMemoryIndexed8UImm3:
6245 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6246 case Match_InvalidMemoryIndexed4UImm5:
6247 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6248 case Match_InvalidMemoryIndexed2UImm5:
6249 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6250 case Match_InvalidMemoryIndexed8UImm6:
6251 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6252 case Match_InvalidMemoryIndexed16UImm6:
6253 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6254 case Match_InvalidMemoryIndexed4UImm6:
6255 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6256 case Match_InvalidMemoryIndexed2UImm6:
6257 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6258 case Match_InvalidMemoryIndexed1UImm6:
6259 return Error(Loc,
"index must be in range [0, 63].");
6260 case Match_InvalidMemoryWExtend8:
6262 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6263 case Match_InvalidMemoryWExtend16:
6265 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6266 case Match_InvalidMemoryWExtend32:
6268 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6269 case Match_InvalidMemoryWExtend64:
6271 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6272 case Match_InvalidMemoryWExtend128:
6274 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6275 case Match_InvalidMemoryXExtend8:
6277 "expected 'lsl' or 'sxtx' with optional shift of #0");
6278 case Match_InvalidMemoryXExtend16:
6280 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6281 case Match_InvalidMemoryXExtend32:
6283 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6284 case Match_InvalidMemoryXExtend64:
6286 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6287 case Match_InvalidMemoryXExtend128:
6289 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6290 case Match_InvalidMemoryIndexed1:
6291 return Error(Loc,
"index must be an integer in range [0, 4095].");
6292 case Match_InvalidMemoryIndexed2:
6293 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6294 case Match_InvalidMemoryIndexed4:
6295 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6296 case Match_InvalidMemoryIndexed8:
6297 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6298 case Match_InvalidMemoryIndexed16:
6299 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6300 case Match_InvalidImm0_0:
6301 return Error(Loc,
"immediate must be 0.");
6302 case Match_InvalidImm0_1:
6303 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6304 case Match_InvalidImm0_3:
6305 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6306 case Match_InvalidImm0_7:
6307 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6308 case Match_InvalidImm0_15:
6309 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6310 case Match_InvalidImm0_31:
6311 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6312 case Match_InvalidImm0_63:
6313 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6314 case Match_InvalidImm0_127:
6315 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6316 case Match_InvalidImm0_255:
6317 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6318 case Match_InvalidImm0_65535:
6319 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6320 case Match_InvalidImm1_8:
6321 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6322 case Match_InvalidImm1_16:
6323 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6324 case Match_InvalidImm1_32:
6325 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6326 case Match_InvalidImm1_64:
6327 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6328 case Match_InvalidImmM1_62:
6329 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6330 case Match_InvalidMemoryIndexedRange2UImm0:
6331 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6332 case Match_InvalidMemoryIndexedRange2UImm1:
6333 return Error(Loc,
"vector select offset must be an immediate range of the "
6334 "form <immf>:<imml>, where the first "
6335 "immediate is a multiple of 2 in the range [0, 2], and "
6336 "the second immediate is immf + 1.");
6337 case Match_InvalidMemoryIndexedRange2UImm2:
6338 case Match_InvalidMemoryIndexedRange2UImm3:
6341 "vector select offset must be an immediate range of the form "
6343 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6345 "depending on the instruction, and the second immediate is immf + 1.");
6346 case Match_InvalidMemoryIndexedRange4UImm0:
6347 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6348 case Match_InvalidMemoryIndexedRange4UImm1:
6349 case Match_InvalidMemoryIndexedRange4UImm2:
6352 "vector select offset must be an immediate range of the form "
6354 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6356 "depending on the instruction, and the second immediate is immf + 3.");
6357 case Match_InvalidSVEAddSubImm8:
6358 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6359 " with a shift amount of 0");
6360 case Match_InvalidSVEAddSubImm16:
6361 case Match_InvalidSVEAddSubImm32:
6362 case Match_InvalidSVEAddSubImm64:
6363 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6364 "multiple of 256 in range [256, 65280]");
6365 case Match_InvalidSVECpyImm8:
6366 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6367 " with a shift amount of 0");
6368 case Match_InvalidSVECpyImm16:
6369 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6370 "multiple of 256 in range [-32768, 65280]");
6371 case Match_InvalidSVECpyImm32:
6372 case Match_InvalidSVECpyImm64:
6373 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6374 "multiple of 256 in range [-32768, 32512]");
6375 case Match_InvalidIndexRange0_0:
6376 return Error(Loc,
"expected lane specifier '[0]'");
6377 case Match_InvalidIndexRange1_1:
6378 return Error(Loc,
"expected lane specifier '[1]'");
6379 case Match_InvalidIndexRange0_15:
6380 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6381 case Match_InvalidIndexRange0_7:
6382 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6383 case Match_InvalidIndexRange0_3:
6384 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6385 case Match_InvalidIndexRange0_1:
6386 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6387 case Match_InvalidSVEIndexRange0_63:
6388 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6389 case Match_InvalidSVEIndexRange0_31:
6390 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6391 case Match_InvalidSVEIndexRange0_15:
6392 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6393 case Match_InvalidSVEIndexRange0_7:
6394 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6395 case Match_InvalidSVEIndexRange0_3:
6396 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6397 case Match_InvalidLabel:
6398 return Error(Loc,
"expected label or encodable integer pc offset");
6400 return Error(Loc,
"expected readable system register");
6402 case Match_InvalidSVCR:
6403 return Error(Loc,
"expected writable system register or pstate");
6404 case Match_InvalidComplexRotationEven:
6405 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6406 case Match_InvalidComplexRotationOdd:
6407 return Error(Loc,
"complex rotation must be 90 or 270.");
6408 case Match_MnemonicFail: {
6410 ((AArch64Operand &)*Operands[0]).
getToken(),
6411 ComputeAvailableFeatures(STI->getFeatureBits()));
6412 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6414 case Match_InvalidGPR64shifted8:
6415 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6416 case Match_InvalidGPR64shifted16:
6417 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6418 case Match_InvalidGPR64shifted32:
6419 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6420 case Match_InvalidGPR64shifted64:
6421 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6422 case Match_InvalidGPR64shifted128:
6424 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6425 case Match_InvalidGPR64NoXZRshifted8:
6426 return Error(Loc,
"register must be x0..x30 without shift");
6427 case Match_InvalidGPR64NoXZRshifted16:
6428 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6429 case Match_InvalidGPR64NoXZRshifted32:
6430 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6431 case Match_InvalidGPR64NoXZRshifted64:
6432 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6433 case Match_InvalidGPR64NoXZRshifted128:
6434 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6435 case Match_InvalidZPR32UXTW8:
6436 case Match_InvalidZPR32SXTW8:
6437 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6438 case Match_InvalidZPR32UXTW16:
6439 case Match_InvalidZPR32SXTW16:
6440 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6441 case Match_InvalidZPR32UXTW32:
6442 case Match_InvalidZPR32SXTW32:
6443 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6444 case Match_InvalidZPR32UXTW64:
6445 case Match_InvalidZPR32SXTW64:
6446 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6447 case Match_InvalidZPR64UXTW8:
6448 case Match_InvalidZPR64SXTW8:
6449 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6450 case Match_InvalidZPR64UXTW16:
6451 case Match_InvalidZPR64SXTW16:
6452 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6453 case Match_InvalidZPR64UXTW32:
6454 case Match_InvalidZPR64SXTW32:
6455 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6456 case Match_InvalidZPR64UXTW64:
6457 case Match_InvalidZPR64SXTW64:
6458 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6459 case Match_InvalidZPR32LSL8:
6460 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6461 case Match_InvalidZPR32LSL16:
6462 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6463 case Match_InvalidZPR32LSL32:
6464 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6465 case Match_InvalidZPR32LSL64:
6466 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6467 case Match_InvalidZPR64LSL8:
6468 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6469 case Match_InvalidZPR64LSL16:
6470 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6471 case Match_InvalidZPR64LSL32:
6472 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6473 case Match_InvalidZPR64LSL64:
6474 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6475 case Match_InvalidZPR0:
6476 return Error(Loc,
"expected register without element width suffix");
6477 case Match_InvalidZPR8:
6478 case Match_InvalidZPR16:
6479 case Match_InvalidZPR32:
6480 case Match_InvalidZPR64:
6481 case Match_InvalidZPR128:
6482 return Error(Loc,
"invalid element width");
6483 case Match_InvalidZPR_3b8:
6484 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6485 case Match_InvalidZPR_3b16:
6486 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6487 case Match_InvalidZPR_3b32:
6488 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6489 case Match_InvalidZPR_4b8:
6491 "Invalid restricted vector register, expected z0.b..z15.b");
6492 case Match_InvalidZPR_4b16:
6493 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6494 case Match_InvalidZPR_4b32:
6495 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6496 case Match_InvalidZPR_4b64:
6497 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6498 case Match_InvalidZPRMul2_Lo8:
6499 return Error(Loc,
"Invalid restricted vector register, expected even "
6500 "register in z0.b..z14.b");
6501 case Match_InvalidZPRMul2_Hi8:
6502 return Error(Loc,
"Invalid restricted vector register, expected even "
6503 "register in z16.b..z30.b");
6504 case Match_InvalidZPRMul2_Lo16:
6505 return Error(Loc,
"Invalid restricted vector register, expected even "
6506 "register in z0.h..z14.h");
6507 case Match_InvalidZPRMul2_Hi16:
6508 return Error(Loc,
"Invalid restricted vector register, expected even "
6509 "register in z16.h..z30.h");
6510 case Match_InvalidZPRMul2_Lo32:
6511 return Error(Loc,
"Invalid restricted vector register, expected even "
6512 "register in z0.s..z14.s");
6513 case Match_InvalidZPRMul2_Hi32:
6514 return Error(Loc,
"Invalid restricted vector register, expected even "
6515 "register in z16.s..z30.s");
6516 case Match_InvalidZPRMul2_Lo64:
6517 return Error(Loc,
"Invalid restricted vector register, expected even "
6518 "register in z0.d..z14.d");
6519 case Match_InvalidZPRMul2_Hi64:
6520 return Error(Loc,
"Invalid restricted vector register, expected even "
6521 "register in z16.d..z30.d");
6522 case Match_InvalidZPR_K0:
6523 return Error(Loc,
"invalid restricted vector register, expected register "
6524 "in z20..z23 or z28..z31");
6525 case Match_InvalidSVEPattern:
6526 return Error(Loc,
"invalid predicate pattern");
6527 case Match_InvalidSVEPPRorPNRAnyReg:
6528 case Match_InvalidSVEPPRorPNRBReg:
6529 case Match_InvalidSVEPredicateAnyReg:
6530 case Match_InvalidSVEPredicateBReg:
6531 case Match_InvalidSVEPredicateHReg:
6532 case Match_InvalidSVEPredicateSReg:
6533 case Match_InvalidSVEPredicateDReg:
6534 return Error(Loc,
"invalid predicate register.");
6535 case Match_InvalidSVEPredicate3bAnyReg:
6536 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6537 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6538 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6539 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6540 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6541 return Error(Loc,
"Invalid predicate register, expected PN in range "
6542 "pn8..pn15 with element suffix.");
6543 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6544 return Error(Loc,
"invalid restricted predicate-as-counter register "
6545 "expected pn8..pn15");
6546 case Match_InvalidSVEPNPredicateBReg:
6547 case Match_InvalidSVEPNPredicateHReg:
6548 case Match_InvalidSVEPNPredicateSReg:
6549 case Match_InvalidSVEPNPredicateDReg:
6550 return Error(Loc,
"Invalid predicate register, expected PN in range "
6551 "pn0..pn15 with element suffix.");
6552 case Match_InvalidSVEVecLenSpecifier:
6553 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6554 case Match_InvalidSVEPredicateListMul2x8:
6555 case Match_InvalidSVEPredicateListMul2x16:
6556 case Match_InvalidSVEPredicateListMul2x32:
6557 case Match_InvalidSVEPredicateListMul2x64:
6558 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6559 "predicate registers, where the first vector is a multiple of 2 "
6560 "and with correct element type");
6561 case Match_InvalidSVEExactFPImmOperandHalfOne:
6562 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6563 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6564 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6565 case Match_InvalidSVEExactFPImmOperandZeroOne:
6566 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6567 case Match_InvalidMatrixTileVectorH8:
6568 case Match_InvalidMatrixTileVectorV8:
6569 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6570 case Match_InvalidMatrixTileVectorH16:
6571 case Match_InvalidMatrixTileVectorV16:
6573 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6574 case Match_InvalidMatrixTileVectorH32:
6575 case Match_InvalidMatrixTileVectorV32:
6577 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6578 case Match_InvalidMatrixTileVectorH64:
6579 case Match_InvalidMatrixTileVectorV64:
6581 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6582 case Match_InvalidMatrixTileVectorH128:
6583 case Match_InvalidMatrixTileVectorV128:
6585 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6586 case Match_InvalidMatrixTile16:
6587 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6588 case Match_InvalidMatrixTile32:
6589 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6590 case Match_InvalidMatrixTile64:
6591 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6592 case Match_InvalidMatrix:
6593 return Error(Loc,
"invalid matrix operand, expected za");
6594 case Match_InvalidMatrix8:
6595 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6596 case Match_InvalidMatrix16:
6597 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6598 case Match_InvalidMatrix32:
6599 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6600 case Match_InvalidMatrix64:
6601 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6602 case Match_InvalidMatrixIndexGPR32_12_15:
6603 return Error(Loc,
"operand must be a register in range [w12, w15]");
6604 case Match_InvalidMatrixIndexGPR32_8_11:
6605 return Error(Loc,
"operand must be a register in range [w8, w11]");
6606 case Match_InvalidSVEVectorList2x8Mul2:
6607 case Match_InvalidSVEVectorList2x16Mul2:
6608 case Match_InvalidSVEVectorList2x32Mul2:
6609 case Match_InvalidSVEVectorList2x64Mul2:
6610 case Match_InvalidSVEVectorList2x128Mul2:
6611 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6612 "SVE vectors, where the first vector is a multiple of 2 "
6613 "and with matching element types");
6614 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6615 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6616 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6617 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6618 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6619 "SVE vectors in the range z0-z14, where the first vector "
6620 "is a multiple of 2 "
6621 "and with matching element types");
6622 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6623 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6624 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6625 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6627 "Invalid vector list, expected list with 2 consecutive "
6628 "SVE vectors in the range z16-z30, where the first vector "
6629 "is a multiple of 2 "
6630 "and with matching element types");
6631 case Match_InvalidSVEVectorList4x8Mul4:
6632 case Match_InvalidSVEVectorList4x16Mul4:
6633 case Match_InvalidSVEVectorList4x32Mul4:
6634 case Match_InvalidSVEVectorList4x64Mul4:
6635 case Match_InvalidSVEVectorList4x128Mul4:
6636 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6637 "SVE vectors, where the first vector is a multiple of 4 "
6638 "and with matching element types");
6639 case Match_InvalidLookupTable:
6640 return Error(Loc,
"Invalid lookup table, expected zt0");
6641 case Match_InvalidSVEVectorListStrided2x8:
6642 case Match_InvalidSVEVectorListStrided2x16:
6643 case Match_InvalidSVEVectorListStrided2x32:
6644 case Match_InvalidSVEVectorListStrided2x64:
6647 "Invalid vector list, expected list with each SVE vector in the list "
6648 "8 registers apart, and the first register in the range [z0, z7] or "
6649 "[z16, z23] and with correct element type");
6650 case Match_InvalidSVEVectorListStrided4x8:
6651 case Match_InvalidSVEVectorListStrided4x16:
6652 case Match_InvalidSVEVectorListStrided4x32:
6653 case Match_InvalidSVEVectorListStrided4x64:
6656 "Invalid vector list, expected list with each SVE vector in the list "
6657 "4 registers apart, and the first register in the range [z0, z3] or "
6658 "[z16, z19] and with correct element type");
6659 case Match_AddSubLSLImm3ShiftLarge:
6661 "expected 'lsl' with optional integer in range [0, 7]");
6669bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6673 bool MatchingInlineAsm) {
6674 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6675 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6676 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6679 unsigned NumOperands = Operands.
size();
6681 if (NumOperands == 4 && Tok ==
"lsl") {
6682 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6683 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6684 if (Op2.isScalarReg() && Op3.isImm()) {
6690 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6692 NewOp3Val = (32 - Op3Val) & 0x1f;
6693 NewOp4Val = 31 - Op3Val;
6695 NewOp3Val = (64 - Op3Val) & 0x3f;
6696 NewOp4Val = 63 - Op3Val;
6703 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6704 Operands.
push_back(AArch64Operand::CreateImm(
6705 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6706 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6710 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6712 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6713 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6714 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6716 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6720 if (LSBCE && WidthCE) {
6722 uint64_t Width = WidthCE->
getValue();
6724 uint64_t RegWidth = 0;
6725 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6731 if (LSB >= RegWidth)
6732 return Error(LSBOp.getStartLoc(),
6733 "expected integer in range [0, 31]");
6734 if (Width < 1 || Width > RegWidth)
6735 return Error(WidthOp.getStartLoc(),
6736 "expected integer in range [1, 32]");
6740 ImmR = (32 - LSB) & 0x1f;
6742 ImmR = (64 - LSB) & 0x3f;
6744 uint64_t ImmS = Width - 1;
6746 if (ImmR != 0 && ImmS >= ImmR)
6747 return Error(WidthOp.getStartLoc(),
6748 "requested insert overflows register");
6753 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6754 Operands[2] = AArch64Operand::CreateReg(
6755 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6757 Operands[3] = AArch64Operand::CreateImm(
6758 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6760 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6764 }
else if (NumOperands == 5) {
6767 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6768 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6769 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6770 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6772 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6776 if (Op3CE && Op4CE) {
6777 uint64_t Op3Val = Op3CE->
getValue();
6778 uint64_t Op4Val = Op4CE->
getValue();
6780 uint64_t RegWidth = 0;
6781 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6787 if (Op3Val >= RegWidth)
6788 return Error(Op3.getStartLoc(),
6789 "expected integer in range [0, 31]");
6790 if (Op4Val < 1 || Op4Val > RegWidth)
6791 return Error(Op4.getStartLoc(),
6792 "expected integer in range [1, 32]");
6794 uint64_t NewOp3Val = 0;
6796 NewOp3Val = (32 - Op3Val) & 0x1f;
6798 NewOp3Val = (64 - Op3Val) & 0x3f;
6800 uint64_t NewOp4Val = Op4Val - 1;
6802 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6803 return Error(Op4.getStartLoc(),
6804 "requested insert overflows register");
6806 const MCExpr *NewOp3 =
6808 const MCExpr *NewOp4 =
6810 Operands[3] = AArch64Operand::CreateImm(
6811 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6812 Operands[4] = AArch64Operand::CreateImm(
6813 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6815 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6817 else if (Tok ==
"sbfiz")
6818 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6820 else if (Tok ==
"ubfiz")
6821 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6830 }
else if (NumOperands == 5 &&
6831 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6832 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6833 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6834 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6836 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6840 if (Op3CE && Op4CE) {
6841 uint64_t Op3Val = Op3CE->
getValue();
6842 uint64_t Op4Val = Op4CE->
getValue();
6844 uint64_t RegWidth = 0;
6845 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6851 if (Op3Val >= RegWidth)
6852 return Error(Op3.getStartLoc(),
6853 "expected integer in range [0, 31]");
6854 if (Op4Val < 1 || Op4Val > RegWidth)
6855 return Error(Op4.getStartLoc(),
6856 "expected integer in range [1, 32]");
6858 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6860 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6861 return Error(Op4.getStartLoc(),
6862 "requested extract overflows register");
6864 const MCExpr *NewOp4 =
6866 Operands[4] = AArch64Operand::CreateImm(
6867 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6869 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6871 else if (Tok ==
"sbfx")
6872 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6874 else if (Tok ==
"ubfx")
6875 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6888 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6889 NumOperands == 4 && Tok ==
"movi") {
6890 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6891 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6892 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6893 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6894 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6895 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6896 if (Suffix.
lower() ==
".2d" &&
6898 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6899 " correctly on this CPU, converting to equivalent movi.16b");
6901 unsigned Idx = Op1.isToken() ? 1 : 2;
6903 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6911 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6914 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6915 if (
Op.isScalarReg()) {
6917 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6918 Op.getStartLoc(),
Op.getEndLoc(),
6923 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6924 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6925 if (
Op.isScalarReg() &&
6926 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6930 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6931 if (
Op.isScalarReg()) {
6933 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6940 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6941 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6942 if (
Op.isScalarReg() &&
6943 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6947 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6948 if (
Op.isScalarReg()) {
6950 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6958 FeatureBitset MissingFeatures;
6961 unsigned MatchResult =
6962 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6963 MatchingInlineAsm, 1);
6967 if (MatchResult != Match_Success) {
6970 auto ShortFormNEONErrorInfo = ErrorInfo;
6971 auto ShortFormNEONMatchResult = MatchResult;
6972 auto ShortFormNEONMissingFeatures = MissingFeatures;
6975 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6976 MatchingInlineAsm, 0);
6981 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6982 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6983 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6984 MatchResult = ShortFormNEONMatchResult;
6985 ErrorInfo = ShortFormNEONErrorInfo;
6986 MissingFeatures = ShortFormNEONMissingFeatures;
6990 switch (MatchResult) {
6991 case Match_Success: {
6994 NumOperands = Operands.
size();
6995 for (
unsigned i = 1; i < NumOperands; ++i)
6996 OperandLocs.
push_back(Operands[i]->getStartLoc());
6997 if (validateInstruction(Inst, IDLoc, OperandLocs))
7004 case Match_MissingFeature: {
7005 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
7008 std::string Msg =
"instruction requires:";
7009 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
7010 if (MissingFeatures[i]) {
7015 return Error(IDLoc, Msg);
7017 case Match_MnemonicFail:
7018 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
7019 case Match_InvalidOperand: {
7020 SMLoc ErrorLoc = IDLoc;
7022 if (ErrorInfo != ~0ULL) {
7023 if (ErrorInfo >= Operands.
size())
7024 return Error(IDLoc,
"too few operands for instruction",
7025 SMRange(IDLoc, getTok().getLoc()));
7027 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7028 if (ErrorLoc == SMLoc())
7033 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
7034 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
7035 MatchResult = Match_InvalidSuffix;
7037 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7039 case Match_InvalidTiedOperand:
7040 case Match_InvalidMemoryIndexed1:
7041 case Match_InvalidMemoryIndexed2:
7042 case Match_InvalidMemoryIndexed4:
7043 case Match_InvalidMemoryIndexed8:
7044 case Match_InvalidMemoryIndexed16:
7045 case Match_InvalidCondCode:
7046 case Match_AddSubLSLImm3ShiftLarge:
7047 case Match_AddSubRegExtendSmall:
7048 case Match_AddSubRegExtendLarge:
7049 case Match_AddSubSecondSource:
7050 case Match_LogicalSecondSource:
7051 case Match_AddSubRegShift32:
7052 case Match_AddSubRegShift64:
7053 case Match_InvalidMovImm32Shift:
7054 case Match_InvalidMovImm64Shift:
7055 case Match_InvalidFPImm:
7056 case Match_InvalidMemoryWExtend8:
7057 case Match_InvalidMemoryWExtend16:
7058 case Match_InvalidMemoryWExtend32:
7059 case Match_InvalidMemoryWExtend64:
7060 case Match_InvalidMemoryWExtend128:
7061 case Match_InvalidMemoryXExtend8:
7062 case Match_InvalidMemoryXExtend16:
7063 case Match_InvalidMemoryXExtend32:
7064 case Match_InvalidMemoryXExtend64:
7065 case Match_InvalidMemoryXExtend128:
7066 case Match_InvalidMemoryIndexed1SImm4:
7067 case Match_InvalidMemoryIndexed2SImm4:
7068 case Match_InvalidMemoryIndexed3SImm4:
7069 case Match_InvalidMemoryIndexed4SImm4:
7070 case Match_InvalidMemoryIndexed1SImm6:
7071 case Match_InvalidMemoryIndexed16SImm4:
7072 case Match_InvalidMemoryIndexed32SImm4:
7073 case Match_InvalidMemoryIndexed4SImm7:
7074 case Match_InvalidMemoryIndexed8SImm7:
7075 case Match_InvalidMemoryIndexed16SImm7:
7076 case Match_InvalidMemoryIndexed8UImm5:
7077 case Match_InvalidMemoryIndexed8UImm3:
7078 case Match_InvalidMemoryIndexed4UImm5:
7079 case Match_InvalidMemoryIndexed2UImm5:
7080 case Match_InvalidMemoryIndexed1UImm6:
7081 case Match_InvalidMemoryIndexed2UImm6:
7082 case Match_InvalidMemoryIndexed4UImm6:
7083 case Match_InvalidMemoryIndexed8UImm6:
7084 case Match_InvalidMemoryIndexed16UImm6:
7085 case Match_InvalidMemoryIndexedSImm6:
7086 case Match_InvalidMemoryIndexedSImm5:
7087 case Match_InvalidMemoryIndexedSImm8:
7088 case Match_InvalidMemoryIndexedSImm9:
7089 case Match_InvalidMemoryIndexed16SImm9:
7090 case Match_InvalidMemoryIndexed8SImm10:
7091 case Match_InvalidImm0_0:
7092 case Match_InvalidImm0_1:
7093 case Match_InvalidImm0_3:
7094 case Match_InvalidImm0_7:
7095 case Match_InvalidImm0_15:
7096 case Match_InvalidImm0_31:
7097 case Match_InvalidImm0_63:
7098 case Match_InvalidImm0_127:
7099 case Match_InvalidImm0_255:
7100 case Match_InvalidImm0_65535:
7101 case Match_InvalidImm1_8:
7102 case Match_InvalidImm1_16:
7103 case Match_InvalidImm1_32:
7104 case Match_InvalidImm1_64:
7105 case Match_InvalidImmM1_62:
7106 case Match_InvalidMemoryIndexedRange2UImm0:
7107 case Match_InvalidMemoryIndexedRange2UImm1:
7108 case Match_InvalidMemoryIndexedRange2UImm2:
7109 case Match_InvalidMemoryIndexedRange2UImm3:
7110 case Match_InvalidMemoryIndexedRange4UImm0:
7111 case Match_InvalidMemoryIndexedRange4UImm1:
7112 case Match_InvalidMemoryIndexedRange4UImm2:
7113 case Match_InvalidSVEAddSubImm8:
7114 case Match_InvalidSVEAddSubImm16:
7115 case Match_InvalidSVEAddSubImm32:
7116 case Match_InvalidSVEAddSubImm64:
7117 case Match_InvalidSVECpyImm8:
7118 case Match_InvalidSVECpyImm16:
7119 case Match_InvalidSVECpyImm32:
7120 case Match_InvalidSVECpyImm64:
7121 case Match_InvalidIndexRange0_0:
7122 case Match_InvalidIndexRange1_1:
7123 case Match_InvalidIndexRange0_15:
7124 case Match_InvalidIndexRange0_7:
7125 case Match_InvalidIndexRange0_3:
7126 case Match_InvalidIndexRange0_1:
7127 case Match_InvalidSVEIndexRange0_63:
7128 case Match_InvalidSVEIndexRange0_31:
7129 case Match_InvalidSVEIndexRange0_15:
7130 case Match_InvalidSVEIndexRange0_7:
7131 case Match_InvalidSVEIndexRange0_3:
7132 case Match_InvalidLabel:
7133 case Match_InvalidComplexRotationEven:
7134 case Match_InvalidComplexRotationOdd:
7135 case Match_InvalidGPR64shifted8:
7136 case Match_InvalidGPR64shifted16:
7137 case Match_InvalidGPR64shifted32:
7138 case Match_InvalidGPR64shifted64:
7139 case Match_InvalidGPR64shifted128:
7140 case Match_InvalidGPR64NoXZRshifted8:
7141 case Match_InvalidGPR64NoXZRshifted16:
7142 case Match_InvalidGPR64NoXZRshifted32:
7143 case Match_InvalidGPR64NoXZRshifted64:
7144 case Match_InvalidGPR64NoXZRshifted128:
7145 case Match_InvalidZPR32UXTW8:
7146 case Match_InvalidZPR32UXTW16:
7147 case Match_InvalidZPR32UXTW32:
7148 case Match_InvalidZPR32UXTW64:
7149 case Match_InvalidZPR32SXTW8:
7150 case Match_InvalidZPR32SXTW16:
7151 case Match_InvalidZPR32SXTW32:
7152 case Match_InvalidZPR32SXTW64:
7153 case Match_InvalidZPR64UXTW8:
7154 case Match_InvalidZPR64SXTW8:
7155 case Match_InvalidZPR64UXTW16:
7156 case Match_InvalidZPR64SXTW16:
7157 case Match_InvalidZPR64UXTW32:
7158 case Match_InvalidZPR64SXTW32:
7159 case Match_InvalidZPR64UXTW64:
7160 case Match_InvalidZPR64SXTW64:
7161 case Match_InvalidZPR32LSL8:
7162 case Match_InvalidZPR32LSL16:
7163 case Match_InvalidZPR32LSL32:
7164 case Match_InvalidZPR32LSL64:
7165 case Match_InvalidZPR64LSL8:
7166 case Match_InvalidZPR64LSL16:
7167 case Match_InvalidZPR64LSL32:
7168 case Match_InvalidZPR64LSL64:
7169 case Match_InvalidZPR0:
7170 case Match_InvalidZPR8:
7171 case Match_InvalidZPR16:
7172 case Match_InvalidZPR32:
7173 case Match_InvalidZPR64:
7174 case Match_InvalidZPR128:
7175 case Match_InvalidZPR_3b8:
7176 case Match_InvalidZPR_3b16:
7177 case Match_InvalidZPR_3b32:
7178 case Match_InvalidZPR_4b8:
7179 case Match_InvalidZPR_4b16:
7180 case Match_InvalidZPR_4b32:
7181 case Match_InvalidZPR_4b64:
7182 case Match_InvalidSVEPPRorPNRAnyReg:
7183 case Match_InvalidSVEPPRorPNRBReg:
7184 case Match_InvalidSVEPredicateAnyReg:
7185 case Match_InvalidSVEPattern:
7186 case Match_InvalidSVEVecLenSpecifier:
7187 case Match_InvalidSVEPredicateBReg:
7188 case Match_InvalidSVEPredicateHReg:
7189 case Match_InvalidSVEPredicateSReg:
7190 case Match_InvalidSVEPredicateDReg:
7191 case Match_InvalidSVEPredicate3bAnyReg:
7192 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7193 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7194 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7195 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7196 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7197 case Match_InvalidSVEPNPredicateBReg:
7198 case Match_InvalidSVEPNPredicateHReg:
7199 case Match_InvalidSVEPNPredicateSReg:
7200 case Match_InvalidSVEPNPredicateDReg:
7201 case Match_InvalidSVEPredicateListMul2x8:
7202 case Match_InvalidSVEPredicateListMul2x16:
7203 case Match_InvalidSVEPredicateListMul2x32:
7204 case Match_InvalidSVEPredicateListMul2x64:
7205 case Match_InvalidSVEExactFPImmOperandHalfOne:
7206 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7207 case Match_InvalidSVEExactFPImmOperandZeroOne:
7208 case Match_InvalidMatrixTile16:
7209 case Match_InvalidMatrixTile32:
7210 case Match_InvalidMatrixTile64:
7211 case Match_InvalidMatrix:
7212 case Match_InvalidMatrix8:
7213 case Match_InvalidMatrix16:
7214 case Match_InvalidMatrix32:
7215 case Match_InvalidMatrix64:
7216 case Match_InvalidMatrixTileVectorH8:
7217 case Match_InvalidMatrixTileVectorH16:
7218 case Match_InvalidMatrixTileVectorH32:
7219 case Match_InvalidMatrixTileVectorH64:
7220 case Match_InvalidMatrixTileVectorH128:
7221 case Match_InvalidMatrixTileVectorV8:
7222 case Match_InvalidMatrixTileVectorV16:
7223 case Match_InvalidMatrixTileVectorV32:
7224 case Match_InvalidMatrixTileVectorV64:
7225 case Match_InvalidMatrixTileVectorV128:
7226 case Match_InvalidSVCR:
7227 case Match_InvalidMatrixIndexGPR32_12_15:
7228 case Match_InvalidMatrixIndexGPR32_8_11:
7229 case Match_InvalidLookupTable:
7230 case Match_InvalidZPRMul2_Lo8:
7231 case Match_InvalidZPRMul2_Hi8:
7232 case Match_InvalidZPRMul2_Lo16:
7233 case Match_InvalidZPRMul2_Hi16:
7234 case Match_InvalidZPRMul2_Lo32:
7235 case Match_InvalidZPRMul2_Hi32:
7236 case Match_InvalidZPRMul2_Lo64:
7237 case Match_InvalidZPRMul2_Hi64:
7238 case Match_InvalidZPR_K0:
7239 case Match_InvalidSVEVectorList2x8Mul2:
7240 case Match_InvalidSVEVectorList2x16Mul2:
7241 case Match_InvalidSVEVectorList2x32Mul2:
7242 case Match_InvalidSVEVectorList2x64Mul2:
7243 case Match_InvalidSVEVectorList2x128Mul2:
7244 case Match_InvalidSVEVectorList4x8Mul4:
7245 case Match_InvalidSVEVectorList4x16Mul4:
7246 case Match_InvalidSVEVectorList4x32Mul4:
7247 case Match_InvalidSVEVectorList4x64Mul4:
7248 case Match_InvalidSVEVectorList4x128Mul4:
7249 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7250 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7251 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7252 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7253 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7254 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7255 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7256 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7257 case Match_InvalidSVEVectorListStrided2x8:
7258 case Match_InvalidSVEVectorListStrided2x16:
7259 case Match_InvalidSVEVectorListStrided2x32:
7260 case Match_InvalidSVEVectorListStrided2x64:
7261 case Match_InvalidSVEVectorListStrided4x8:
7262 case Match_InvalidSVEVectorListStrided4x16:
7263 case Match_InvalidSVEVectorListStrided4x32:
7264 case Match_InvalidSVEVectorListStrided4x64:
7267 if (ErrorInfo >= Operands.
size())
7268 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7271 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7272 if (ErrorLoc == SMLoc())
7274 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7282bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7289 SMLoc Loc = DirectiveID.
getLoc();
7290 if (IDVal ==
".arch")
7291 parseDirectiveArch(Loc);
7292 else if (IDVal ==
".cpu")
7293 parseDirectiveCPU(Loc);
7294 else if (IDVal ==
".tlsdesccall")
7295 parseDirectiveTLSDescCall(Loc);
7296 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7297 parseDirectiveLtorg(Loc);
7298 else if (IDVal ==
".unreq")
7299 parseDirectiveUnreq(Loc);
7300 else if (IDVal ==
".inst")
7301 parseDirectiveInst(Loc);
7302 else if (IDVal ==
".cfi_negate_ra_state")
7303 parseDirectiveCFINegateRAState();
7304 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7305 parseDirectiveCFINegateRAStateWithPC();
7306 else if (IDVal ==
".cfi_b_key_frame")
7307 parseDirectiveCFIBKeyFrame();
7308 else if (IDVal ==
".cfi_mte_tagged_frame")
7309 parseDirectiveCFIMTETaggedFrame();
7310 else if (IDVal ==
".arch_extension")
7311 parseDirectiveArchExtension(Loc);
7312 else if (IDVal ==
".variant_pcs")
7313 parseDirectiveVariantPCS(Loc);
7316 parseDirectiveLOH(IDVal, Loc);
7319 }
else if (IsCOFF) {
7320 if (IDVal ==
".seh_stackalloc")
7321 parseDirectiveSEHAllocStack(Loc);
7322 else if (IDVal ==
".seh_endprologue")
7323 parseDirectiveSEHPrologEnd(Loc);
7324 else if (IDVal ==
".seh_save_r19r20_x")
7325 parseDirectiveSEHSaveR19R20X(Loc);
7326 else if (IDVal ==
".seh_save_fplr")
7327 parseDirectiveSEHSaveFPLR(Loc);
7328 else if (IDVal ==
".seh_save_fplr_x")
7329 parseDirectiveSEHSaveFPLRX(Loc);
7330 else if (IDVal ==
".seh_save_reg")
7331 parseDirectiveSEHSaveReg(Loc);
7332 else if (IDVal ==
".seh_save_reg_x")
7333 parseDirectiveSEHSaveRegX(Loc);
7334 else if (IDVal ==
".seh_save_regp")
7335 parseDirectiveSEHSaveRegP(Loc);
7336 else if (IDVal ==
".seh_save_regp_x")
7337 parseDirectiveSEHSaveRegPX(Loc);
7338 else if (IDVal ==
".seh_save_lrpair")
7339 parseDirectiveSEHSaveLRPair(Loc);
7340 else if (IDVal ==
".seh_save_freg")
7341 parseDirectiveSEHSaveFReg(Loc);
7342 else if (IDVal ==
".seh_save_freg_x")
7343 parseDirectiveSEHSaveFRegX(Loc);
7344 else if (IDVal ==
".seh_save_fregp")
7345 parseDirectiveSEHSaveFRegP(Loc);
7346 else if (IDVal ==
".seh_save_fregp_x")
7347 parseDirectiveSEHSaveFRegPX(Loc);
7348 else if (IDVal ==
".seh_set_fp")
7349 parseDirectiveSEHSetFP(Loc);
7350 else if (IDVal ==
".seh_add_fp")
7351 parseDirectiveSEHAddFP(Loc);
7352 else if (IDVal ==
".seh_nop")
7353 parseDirectiveSEHNop(Loc);
7354 else if (IDVal ==
".seh_save_next")
7355 parseDirectiveSEHSaveNext(Loc);
7356 else if (IDVal ==
".seh_startepilogue")
7357 parseDirectiveSEHEpilogStart(Loc);
7358 else if (IDVal ==
".seh_endepilogue")
7359 parseDirectiveSEHEpilogEnd(Loc);
7360 else if (IDVal ==
".seh_trap_frame")
7361 parseDirectiveSEHTrapFrame(Loc);
7362 else if (IDVal ==
".seh_pushframe")
7363 parseDirectiveSEHMachineFrame(Loc);
7364 else if (IDVal ==
".seh_context")
7365 parseDirectiveSEHContext(Loc);
7366 else if (IDVal ==
".seh_ec_context")
7367 parseDirectiveSEHECContext(Loc);
7368 else if (IDVal ==
".seh_clear_unwound_to_call")
7369 parseDirectiveSEHClearUnwoundToCall(Loc);
7370 else if (IDVal ==
".seh_pac_sign_lr")
7371 parseDirectiveSEHPACSignLR(Loc);
7372 else if (IDVal ==
".seh_save_any_reg")
7373 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7374 else if (IDVal ==
".seh_save_any_reg_p")
7375 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7376 else if (IDVal ==
".seh_save_any_reg_x")
7377 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7378 else if (IDVal ==
".seh_save_any_reg_px")
7379 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7380 else if (IDVal ==
".seh_allocz")
7381 parseDirectiveSEHAllocZ(Loc);
7382 else if (IDVal ==
".seh_save_zreg")
7383 parseDirectiveSEHSaveZReg(Loc);
7384 else if (IDVal ==
".seh_save_preg")
7385 parseDirectiveSEHSavePReg(Loc);
7389 if (IDVal ==
".aeabi_subsection")
7390 parseDirectiveAeabiSubSectionHeader(Loc);
7391 else if (IDVal ==
".aeabi_attribute")
7392 parseDirectiveAeabiAArch64Attr(Loc);
7405 if (!NoCrypto && Crypto) {
7408 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7409 ArchInfo == AArch64::ARMV8_3A) {
7413 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7414 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7415 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7416 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7417 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7418 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7424 }
else if (NoCrypto) {
7427 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7428 ArchInfo == AArch64::ARMV8_3A) {
7429 RequestedExtensions.
push_back(
"nosha2");
7432 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7433 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7434 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7435 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7436 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7437 ArchInfo == AArch64::ARMV9_4A) {
7439 RequestedExtensions.
push_back(
"nosha3");
7440 RequestedExtensions.
push_back(
"nosha2");
7452bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7453 SMLoc CurLoc = getLoc();
7455 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7456 StringRef Arch, ExtensionString;
7457 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7461 return Error(CurLoc,
"unknown arch name");
7467 std::vector<StringRef> AArch64Features;
7471 MCSubtargetInfo &STI = copySTI();
7472 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7474 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7477 if (!ExtensionString.
empty())
7478 ExtensionString.
split(RequestedExtensions,
'+');
7483 for (
auto Name : RequestedExtensions) {
7487 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7494 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7502 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7503 setAvailableFeatures(Features);
7505 getTargetStreamer().emitDirectiveArch(Name);
7511bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7512 SMLoc ExtLoc = getLoc();
7514 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7519 bool EnableFeature =
true;
7520 StringRef
Name = FullName;
7521 if (
Name.starts_with_insensitive(
"no")) {
7522 EnableFeature =
false;
7531 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7533 MCSubtargetInfo &STI = copySTI();
7538 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7539 setAvailableFeatures(Features);
7541 getTargetStreamer().emitDirectiveArchExtension(FullName);
7547bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7548 SMLoc CurLoc = getLoc();
7550 StringRef CPU, ExtensionString;
7551 std::tie(CPU, ExtensionString) =
7552 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7558 if (!ExtensionString.
empty())
7559 ExtensionString.
split(RequestedExtensions,
'+');
7563 Error(CurLoc,
"unknown CPU name");
7568 MCSubtargetInfo &STI = copySTI();
7572 for (
auto Name : RequestedExtensions) {
7576 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7583 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7591 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7592 setAvailableFeatures(Features);
7598bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7600 return Error(Loc,
"expected expression following '.inst' directive");
7602 auto parseOp = [&]() ->
bool {
7604 const MCExpr *Expr =
nullptr;
7605 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7608 if (check(!
Value, L,
"expected constant expression"))
7610 getTargetStreamer().emitInst(
Value->getValue());
7614 return parseMany(parseOp);
7619bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7621 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7633 getParser().getStreamer().emitInstruction(Inst, getSTI());
7639bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7643 return TokError(
"expected an identifier or a number in directive");
7646 int64_t
Id = getTok().getIntVal();
7648 return TokError(
"invalid numeric identifier in directive");
7651 StringRef
Name = getTok().getIdentifier();
7657 return TokError(
"invalid identifier in directive");
7665 assert(NbArgs != -1 &&
"Invalid number of arguments");
7668 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7670 if (getParser().parseIdentifier(Name))
7671 return TokError(
"expected identifier in directive");
7674 if (Idx + 1 == NbArgs)
7682 getStreamer().emitLOHDirective(Kind, Args);
7688bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7691 getTargetStreamer().emitCurrentConstantPool();
7697bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7699 SMLoc SRegLoc = getLoc();
7700 RegKind RegisterKind = RegKind::Scalar;
7702 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7706 RegisterKind = RegKind::NeonVector;
7707 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7713 return Error(SRegLoc,
"vector register without type specifier expected");
7718 RegisterKind = RegKind::SVEDataVector;
7720 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7726 return Error(SRegLoc,
7727 "sve vector register without type specifier expected");
7732 RegisterKind = RegKind::SVEPredicateVector;
7733 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7739 return Error(SRegLoc,
7740 "sve predicate register without type specifier expected");
7744 return Error(SRegLoc,
"register name or alias expected");
7750 auto pair = std::make_pair(RegisterKind, RegNum);
7751 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7752 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7759bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7761 return TokError(
"unexpected input in .unreq directive.");
7762 RegisterReqs.
erase(getTok().getIdentifier().lower());
7767bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7770 getStreamer().emitCFINegateRAState();
7774bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7777 getStreamer().emitCFINegateRAStateWithPC();
7783bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7786 getStreamer().emitCFIBKeyFrame();
7792bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7795 getStreamer().emitCFIMTETaggedFrame();
7801bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7803 if (getParser().parseIdentifier(Name))
7804 return TokError(
"expected symbol name");
7807 getTargetStreamer().emitDirectiveVariantPCS(
7814bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7816 if (parseImmExpr(
Size))
7818 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7824bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7825 getTargetStreamer().emitARM64WinCFIPrologEnd();
7831bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7833 if (parseImmExpr(
Offset))
7835 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7841bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7843 if (parseImmExpr(
Offset))
7845 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7851bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7853 if (parseImmExpr(
Offset))
7855 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7861bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7864 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7865 parseComma() || parseImmExpr(
Offset))
7867 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7873bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7876 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7877 parseComma() || parseImmExpr(
Offset))
7879 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7885bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7888 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7889 parseComma() || parseImmExpr(
Offset))
7891 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7897bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7900 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7901 parseComma() || parseImmExpr(
Offset))
7903 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7909bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7913 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7914 parseComma() || parseImmExpr(
Offset))
7916 if (check(((
Reg - 19) % 2 != 0), L,
7917 "expected register with even offset from x19"))
7919 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7925bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7928 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7929 parseComma() || parseImmExpr(
Offset))
7931 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7937bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7940 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7941 parseComma() || parseImmExpr(
Offset))
7943 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7949bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7952 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7953 parseComma() || parseImmExpr(
Offset))
7955 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7961bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7964 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7965 parseComma() || parseImmExpr(
Offset))
7967 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7973bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7974 getTargetStreamer().emitARM64WinCFISetFP();
7980bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7982 if (parseImmExpr(
Size))
7984 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7990bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7991 getTargetStreamer().emitARM64WinCFINop();
7997bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7998 getTargetStreamer().emitARM64WinCFISaveNext();
8004bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
8005 getTargetStreamer().emitARM64WinCFIEpilogStart();
8011bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
8012 getTargetStreamer().emitARM64WinCFIEpilogEnd();
8018bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
8019 getTargetStreamer().emitARM64WinCFITrapFrame();
8025bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
8026 getTargetStreamer().emitARM64WinCFIMachineFrame();
8032bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
8033 getTargetStreamer().emitARM64WinCFIContext();
8039bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
8040 getTargetStreamer().emitARM64WinCFIECContext();
8046bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
8047 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
8053bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
8054 getTargetStreamer().emitARM64WinCFIPACSignLR();
8063bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
8068 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
8069 parseComma() || parseImmExpr(
Offset))
8072 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
8073 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
8074 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8075 return Error(L,
"invalid save_any_reg offset");
8076 unsigned EncodedReg;
8077 if (
Reg == AArch64::FP)
8079 else if (
Reg == AArch64::LR)
8082 EncodedReg =
Reg - AArch64::X0;
8084 if (
Reg == AArch64::LR)
8085 return Error(Start,
"lr cannot be paired with another register");
8087 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
8089 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
8092 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
8094 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
8096 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
8097 unsigned EncodedReg =
Reg - AArch64::D0;
8098 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
8099 return Error(L,
"invalid save_any_reg offset");
8101 if (
Reg == AArch64::D31)
8102 return Error(Start,
"d31 cannot be paired with another register");
8104 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
8106 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
8109 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
8111 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
8113 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
8114 unsigned EncodedReg =
Reg - AArch64::Q0;
8116 return Error(L,
"invalid save_any_reg offset");
8118 if (
Reg == AArch64::Q31)
8119 return Error(Start,
"q31 cannot be paired with another register");
8121 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
8123 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
8126 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
8128 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
8131 return Error(Start,
"save_any_reg register must be x, q or d register");
8138bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8140 if (parseImmExpr(
Offset))
8142 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8148bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8153 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8156 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8157 "expected register in range z8 to z23"))
8159 if (parseComma() || parseImmExpr(
Offset))
8161 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8167bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8172 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8175 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8176 "expected register in range p4 to p15"))
8178 if (parseComma() || parseImmExpr(
Offset))
8180 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8184bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8190 MCAsmParser &Parser = getParser();
8193 StringRef SubsectionName;
8204 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8205 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8210 if (SubsectionExists) {
8211 getTargetStreamer().emitAttributesSubsection(
8214 SubsectionExists->IsOptional),
8216 SubsectionExists->ParameterType));
8222 "Could not switch to subsection '" + SubsectionName +
8223 "' using subsection name, subsection has not been defined");
8246 if (SubsectionExists) {
8247 if (IsOptional != SubsectionExists->IsOptional) {
8249 "optionality mismatch! subsection '" + SubsectionName +
8250 "' already exists with optionality defined as '" +
8252 SubsectionExists->IsOptional) +
8260 "optionality parameter not found, expected required|optional");
8267 "aeabi_feature_and_bits must be marked as optional");
8274 "aeabi_pauthabi must be marked as required");
8294 if (SubsectionExists) {
8295 if (
Type != SubsectionExists->ParameterType) {
8297 "type mismatch! subsection '" + SubsectionName +
8298 "' already exists with type defined as '" +
8300 SubsectionExists->ParameterType) +
8308 "type parameter not found, expected uleb128|ntbs");
8316 SubsectionName +
" must be marked as ULEB128");
8325 "attributes subsection header directive");
8329 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8334bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8338 MCAsmParser &Parser = getParser();
8340 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8341 getTargetStreamer().getActiveAttributesSubsection();
8342 if (
nullptr == ActiveSubsection) {
8344 "no active subsection, build attribute can not be added");
8347 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8348 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8356 ActiveSubsectionName)
8359 StringRef TagStr =
"";
8362 Tag = getTok().getIntVal();
8365 switch (ActiveSubsectionID) {
8370 "' \nExcept for public subsections, "
8371 "tags have to be an unsigned int.");
8378 TagStr +
"' for subsection '" +
8379 ActiveSubsectionName +
"'");
8387 TagStr +
"' for subsection '" +
8388 ActiveSubsectionName +
"'");
8406 unsigned ValueInt = unsigned(-1);
8407 std::string ValueStr =
"";
8412 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8415 ValueInt = getTok().getIntVal();
8420 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8428 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8439 if (0 != ValueInt && 1 != ValueInt) {
8441 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8442 "' options are 0|1");
8451 "unexpected token for AArch64 build attributes tag and value "
8452 "attribute directive");
8456 if (
unsigned(-1) != ValueInt) {
8457 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8459 if (
"" != ValueStr) {
8460 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8466bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8469 if (getParser().parseExpression(Res))
8471 MCAsmParser &Parser = getParser();
8475 return Error(getLoc(),
"expected relocation specifier");
8478 SMLoc Loc = getLoc();
8480 if (Identifier ==
"auth")
8481 return parseAuthExpr(Res, EndLoc);
8485 if (Identifier ==
"got")
8489 if (Identifier ==
"gotpcrel")
8491 else if (Identifier ==
"plt")
8493 else if (Identifier ==
"funcinit")
8497 return Error(Loc,
"invalid relocation specifier");
8502 return Error(Loc,
"@ specifier only allowed after a symbol");
8505 std::optional<MCBinaryExpr::Opcode> Opcode;
8513 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8524bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8525 MCAsmParser &Parser = getParser();
8527 AsmToken Tok = Parser.
getTok();
8534 return TokError(
"expected key name");
8539 return TokError(
"invalid key '" + KeyStr +
"'");
8546 return TokError(
"expected integer discriminator");
8550 return TokError(
"integer discriminator " + Twine(Discriminator) +
8551 " out of range [0, 0xFFFF]");
8554 bool UseAddressDiversity =
false;
8559 return TokError(
"expected 'addr'");
8560 UseAddressDiversity =
true;
8569 UseAddressDiversity, Ctx, Res->
getLoc());
8573bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8582 ELFSpec = AE->getSpecifier();
8583 Expr = AE->getSubExpr();
8623#define GET_REGISTER_MATCHER
8624#define GET_SUBTARGET_FEATURE_NAME
8625#define GET_MATCHER_IMPLEMENTATION
8626#define GET_MNEMONIC_SPELL_CHECKER
8627#include "AArch64GenAsmMatcher.inc"
8633 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8635 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8637 return Match_InvalidOperand;
8640 return Match_InvalidOperand;
8641 if (CE->getValue() == ExpectedVal)
8642 return Match_Success;
8643 return Match_InvalidOperand;
8648 return Match_InvalidOperand;
8654 if (
Op.isTokenEqual(
"za"))
8655 return Match_Success;
8656 return Match_InvalidOperand;
8662#define MATCH_HASH(N) \
8663 case MCK__HASH_##N: \
8664 return MatchesOpImmediate(N);
8690#define MATCH_HASH_MINUS(N) \
8691 case MCK__HASH__MINUS_##N: \
8692 return MatchesOpImmediate(-N);
8696#undef MATCH_HASH_MINUS
8700ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8705 return Error(S,
"expected register");
8707 MCRegister FirstReg;
8708 ParseStatus Res = tryParseScalarRegister(FirstReg);
8710 return Error(S,
"expected first even register of a consecutive same-size "
8711 "even/odd register pair");
8713 const MCRegisterClass &WRegClass =
8714 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8715 const MCRegisterClass &XRegClass =
8716 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8718 bool isXReg = XRegClass.
contains(FirstReg),
8719 isWReg = WRegClass.
contains(FirstReg);
8720 if (!isXReg && !isWReg)
8721 return Error(S,
"expected first even register of a consecutive same-size "
8722 "even/odd register pair");
8724 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8727 if (FirstEncoding & 0x1)
8728 return Error(S,
"expected first even register of a consecutive same-size "
8729 "even/odd register pair");
8732 return Error(getLoc(),
"expected comma");
8737 MCRegister SecondReg;
8738 Res = tryParseScalarRegister(SecondReg);
8740 return Error(
E,
"expected second odd register of a consecutive same-size "
8741 "even/odd register pair");
8744 (isXReg && !XRegClass.
contains(SecondReg)) ||
8745 (isWReg && !WRegClass.
contains(SecondReg)))
8746 return Error(
E,
"expected second odd register of a consecutive same-size "
8747 "even/odd register pair");
8752 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8755 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8758 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8764template <
bool ParseShiftExtend,
bool ParseSuffix>
8765ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8766 const SMLoc S = getLoc();
8772 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8777 if (ParseSuffix &&
Kind.empty())
8784 unsigned ElementWidth = KindRes->second;
8788 Operands.
push_back(AArch64Operand::CreateVectorReg(
8789 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8791 ParseStatus Res = tryParseVectorIndex(Operands);
8802 Res = tryParseOptionalShiftExtend(ExtOpnd);
8806 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8807 Operands.
push_back(AArch64Operand::CreateVectorReg(
8808 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8809 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8810 Ext->hasShiftExtendAmount()));
8815ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8816 MCAsmParser &Parser = getParser();
8818 SMLoc
SS = getLoc();
8819 const AsmToken &TokE = getTok();
8830 const MCExpr *ImmVal;
8837 return TokError(
"invalid operand for instruction");
8842 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8847 Pattern = Pat->Encoding;
8848 assert(Pattern >= 0 && Pattern < 32);
8859AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8861 SMLoc
SS = getLoc();
8862 const AsmToken &TokE = getTok();
8864 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8870 Pattern = Pat->Encoding;
8871 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8880ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8881 SMLoc
SS = getLoc();
8884 if (!tryParseScalarRegister(XReg).isSuccess())
8890 XReg, AArch64::x8sub_0,
8891 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8894 "expected an even-numbered x-register in the range [x0,x22]");
8897 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8901ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8911 if (getParser().parseExpression(ImmF))
8921 SMLoc
E = getTok().getLoc();
8923 if (getParser().parseExpression(ImmL))
8930 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8935ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8945 if (getParser().parseExpression(Ex))
8955 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8962 Operands.
push_back(AArch64Operand::CreateImm(
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
static unsigned matchMatrixRegName(StringRef Name)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static const struct Extension ExtensionMap[]
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Value * getPointer(Value *Ptr)
loop data Loop Data Prefetch
static 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
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB)
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
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 ==...
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
static int MCLOHNameToId(StringRef Name)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
FunctionAddr VTableAddr Next
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const FeatureBitset Features
AArch64::ExtensionBitset DefaultExts
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
FeatureBitset FeaturesRequired