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(); }
166 std::string &Suggestion);
168 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
170 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
176 bool invertCondCode);
177 bool parseImmExpr(int64_t &Out);
179 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
182 bool showMatchError(SMLoc Loc,
unsigned ErrCode,
uint64_t ErrorInfo,
185 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
186 bool parseDataExpr(
const MCExpr *&Res)
override;
187 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
189 bool parseDirectiveArch(SMLoc L);
190 bool parseDirectiveArchExtension(SMLoc L);
191 bool parseDirectiveCPU(SMLoc L);
192 bool parseDirectiveInst(SMLoc L);
194 bool parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth);
196 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
197 bool parseDirectiveLtorg(SMLoc L);
199 bool parseDirectiveReq(StringRef Name, SMLoc L);
200 bool parseDirectiveUnreq(SMLoc L);
201 bool parseDirectiveCFINegateRAState();
202 bool parseDirectiveCFINegateRAStateWithPC();
203 bool parseDirectiveCFILLVMSetRAState();
204 bool parseDirectiveCFIBKeyFrame();
205 bool parseDirectiveCFIMTETaggedFrame();
206 bool parseDirectiveCFINonHintPAuthFrame();
208 bool parseDirectiveVariantPCS(SMLoc L);
210 bool parseDirectiveSEHAllocStack(SMLoc L);
211 bool parseDirectiveSEHPrologEnd(SMLoc L);
212 bool parseDirectiveSEHEndC(SMLoc L);
213 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
214 bool parseDirectiveSEHSaveFPLR(SMLoc L);
215 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
216 bool parseDirectiveSEHSaveReg(SMLoc L);
217 bool parseDirectiveSEHSaveRegX(SMLoc L);
218 bool parseDirectiveSEHSaveRegP(SMLoc L);
219 bool parseDirectiveSEHSaveRegPX(SMLoc L);
220 bool parseDirectiveSEHSaveLRPair(SMLoc L);
221 bool parseDirectiveSEHSaveFReg(SMLoc L);
222 bool parseDirectiveSEHSaveFRegX(SMLoc L);
223 bool parseDirectiveSEHSaveFRegP(SMLoc L);
224 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
225 bool parseDirectiveSEHSetFP(SMLoc L);
226 bool parseDirectiveSEHAddFP(SMLoc L);
227 bool parseDirectiveSEHNop(SMLoc L);
228 bool parseDirectiveSEHSaveNext(SMLoc L);
229 bool parseDirectiveSEHEpilogStart(SMLoc L);
230 bool parseDirectiveSEHEpilogEnd(SMLoc L);
231 bool parseDirectiveSEHTrapFrame(SMLoc L);
232 bool parseDirectiveSEHMachineFrame(SMLoc L);
233 bool parseDirectiveSEHContext(SMLoc L);
234 bool parseDirectiveSEHECContext(SMLoc L);
235 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
236 bool parseDirectiveSEHPACSignLR(SMLoc L);
237 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
238 bool parseDirectiveSEHAllocZ(SMLoc L);
239 bool parseDirectiveSEHSaveZReg(SMLoc L);
240 bool parseDirectiveSEHSavePReg(SMLoc L);
241 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
242 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
244 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
245 SmallVectorImpl<SMLoc> &Loc);
246 unsigned getNumRegsForRegKind(RegKind K);
247 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
250 bool MatchingInlineAsm)
override;
254#define GET_ASSEMBLER_HEADER
255#include "AArch64GenAsmMatcher.inc"
269 template <
bool IsSVEPrefetch = false>
275 template <
bool AddFPZeroAsLiteral>
283 template <
bool ParseShiftExtend,
284 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
287 template <
bool ParseShiftExtend,
bool ParseSuffix>
289 template <RegKind RK>
293 template <RegKind VectorKind>
295 bool ExpectMatch =
false);
303 enum AArch64MatchResultTy {
304 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
305#define GET_OPERAND_DIAGNOSTIC_TYPES
306#include "AArch64GenAsmMatcher.inc"
309 bool IsWindowsArm64EC;
311 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
312 const MCInstrInfo &MII)
313 : MCTargetAsmParser(STI, MII) {
317 MCStreamer &S = getParser().getStreamer();
319 new AArch64TargetStreamer(S);
331 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
334 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
335 const MCParsedAsmOperand &Op2)
const override;
336 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
338 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
339 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
340 SMLoc &EndLoc)
override;
341 bool ParseDirective(AsmToken DirectiveID)
override;
342 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
343 unsigned Kind)
override;
375 SMLoc StartLoc, EndLoc;
384 struct ShiftExtendOp {
387 bool HasExplicitAmount;
397 RegConstraintEqualityTy EqualityTy;
413 ShiftExtendOp ShiftExtend;
418 unsigned ElementWidth;
422 struct MatrixTileListOp {
423 unsigned RegMask = 0;
426 struct VectorListOp {
430 unsigned NumElements;
431 unsigned ElementWidth;
432 RegKind RegisterKind;
435 struct VectorIndexOp {
443 struct ShiftedImmOp {
445 unsigned ShiftAmount;
474 uint32_t PStateField;
487 struct TIndexHintOp {
496 unsigned PStateField;
502 struct MatrixRegOp MatrixReg;
503 struct MatrixTileListOp MatrixTileList;
504 struct VectorListOp VectorList;
505 struct VectorIndexOp VectorIndex;
507 struct ShiftedImmOp ShiftedImm;
508 struct ImmRangeOp ImmRange;
510 struct FPImmOp FPImm;
512 struct SysRegOp SysReg;
513 struct SysCRImmOp SysCRImm;
515 struct TIndexHintOp TIndexHint;
516 struct ShiftExtendOp ShiftExtend;
525 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
527 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
529 StartLoc =
o.StartLoc;
539 ShiftedImm =
o.ShiftedImm;
542 ImmRange =
o.ImmRange;
556 case k_MatrixRegister:
557 MatrixReg =
o.MatrixReg;
559 case k_MatrixTileList:
560 MatrixTileList =
o.MatrixTileList;
563 VectorList =
o.VectorList;
566 VectorIndex =
o.VectorIndex;
572 SysCRImm =
o.SysCRImm;
578 TIndexHint =
o.TIndexHint;
581 ShiftExtend =
o.ShiftExtend;
590 SMLoc getStartLoc()
const override {
return StartLoc; }
592 SMLoc getEndLoc()
const override {
return EndLoc; }
595 assert(Kind == k_Token &&
"Invalid access!");
596 return StringRef(Tok.Data, Tok.Length);
599 bool isTokenSuffix()
const {
600 assert(Kind == k_Token &&
"Invalid access!");
604 const MCExpr *
getImm()
const {
605 assert(Kind == k_Immediate &&
"Invalid access!");
609 const MCExpr *getShiftedImmVal()
const {
610 assert(Kind == k_ShiftedImm &&
"Invalid access!");
611 return ShiftedImm.Val;
614 unsigned getShiftedImmShift()
const {
615 assert(Kind == k_ShiftedImm &&
"Invalid access!");
616 return ShiftedImm.ShiftAmount;
619 unsigned getFirstImmVal()
const {
620 assert(Kind == k_ImmRange &&
"Invalid access!");
621 return ImmRange.First;
624 unsigned getLastImmVal()
const {
625 assert(Kind == k_ImmRange &&
"Invalid access!");
626 return ImmRange.Last;
630 assert(Kind == k_CondCode &&
"Invalid access!");
635 assert (Kind == k_FPImm &&
"Invalid access!");
636 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
639 bool getFPImmIsExact()
const {
640 assert (Kind == k_FPImm &&
"Invalid access!");
641 return FPImm.IsExact;
644 unsigned getBarrier()
const {
645 assert(Kind == k_Barrier &&
"Invalid access!");
649 StringRef getBarrierName()
const {
650 assert(Kind == k_Barrier &&
"Invalid access!");
654 bool getBarriernXSModifier()
const {
655 assert(Kind == k_Barrier &&
"Invalid access!");
659 MCRegister
getReg()
const override {
660 assert(Kind == k_Register &&
"Invalid access!");
664 MCRegister getMatrixReg()
const {
665 assert(Kind == k_MatrixRegister &&
"Invalid access!");
666 return MatrixReg.Reg;
669 unsigned getMatrixElementWidth()
const {
670 assert(Kind == k_MatrixRegister &&
"Invalid access!");
671 return MatrixReg.ElementWidth;
674 MatrixKind getMatrixKind()
const {
675 assert(Kind == k_MatrixRegister &&
"Invalid access!");
676 return MatrixReg.Kind;
679 unsigned getMatrixTileListRegMask()
const {
680 assert(isMatrixTileList() &&
"Invalid access!");
681 return MatrixTileList.RegMask;
684 RegConstraintEqualityTy getRegEqualityTy()
const {
685 assert(Kind == k_Register &&
"Invalid access!");
686 return Reg.EqualityTy;
689 MCRegister getVectorListStart()
const {
690 assert(Kind == k_VectorList &&
"Invalid access!");
691 return VectorList.Reg;
694 unsigned getVectorListCount()
const {
695 assert(Kind == k_VectorList &&
"Invalid access!");
696 return VectorList.Count;
699 unsigned getVectorListStride()
const {
700 assert(Kind == k_VectorList &&
"Invalid access!");
701 return VectorList.Stride;
704 int getVectorIndex()
const {
705 assert(Kind == k_VectorIndex &&
"Invalid access!");
706 return VectorIndex.Val;
709 StringRef getSysReg()
const {
710 assert(Kind == k_SysReg &&
"Invalid access!");
711 return StringRef(SysReg.Data, SysReg.Length);
714 unsigned getSysCR()
const {
715 assert(Kind == k_SysCR &&
"Invalid access!");
719 unsigned getPrefetch()
const {
720 assert(Kind == k_Prefetch &&
"Invalid access!");
724 unsigned getTIndexHint()
const {
725 assert(Kind == k_TIndexHint &&
"Invalid access!");
726 return TIndexHint.Val;
729 StringRef getTIndexHintName()
const {
730 assert(Kind == k_TIndexHint &&
"Invalid access!");
731 return StringRef(TIndexHint.Data, TIndexHint.Length);
734 StringRef getSVCR()
const {
735 assert(Kind == k_SVCR &&
"Invalid access!");
736 return StringRef(SVCR.Data, SVCR.Length);
739 StringRef getPrefetchName()
const {
740 assert(Kind == k_Prefetch &&
"Invalid access!");
745 if (Kind == k_ShiftExtend)
746 return ShiftExtend.Type;
747 if (Kind == k_Register)
748 return Reg.ShiftExtend.Type;
752 unsigned getShiftExtendAmount()
const {
753 if (Kind == k_ShiftExtend)
754 return ShiftExtend.Amount;
755 if (Kind == k_Register)
756 return Reg.ShiftExtend.Amount;
760 bool hasShiftExtendAmount()
const {
761 if (Kind == k_ShiftExtend)
762 return ShiftExtend.HasExplicitAmount;
763 if (Kind == k_Register)
764 return Reg.ShiftExtend.HasExplicitAmount;
768 bool isImm()
const override {
return Kind == k_Immediate; }
769 bool isMem()
const override {
return false; }
771 bool isUImm6()
const {
778 return (Val >= 0 && Val < 64);
781 template <
int W
idth> DiagnosticPredicate isSImm()
const {
782 return isSImmScaled<Width, 1>();
785 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
786 return isImmScaled<Bits, Scale>(
true);
789 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
790 DiagnosticPredicate isUImmScaled()
const {
791 if (IsRange && isImmRange() &&
792 (getLastImmVal() != getFirstImmVal() +
Offset))
795 return isImmScaled<Bits, Scale, IsRange>(
false);
798 template <
int Bits,
int Scale,
bool IsRange = false>
799 DiagnosticPredicate isImmScaled(
bool Signed)
const {
800 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
801 (isImmRange() && !IsRange))
806 Val = getFirstImmVal();
814 int64_t MinVal, MaxVal;
816 int64_t Shift =
Bits - 1;
817 MinVal = (int64_t(1) << Shift) * -Scale;
818 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
821 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
824 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
830 DiagnosticPredicate isSVEPattern()
const {
837 if (Val >= 0 && Val < 32)
842 DiagnosticPredicate isSVEVecLenSpecifier()
const {
849 if (Val >= 0 && Val <= 1)
854 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
858 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
887 template <
int Scale> DiagnosticPredicate isUImm12Offset()
const {
893 return DiagnosticPredicate(isSymbolicUImm12Offset(
getImm()));
896 if ((Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000)
901 template <
int N,
int M> DiagnosticPredicate isImmInRange()
const {
908 if (Val >=
N && Val <= M)
913 bool isHinteUImm16()
const {
920 return Val >= 0 && Val <= 65535 &&
921 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
926 template <
typename T>
927 bool isLogicalImm()
const {
944 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
946 bool isImmRange()
const {
return Kind == k_ImmRange; }
951 template <
unsigned W
idth>
952 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
953 if (isShiftedImm() && Width == getShiftedImmShift())
955 return std::make_pair(
CE->getValue(), Width);
959 int64_t Val =
CE->getValue();
961 return std::make_pair(Val >> Width, Width);
963 return std::make_pair(Val, 0u);
969 bool isAddSubImm()
const {
970 if (!isShiftedImm() && !isImm())
976 if (isShiftedImm()) {
977 unsigned Shift = ShiftedImm.ShiftAmount;
978 Expr = ShiftedImm.Val;
979 if (Shift != 0 && Shift != 12)
988 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1004 if (
auto ShiftedVal = getShiftedVal<12>())
1005 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1012 bool isAddSubImmNeg()
const {
1013 if (!isShiftedImm() && !isImm())
1017 if (
auto ShiftedVal = getShiftedVal<12>())
1018 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1028 template <
typename T>
1029 DiagnosticPredicate isSVECpyImm()
const {
1033 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1034 std::is_same<int8_t, T>::value;
1035 if (
auto ShiftedImm = getShiftedVal<8>())
1036 if (!(IsByte && ShiftedImm->second) &&
1038 << ShiftedImm->second))
1047 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1051 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1052 std::is_same<int8_t, T>::value;
1053 if (
auto ShiftedImm = getShiftedVal<8>())
1054 if (!(IsByte && ShiftedImm->second) &&
1056 << ShiftedImm->second))
1062 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1063 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1068 bool isCondCode()
const {
return Kind == k_CondCode; }
1070 bool isSIMDImmType10()
const {
1080 bool isBranchTarget()
const {
1089 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1090 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1100 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1110 bool isMovWSymbolG3()
const {
1114 bool isMovWSymbolG2()
const {
1121 bool isMovWSymbolG1()
const {
1129 bool isMovWSymbolG0()
const {
1137 template<
int RegW
idth,
int Shift>
1138 bool isMOVZMovAlias()
const {
1139 if (!isImm())
return false;
1152 template<
int RegW
idth,
int Shift>
1153 bool isMOVNMovAlias()
const {
1154 if (!isImm())
return false;
1157 if (!CE)
return false;
1163 bool isFPImm()
const {
1164 return Kind == k_FPImm &&
1168 bool isBarrier()
const {
1169 return Kind == k_Barrier && !getBarriernXSModifier();
1171 bool isBarriernXS()
const {
1172 return Kind == k_Barrier && getBarriernXSModifier();
1174 bool isSysReg()
const {
return Kind == k_SysReg; }
1176 bool isMRSSystemRegister()
const {
1177 if (!isSysReg())
return false;
1179 return SysReg.MRSReg != -1U;
1182 bool isMSRSystemRegister()
const {
1183 if (!isSysReg())
return false;
1184 return SysReg.MSRReg != -1U;
1187 bool isSystemPStateFieldWithImm0_1()
const {
1188 if (!isSysReg())
return false;
1189 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1192 bool isSystemPStateFieldWithImm0_15()
const {
1195 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1198 bool isSVCR()
const {
1201 return SVCR.PStateField != -1U;
1204 bool isReg()
const override {
1205 return Kind == k_Register;
1208 bool isVectorList()
const {
return Kind == k_VectorList; }
1210 bool isScalarReg()
const {
1211 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1214 bool isNeonVectorReg()
const {
1215 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1218 bool isNeonVectorRegLo()
const {
1219 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1220 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1221 .contains(
Reg.Reg) ||
1222 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1223 .contains(
Reg.Reg));
1226 bool isNeonVectorReg0to7()
const {
1227 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1228 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1229 .contains(
Reg.Reg));
1232 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1233 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1235 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1238 case AArch64::PPRRegClassID:
1239 case AArch64::PPR_3bRegClassID:
1240 case AArch64::PPR_p8to15RegClassID:
1241 case AArch64::PNRRegClassID:
1242 case AArch64::PNR_p8to15RegClassID:
1243 case AArch64::PPRorPNRRegClassID:
1244 RK = RegKind::SVEPredicateAsCounter;
1250 return (Kind == k_Register &&
Reg.Kind == RK) &&
1251 getAArch64MCRegisterClass(Class).contains(
getReg());
1254 template <
unsigned Class>
bool isSVEVectorReg()
const {
1257 case AArch64::ZPRRegClassID:
1258 case AArch64::ZPR_3bRegClassID:
1259 case AArch64::ZPR_4bRegClassID:
1260 case AArch64::ZPRMul2_LoRegClassID:
1261 case AArch64::ZPRMul2_HiRegClassID:
1262 case AArch64::ZPR_KRegClassID:
1263 RK = RegKind::SVEDataVector;
1265 case AArch64::PPRRegClassID:
1266 case AArch64::PPR_3bRegClassID:
1267 case AArch64::PPR_p8to15RegClassID:
1268 case AArch64::PNRRegClassID:
1269 case AArch64::PNR_p8to15RegClassID:
1270 case AArch64::PPRorPNRRegClassID:
1271 RK = RegKind::SVEPredicateVector;
1277 return (Kind == k_Register &&
Reg.Kind == RK) &&
1278 getAArch64MCRegisterClass(Class).contains(
getReg());
1281 template <
unsigned Class>
bool isFPRasZPR()
const {
1282 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1283 getAArch64MCRegisterClass(Class).contains(
getReg());
1286 template <
int ElementW
idth,
unsigned Class>
1287 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1288 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1291 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1297 template <
int ElementW
idth,
unsigned Class>
1298 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1299 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1300 Reg.Kind != RegKind::SVEPredicateVector))
1303 if ((isSVEPredicateAsCounterReg<Class>() ||
1304 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1305 Reg.ElementWidth == ElementWidth)
1311 template <
int ElementW
idth,
unsigned Class>
1312 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1313 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1316 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1322 template <
int ElementW
idth,
unsigned Class>
1323 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1324 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1327 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1333 template <
int ElementWidth,
unsigned Class,
1335 bool ShiftWidthAlwaysSame>
1336 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1337 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1338 if (!VectorMatch.isMatch())
1344 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1347 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1350 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1356 bool isGPR32as64()
const {
1357 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1358 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1362 bool isGPR64as32()
const {
1363 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1364 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1368 bool isGPR64x8()
const {
1369 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1370 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1374 bool isWSeqPair()
const {
1375 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1376 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1380 bool isXSeqPair()
const {
1381 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1382 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1386 bool isSyspXzrPair()
const {
1390 template<
int64_t Angle,
int64_t Remainder>
1391 DiagnosticPredicate isComplexRotation()
const {
1400 if (
Value % Angle == Remainder &&
Value <= 270)
1405 template <
unsigned RegClassID>
bool isGPR64()
const {
1406 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1407 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1410 template <
unsigned RegClassID,
int ExtW
idth>
1411 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1412 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1416 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1423 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1424 bool isImplicitlyTypedVectorList()
const {
1425 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1426 VectorList.NumElements == 0 &&
1428 (!IsConsecutive || (VectorList.Stride == 1));
1431 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1432 unsigned ElementWidth,
unsigned Stride = 1>
1433 bool isTypedVectorList()
const {
1434 if (Kind != k_VectorList)
1436 if (VectorList.Count != NumRegs)
1438 if (VectorList.RegisterKind != VectorKind)
1440 if (VectorList.ElementWidth != ElementWidth)
1442 if (VectorList.Stride != Stride)
1444 return VectorList.NumElements == NumElements;
1447 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1448 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1450 DiagnosticPredicate isTypedVectorListInRange()
const {
1452 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1455 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1456 (VectorList.Reg - FirstReg) % Multiple != 0)
1461 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned Stride,
1462 unsigned ElementWidth>
1463 DiagnosticPredicate isTypedVectorListStrided()
const {
1464 bool Res = isTypedVectorList<
VectorKind, NumRegs, 0,
1465 ElementWidth, Stride>();
1468 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1469 ((VectorList.Reg >= AArch64::Z16) &&
1470 (VectorList.Reg < (AArch64::Z16 + Stride))))
1475 template <
int Min,
int Max>
1476 DiagnosticPredicate isVectorIndex()
const {
1477 if (Kind != k_VectorIndex)
1479 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1484 bool isToken()
const override {
return Kind == k_Token; }
1486 bool isTokenEqual(StringRef Str)
const {
1487 return Kind == k_Token &&
getToken() == Str;
1489 bool isSysCR()
const {
return Kind == k_SysCR; }
1490 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1491 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1492 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1493 bool isShifter()
const {
1494 if (!isShiftExtend())
1503 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1504 if (Kind != k_FPImm)
1507 if (getFPImmIsExact()) {
1509 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1511 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1514 APFloat RealVal(APFloat::IEEEdouble());
1516 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1517 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1520 if (
getFPImm().bitwiseIsEqual(RealVal))
1527 template <
unsigned ImmA,
unsigned ImmB>
1528 DiagnosticPredicate isExactFPImm()
const {
1530 if ((Res = isExactFPImm<ImmA>()))
1532 if ((Res = isExactFPImm<ImmB>()))
1537 bool isExtend()
const {
1538 if (!isShiftExtend())
1547 getShiftExtendAmount() <= 4;
1550 bool isExtend64()
const {
1560 bool isExtendLSL64()
const {
1566 getShiftExtendAmount() <= 4;
1569 bool isLSLImm3Shift()
const {
1570 if (!isShiftExtend())
1576 template<
int W
idth>
bool isMemXExtend()
const {
1581 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1582 getShiftExtendAmount() == 0);
1585 template<
int W
idth>
bool isMemWExtend()
const {
1590 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1591 getShiftExtendAmount() == 0);
1594 template <
unsigned w
idth>
1595 bool isArithmeticShifter()
const {
1605 template <
unsigned w
idth>
1606 bool isLogicalShifter()
const {
1614 getShiftExtendAmount() < width;
1617 bool isMovImm32Shifter()
const {
1625 uint64_t Val = getShiftExtendAmount();
1626 return (Val == 0 || Val == 16);
1629 bool isMovImm64Shifter()
const {
1637 uint64_t Val = getShiftExtendAmount();
1638 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1641 bool isLogicalVecShifter()
const {
1646 unsigned Shift = getShiftExtendAmount();
1648 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1651 bool isLogicalVecHalfWordShifter()
const {
1652 if (!isLogicalVecShifter())
1656 unsigned Shift = getShiftExtendAmount();
1658 (Shift == 0 || Shift == 8);
1661 bool isMoveVecShifter()
const {
1662 if (!isShiftExtend())
1666 unsigned Shift = getShiftExtendAmount();
1668 (Shift == 8 || Shift == 16);
1677 bool isSImm9OffsetFB()
const {
1678 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1681 bool isAdrpLabel()
const {
1688 int64_t Val =
CE->getValue();
1689 int64_t Min = - (4096 * (1LL << (21 - 1)));
1690 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1691 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1697 bool isAdrLabel()
const {
1704 int64_t Val =
CE->getValue();
1705 int64_t Min = - (1LL << (21 - 1));
1706 int64_t
Max = ((1LL << (21 - 1)) - 1);
1707 return Val >= Min && Val <=
Max;
1713 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1714 DiagnosticPredicate isMatrixRegOperand()
const {
1717 if (getMatrixKind() != Kind ||
1718 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1719 EltSize != getMatrixElementWidth())
1724 bool isPAuthPCRelLabel16Operand()
const {
1736 return (Val <= 0) && (Val > -(1 << 18));
1739 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1749 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1750 assert(
N == 1 &&
"Invalid number of operands!");
1754 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1755 assert(
N == 1 &&
"Invalid number of operands!");
1759 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1760 assert(
N == 1 &&
"Invalid number of operands!");
1762 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1764 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1771 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1772 assert(
N == 1 &&
"Invalid number of operands!");
1774 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1776 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1783 template <
int W
idth>
1784 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1787 case 8:
Base = AArch64::B0;
break;
1788 case 16:
Base = AArch64::H0;
break;
1789 case 32:
Base = AArch64::S0;
break;
1790 case 64:
Base = AArch64::D0;
break;
1791 case 128:
Base = AArch64::Q0;
break;
1798 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1799 assert(
N == 1 &&
"Invalid number of operands!");
1802 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1803 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1807 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1808 assert(
N == 1 &&
"Invalid number of operands!");
1813 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1814 assert(
N == 1 &&
"Invalid number of operands!");
1815 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1820 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1821 assert(
N == 1 &&
"Invalid number of operands!");
1822 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1827 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1828 assert(
N == 1 &&
"Invalid number of operands!");
1832 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1833 assert(
N == 1 &&
"Invalid number of operands!");
1837 enum VecListIndexType {
1838 VecListIdx_DReg = 0,
1839 VecListIdx_QReg = 1,
1840 VecListIdx_ZReg = 2,
1841 VecListIdx_PReg = 3,
1844 template <VecListIndexType RegTy,
unsigned NumRegs,
1845 bool IsConsecutive =
false>
1846 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1847 assert(
N == 1 &&
"Invalid number of operands!");
1848 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1849 "Expected consecutive registers");
1850 static const unsigned FirstRegs[][5] = {
1852 AArch64::D0, AArch64::D0_D1,
1853 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1855 AArch64::Q0, AArch64::Q0_Q1,
1856 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1858 AArch64::Z0, AArch64::Z0_Z1,
1859 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1861 AArch64::P0, AArch64::P0_P1 }
1864 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1865 " NumRegs must be <= 4 for ZRegs");
1867 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1868 " NumRegs must be <= 2 for PRegs");
1870 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1872 FirstRegs[(
unsigned)RegTy][0]));
1875 template <
unsigned NumRegs>
1876 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1877 assert(
N == 1 &&
"Invalid number of operands!");
1878 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1882 if (getVectorListStart() < AArch64::Z16) {
1883 assert((getVectorListStart() < AArch64::Z8) &&
1884 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1886 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1888 assert((getVectorListStart() < AArch64::Z24) &&
1889 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1891 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1895 if (getVectorListStart() < AArch64::Z16) {
1896 assert((getVectorListStart() < AArch64::Z4) &&
1897 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1899 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1901 assert((getVectorListStart() < AArch64::Z20) &&
1902 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1904 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1912 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1913 assert(
N == 1 &&
"Invalid number of operands!");
1914 unsigned RegMask = getMatrixTileListRegMask();
1915 assert(RegMask <= 0xFF &&
"Invalid mask!");
1919 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1920 assert(
N == 1 &&
"Invalid number of operands!");
1924 template <
unsigned ImmIs0,
unsigned ImmIs1>
1925 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1926 assert(
N == 1 &&
"Invalid number of operands!");
1927 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1931 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1932 assert(
N == 1 &&
"Invalid number of operands!");
1939 template <
int Adj>
void addAdjImmOperands(MCInst &Inst,
unsigned N)
const {
1940 assert(
N == 1 &&
"Invalid number of operands!");
1945 template <
int Shift>
1946 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1947 assert(
N == 2 &&
"Invalid number of operands!");
1948 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1951 }
else if (isShiftedImm()) {
1952 addExpr(Inst, getShiftedImmVal());
1960 template <
int Shift>
1961 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1962 assert(
N == 2 &&
"Invalid number of operands!");
1963 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1970 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1971 assert(
N == 1 &&
"Invalid number of operands!");
1975 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1976 assert(
N == 1 &&
"Invalid number of operands!");
1984 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1985 addImmOperands(Inst,
N);
1989 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1990 assert(
N == 1 &&
"Invalid number of operands!");
2000 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2001 assert(
N == 1 &&
"Invalid number of operands!");
2006 template <
int Scale>
2007 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2008 assert(
N == 1 &&
"Invalid number of operands!");
2013 template <
int Scale>
2014 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2015 assert(
N == 1 &&
"Invalid number of operands!");
2019 template <
typename T>
2020 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2021 assert(
N == 1 &&
"Invalid number of operands!");
2023 std::make_unsigned_t<T> Val = MCE->
getValue();
2028 template <
typename T>
2029 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2030 assert(
N == 1 &&
"Invalid number of operands!");
2032 std::make_unsigned_t<T> Val = ~MCE->getValue();
2037 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2038 assert(
N == 1 &&
"Invalid number of operands!");
2044 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2048 assert(
N == 1 &&
"Invalid number of operands!");
2054 assert(MCE &&
"Invalid constant immediate operand!");
2058 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2062 assert(
N == 1 &&
"Invalid number of operands!");
2071 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2075 assert(
N == 1 &&
"Invalid number of operands!");
2081 assert(MCE &&
"Invalid constant immediate operand!");
2085 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2089 assert(
N == 1 &&
"Invalid number of operands!");
2095 assert(MCE &&
"Invalid constant immediate operand!");
2099 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2103 assert(
N == 1 &&
"Invalid number of operands!");
2109 assert(MCE &&
"Invalid constant immediate operand!");
2113 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2114 assert(
N == 1 &&
"Invalid number of operands!");
2119 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2120 assert(
N == 1 &&
"Invalid number of operands!");
2124 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2125 assert(
N == 1 &&
"Invalid number of operands!");
2129 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2130 assert(
N == 1 &&
"Invalid number of operands!");
2135 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2141 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2142 assert(
N == 1 &&
"Invalid number of operands!");
2147 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2148 assert(
N == 1 &&
"Invalid number of operands!");
2153 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2154 assert(
N == 1 &&
"Invalid number of operands!");
2159 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2160 assert(
N == 1 &&
"Invalid number of operands!");
2164 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2165 assert(
N == 1 &&
"Invalid number of operands!");
2169 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2170 assert(
N == 1 &&
"Invalid number of operands!");
2174 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2175 assert(
N == 1 &&
"Invalid number of operands!");
2181 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2182 assert(
N == 1 &&
"Invalid number of operands!");
2183 unsigned Imm = getShiftExtendAmount();
2187 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2188 assert(
N == 1 &&
"Invalid number of operands!");
2193 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2196 if (
Reg != AArch64::XZR)
2202 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2203 assert(
N == 1 &&
"Invalid number of operands!");
2210 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2211 assert(
N == 1 &&
"Invalid number of operands!");
2218 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2219 assert(
N == 2 &&
"Invalid number of operands!");
2230 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2231 assert(
N == 2 &&
"Invalid number of operands!");
2239 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2240 assert(
N == 1 &&
"Invalid number of operands!");
2252 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2253 assert(
N == 1 &&
"Invalid number of operands!");
2260 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2261 assert(
N == 1 &&
"Invalid number of operands!");
2266 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2267 assert(
N == 1 &&
"Invalid number of operands!");
2272 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2274 static std::unique_ptr<AArch64Operand>
2275 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2276 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2277 Op->Tok.Data = Str.data();
2278 Op->Tok.Length = Str.size();
2279 Op->Tok.IsSuffix = IsSuffix;
2285 static std::unique_ptr<AArch64Operand>
2286 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2287 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2289 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2290 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2292 Op->Reg.Kind = Kind;
2293 Op->Reg.ElementWidth = 0;
2294 Op->Reg.EqualityTy = EqTy;
2295 Op->Reg.ShiftExtend.Type = ExtTy;
2296 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2297 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2303 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2304 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2306 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2307 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2308 Kind == RegKind::SVEPredicateVector ||
2309 Kind == RegKind::SVEPredicateAsCounter) &&
2310 "Invalid vector kind");
2311 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2313 Op->Reg.ElementWidth = ElementWidth;
2317 static std::unique_ptr<AArch64Operand>
2318 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2319 unsigned NumElements,
unsigned ElementWidth,
2320 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2321 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2322 Op->VectorList.Reg =
Reg;
2324 Op->VectorList.Stride = Stride;
2325 Op->VectorList.NumElements = NumElements;
2326 Op->VectorList.ElementWidth = ElementWidth;
2327 Op->VectorList.RegisterKind = RegisterKind;
2333 static std::unique_ptr<AArch64Operand>
2334 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2335 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2336 Op->VectorIndex.Val =
Idx;
2342 static std::unique_ptr<AArch64Operand>
2343 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2344 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2345 Op->MatrixTileList.RegMask = RegMask;
2351 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2352 const unsigned ElementWidth) {
2353 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2355 {{0, AArch64::ZAB0},
2356 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2357 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2358 {{8, AArch64::ZAB0},
2359 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2360 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2361 {{16, AArch64::ZAH0},
2362 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2363 {{16, AArch64::ZAH1},
2364 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2365 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2366 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2367 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2368 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2371 if (ElementWidth == 64)
2374 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2375 assert(!Regs.empty() &&
"Invalid tile or element width!");
2380 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2381 SMLoc
E, MCContext &Ctx) {
2382 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2389 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2390 unsigned ShiftAmount,
2393 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2394 Op->ShiftedImm .Val = Val;
2395 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2401 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2402 unsigned Last, SMLoc S,
2405 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2407 Op->ImmRange.Last =
Last;
2412 static std::unique_ptr<AArch64Operand>
2414 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2415 Op->CondCode.Code =
Code;
2421 static std::unique_ptr<AArch64Operand>
2422 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2423 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2425 Op->FPImm.IsExact = IsExact;
2431 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2435 bool HasnXSModifier) {
2436 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2437 Op->Barrier.Val = Val;
2438 Op->Barrier.Data = Str.data();
2439 Op->Barrier.Length = Str.size();
2440 Op->Barrier.HasnXSModifier = HasnXSModifier;
2446 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2449 uint32_t PStateField,
2451 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2452 Op->SysReg.Data = Str.data();
2453 Op->SysReg.Length = Str.size();
2454 Op->SysReg.MRSReg = MRSReg;
2455 Op->SysReg.MSRReg = MSRReg;
2456 Op->SysReg.PStateField = PStateField;
2462 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2463 SMLoc
E, MCContext &Ctx) {
2464 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2465 Op->SysCRImm.Val = Val;
2471 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2475 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2476 Op->Prefetch.Val = Val;
2477 Op->Barrier.Data = Str.data();
2478 Op->Barrier.Length = Str.size();
2484 static std::unique_ptr<AArch64Operand>
2485 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2486 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2487 Op->TIndexHint.Val = Val;
2488 Op->TIndexHint.Data = Str.data();
2489 Op->TIndexHint.Length = Str.size();
2495 static std::unique_ptr<AArch64Operand>
2496 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2497 SMLoc S, SMLoc
E, MCContext &Ctx) {
2498 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2499 Op->MatrixReg.Reg =
Reg;
2500 Op->MatrixReg.ElementWidth = ElementWidth;
2501 Op->MatrixReg.Kind = Kind;
2507 static std::unique_ptr<AArch64Operand>
2508 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2509 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2510 Op->SVCR.PStateField = PStateField;
2511 Op->SVCR.Data = Str.data();
2512 Op->SVCR.Length = Str.size();
2518 static std::unique_ptr<AArch64Operand>
2520 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2521 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2522 Op->ShiftExtend.Type = ShOp;
2523 Op->ShiftExtend.Amount = Val;
2524 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2536 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2537 if (!getFPImmIsExact())
2542 StringRef
Name = getBarrierName();
2544 OS <<
"<barrier " <<
Name <<
">";
2546 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2552 case k_ShiftedImm: {
2553 unsigned Shift = getShiftedImmShift();
2554 OS <<
"<shiftedimm ";
2561 OS << getFirstImmVal();
2562 OS <<
":" << getLastImmVal() <<
">";
2568 case k_VectorList: {
2569 OS <<
"<vectorlist ";
2570 MCRegister
Reg = getVectorListStart();
2571 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2572 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2577 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2580 OS <<
"<sysreg: " << getSysReg() <<
'>';
2586 OS <<
"c" << getSysCR();
2589 StringRef
Name = getPrefetchName();
2591 OS <<
"<prfop " <<
Name <<
">";
2593 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2597 OS << getTIndexHintName();
2599 case k_MatrixRegister:
2600 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2602 case k_MatrixTileList: {
2603 OS <<
"<matrixlist ";
2604 unsigned RegMask = getMatrixTileListRegMask();
2605 unsigned MaxBits = 8;
2606 for (
unsigned I = MaxBits;
I > 0; --
I)
2607 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2616 OS <<
"<register " <<
getReg().
id() <<
">";
2617 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2622 << getShiftExtendAmount();
2623 if (!hasShiftExtendAmount())
2639 .
Case(
"v0", AArch64::Q0)
2640 .
Case(
"v1", AArch64::Q1)
2641 .
Case(
"v2", AArch64::Q2)
2642 .
Case(
"v3", AArch64::Q3)
2643 .
Case(
"v4", AArch64::Q4)
2644 .
Case(
"v5", AArch64::Q5)
2645 .
Case(
"v6", AArch64::Q6)
2646 .
Case(
"v7", AArch64::Q7)
2647 .
Case(
"v8", AArch64::Q8)
2648 .
Case(
"v9", AArch64::Q9)
2649 .
Case(
"v10", AArch64::Q10)
2650 .
Case(
"v11", AArch64::Q11)
2651 .
Case(
"v12", AArch64::Q12)
2652 .
Case(
"v13", AArch64::Q13)
2653 .
Case(
"v14", AArch64::Q14)
2654 .
Case(
"v15", AArch64::Q15)
2655 .
Case(
"v16", AArch64::Q16)
2656 .
Case(
"v17", AArch64::Q17)
2657 .
Case(
"v18", AArch64::Q18)
2658 .
Case(
"v19", AArch64::Q19)
2659 .
Case(
"v20", AArch64::Q20)
2660 .
Case(
"v21", AArch64::Q21)
2661 .
Case(
"v22", AArch64::Q22)
2662 .
Case(
"v23", AArch64::Q23)
2663 .
Case(
"v24", AArch64::Q24)
2664 .
Case(
"v25", AArch64::Q25)
2665 .
Case(
"v26", AArch64::Q26)
2666 .
Case(
"v27", AArch64::Q27)
2667 .
Case(
"v28", AArch64::Q28)
2668 .
Case(
"v29", AArch64::Q29)
2669 .
Case(
"v30", AArch64::Q30)
2670 .
Case(
"v31", AArch64::Q31)
2679 RegKind VectorKind) {
2680 std::pair<int, int> Res = {-1, -1};
2682 switch (VectorKind) {
2683 case RegKind::NeonVector:
2686 .Case(
".1d", {1, 64})
2687 .Case(
".1q", {1, 128})
2689 .Case(
".2h", {2, 16})
2690 .Case(
".2b", {2, 8})
2691 .Case(
".2s", {2, 32})
2692 .Case(
".2d", {2, 64})
2695 .Case(
".4b", {4, 8})
2696 .Case(
".4h", {4, 16})
2697 .Case(
".4s", {4, 32})
2698 .Case(
".8b", {8, 8})
2699 .Case(
".8h", {8, 16})
2700 .Case(
".16b", {16, 8})
2705 .Case(
".h", {0, 16})
2706 .Case(
".s", {0, 32})
2707 .Case(
".d", {0, 64})
2710 case RegKind::SVEPredicateAsCounter:
2711 case RegKind::SVEPredicateVector:
2712 case RegKind::SVEDataVector:
2713 case RegKind::Matrix:
2717 .Case(
".h", {0, 16})
2718 .Case(
".s", {0, 32})
2719 .Case(
".d", {0, 64})
2720 .Case(
".q", {0, 128})
2727 if (Res == std::make_pair(-1, -1))
2728 return std::nullopt;
2730 return std::optional<std::pair<int, int>>(Res);
2739 .
Case(
"z0", AArch64::Z0)
2740 .
Case(
"z1", AArch64::Z1)
2741 .
Case(
"z2", AArch64::Z2)
2742 .
Case(
"z3", AArch64::Z3)
2743 .
Case(
"z4", AArch64::Z4)
2744 .
Case(
"z5", AArch64::Z5)
2745 .
Case(
"z6", AArch64::Z6)
2746 .
Case(
"z7", AArch64::Z7)
2747 .
Case(
"z8", AArch64::Z8)
2748 .
Case(
"z9", AArch64::Z9)
2749 .
Case(
"z10", AArch64::Z10)
2750 .
Case(
"z11", AArch64::Z11)
2751 .
Case(
"z12", AArch64::Z12)
2752 .
Case(
"z13", AArch64::Z13)
2753 .
Case(
"z14", AArch64::Z14)
2754 .
Case(
"z15", AArch64::Z15)
2755 .
Case(
"z16", AArch64::Z16)
2756 .
Case(
"z17", AArch64::Z17)
2757 .
Case(
"z18", AArch64::Z18)
2758 .
Case(
"z19", AArch64::Z19)
2759 .
Case(
"z20", AArch64::Z20)
2760 .
Case(
"z21", AArch64::Z21)
2761 .
Case(
"z22", AArch64::Z22)
2762 .
Case(
"z23", AArch64::Z23)
2763 .
Case(
"z24", AArch64::Z24)
2764 .
Case(
"z25", AArch64::Z25)
2765 .
Case(
"z26", AArch64::Z26)
2766 .
Case(
"z27", AArch64::Z27)
2767 .
Case(
"z28", AArch64::Z28)
2768 .
Case(
"z29", AArch64::Z29)
2769 .
Case(
"z30", AArch64::Z30)
2770 .
Case(
"z31", AArch64::Z31)
2776 .
Case(
"p0", AArch64::P0)
2777 .
Case(
"p1", AArch64::P1)
2778 .
Case(
"p2", AArch64::P2)
2779 .
Case(
"p3", AArch64::P3)
2780 .
Case(
"p4", AArch64::P4)
2781 .
Case(
"p5", AArch64::P5)
2782 .
Case(
"p6", AArch64::P6)
2783 .
Case(
"p7", AArch64::P7)
2784 .
Case(
"p8", AArch64::P8)
2785 .
Case(
"p9", AArch64::P9)
2786 .
Case(
"p10", AArch64::P10)
2787 .
Case(
"p11", AArch64::P11)
2788 .
Case(
"p12", AArch64::P12)
2789 .
Case(
"p13", AArch64::P13)
2790 .
Case(
"p14", AArch64::P14)
2791 .
Case(
"p15", AArch64::P15)
2797 .
Case(
"pn0", AArch64::PN0)
2798 .
Case(
"pn1", AArch64::PN1)
2799 .
Case(
"pn2", AArch64::PN2)
2800 .
Case(
"pn3", AArch64::PN3)
2801 .
Case(
"pn4", AArch64::PN4)
2802 .
Case(
"pn5", AArch64::PN5)
2803 .
Case(
"pn6", AArch64::PN6)
2804 .
Case(
"pn7", AArch64::PN7)
2805 .
Case(
"pn8", AArch64::PN8)
2806 .
Case(
"pn9", AArch64::PN9)
2807 .
Case(
"pn10", AArch64::PN10)
2808 .
Case(
"pn11", AArch64::PN11)
2809 .
Case(
"pn12", AArch64::PN12)
2810 .
Case(
"pn13", AArch64::PN13)
2811 .
Case(
"pn14", AArch64::PN14)
2812 .
Case(
"pn15", AArch64::PN15)
2818 .
Case(
"za0.d", AArch64::ZAD0)
2819 .
Case(
"za1.d", AArch64::ZAD1)
2820 .
Case(
"za2.d", AArch64::ZAD2)
2821 .
Case(
"za3.d", AArch64::ZAD3)
2822 .
Case(
"za4.d", AArch64::ZAD4)
2823 .
Case(
"za5.d", AArch64::ZAD5)
2824 .
Case(
"za6.d", AArch64::ZAD6)
2825 .
Case(
"za7.d", AArch64::ZAD7)
2826 .
Case(
"za0.s", AArch64::ZAS0)
2827 .
Case(
"za1.s", AArch64::ZAS1)
2828 .
Case(
"za2.s", AArch64::ZAS2)
2829 .
Case(
"za3.s", AArch64::ZAS3)
2830 .
Case(
"za0.h", AArch64::ZAH0)
2831 .
Case(
"za1.h", AArch64::ZAH1)
2832 .
Case(
"za0.b", AArch64::ZAB0)
2838 .
Case(
"za", AArch64::ZA)
2839 .
Case(
"za0.q", AArch64::ZAQ0)
2840 .
Case(
"za1.q", AArch64::ZAQ1)
2841 .
Case(
"za2.q", AArch64::ZAQ2)
2842 .
Case(
"za3.q", AArch64::ZAQ3)
2843 .
Case(
"za4.q", AArch64::ZAQ4)
2844 .
Case(
"za5.q", AArch64::ZAQ5)
2845 .
Case(
"za6.q", AArch64::ZAQ6)
2846 .
Case(
"za7.q", AArch64::ZAQ7)
2847 .
Case(
"za8.q", AArch64::ZAQ8)
2848 .
Case(
"za9.q", AArch64::ZAQ9)
2849 .
Case(
"za10.q", AArch64::ZAQ10)
2850 .
Case(
"za11.q", AArch64::ZAQ11)
2851 .
Case(
"za12.q", AArch64::ZAQ12)
2852 .
Case(
"za13.q", AArch64::ZAQ13)
2853 .
Case(
"za14.q", AArch64::ZAQ14)
2854 .
Case(
"za15.q", AArch64::ZAQ15)
2855 .
Case(
"za0.d", AArch64::ZAD0)
2856 .
Case(
"za1.d", AArch64::ZAD1)
2857 .
Case(
"za2.d", AArch64::ZAD2)
2858 .
Case(
"za3.d", AArch64::ZAD3)
2859 .
Case(
"za4.d", AArch64::ZAD4)
2860 .
Case(
"za5.d", AArch64::ZAD5)
2861 .
Case(
"za6.d", AArch64::ZAD6)
2862 .
Case(
"za7.d", AArch64::ZAD7)
2863 .
Case(
"za0.s", AArch64::ZAS0)
2864 .
Case(
"za1.s", AArch64::ZAS1)
2865 .
Case(
"za2.s", AArch64::ZAS2)
2866 .
Case(
"za3.s", AArch64::ZAS3)
2867 .
Case(
"za0.h", AArch64::ZAH0)
2868 .
Case(
"za1.h", AArch64::ZAH1)
2869 .
Case(
"za0.b", AArch64::ZAB0)
2870 .
Case(
"za0h.q", AArch64::ZAQ0)
2871 .
Case(
"za1h.q", AArch64::ZAQ1)
2872 .
Case(
"za2h.q", AArch64::ZAQ2)
2873 .
Case(
"za3h.q", AArch64::ZAQ3)
2874 .
Case(
"za4h.q", AArch64::ZAQ4)
2875 .
Case(
"za5h.q", AArch64::ZAQ5)
2876 .
Case(
"za6h.q", AArch64::ZAQ6)
2877 .
Case(
"za7h.q", AArch64::ZAQ7)
2878 .
Case(
"za8h.q", AArch64::ZAQ8)
2879 .
Case(
"za9h.q", AArch64::ZAQ9)
2880 .
Case(
"za10h.q", AArch64::ZAQ10)
2881 .
Case(
"za11h.q", AArch64::ZAQ11)
2882 .
Case(
"za12h.q", AArch64::ZAQ12)
2883 .
Case(
"za13h.q", AArch64::ZAQ13)
2884 .
Case(
"za14h.q", AArch64::ZAQ14)
2885 .
Case(
"za15h.q", AArch64::ZAQ15)
2886 .
Case(
"za0h.d", AArch64::ZAD0)
2887 .
Case(
"za1h.d", AArch64::ZAD1)
2888 .
Case(
"za2h.d", AArch64::ZAD2)
2889 .
Case(
"za3h.d", AArch64::ZAD3)
2890 .
Case(
"za4h.d", AArch64::ZAD4)
2891 .
Case(
"za5h.d", AArch64::ZAD5)
2892 .
Case(
"za6h.d", AArch64::ZAD6)
2893 .
Case(
"za7h.d", AArch64::ZAD7)
2894 .
Case(
"za0h.s", AArch64::ZAS0)
2895 .
Case(
"za1h.s", AArch64::ZAS1)
2896 .
Case(
"za2h.s", AArch64::ZAS2)
2897 .
Case(
"za3h.s", AArch64::ZAS3)
2898 .
Case(
"za0h.h", AArch64::ZAH0)
2899 .
Case(
"za1h.h", AArch64::ZAH1)
2900 .
Case(
"za0h.b", AArch64::ZAB0)
2901 .
Case(
"za0v.q", AArch64::ZAQ0)
2902 .
Case(
"za1v.q", AArch64::ZAQ1)
2903 .
Case(
"za2v.q", AArch64::ZAQ2)
2904 .
Case(
"za3v.q", AArch64::ZAQ3)
2905 .
Case(
"za4v.q", AArch64::ZAQ4)
2906 .
Case(
"za5v.q", AArch64::ZAQ5)
2907 .
Case(
"za6v.q", AArch64::ZAQ6)
2908 .
Case(
"za7v.q", AArch64::ZAQ7)
2909 .
Case(
"za8v.q", AArch64::ZAQ8)
2910 .
Case(
"za9v.q", AArch64::ZAQ9)
2911 .
Case(
"za10v.q", AArch64::ZAQ10)
2912 .
Case(
"za11v.q", AArch64::ZAQ11)
2913 .
Case(
"za12v.q", AArch64::ZAQ12)
2914 .
Case(
"za13v.q", AArch64::ZAQ13)
2915 .
Case(
"za14v.q", AArch64::ZAQ14)
2916 .
Case(
"za15v.q", AArch64::ZAQ15)
2917 .
Case(
"za0v.d", AArch64::ZAD0)
2918 .
Case(
"za1v.d", AArch64::ZAD1)
2919 .
Case(
"za2v.d", AArch64::ZAD2)
2920 .
Case(
"za3v.d", AArch64::ZAD3)
2921 .
Case(
"za4v.d", AArch64::ZAD4)
2922 .
Case(
"za5v.d", AArch64::ZAD5)
2923 .
Case(
"za6v.d", AArch64::ZAD6)
2924 .
Case(
"za7v.d", AArch64::ZAD7)
2925 .
Case(
"za0v.s", AArch64::ZAS0)
2926 .
Case(
"za1v.s", AArch64::ZAS1)
2927 .
Case(
"za2v.s", AArch64::ZAS2)
2928 .
Case(
"za3v.s", AArch64::ZAS3)
2929 .
Case(
"za0v.h", AArch64::ZAH0)
2930 .
Case(
"za1v.h", AArch64::ZAH1)
2931 .
Case(
"za0v.b", AArch64::ZAB0)
2935bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2937 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2940ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2942 StartLoc = getLoc();
2943 ParseStatus Res = tryParseScalarRegister(
Reg);
2949MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2951 MCRegister
Reg = MCRegister();
2953 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2956 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2959 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2962 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2965 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2967 if (
Name.equals_insensitive(
"zt0"))
2968 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2972 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2976 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2977 .Case(
"fp", AArch64::FP)
2978 .Case(
"lr", AArch64::LR)
2979 .Case(
"x31", AArch64::XZR)
2980 .Case(
"w31", AArch64::WZR)
2982 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2988 if (Entry == RegisterReqs.
end())
2989 return MCRegister();
2992 if (Kind ==
Entry->getValue().first)
2998unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3000 case RegKind::Scalar:
3001 case RegKind::NeonVector:
3002 case RegKind::SVEDataVector:
3004 case RegKind::Matrix:
3005 case RegKind::SVEPredicateVector:
3006 case RegKind::SVEPredicateAsCounter:
3008 case RegKind::LookupTable:
3017ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3018 const AsmToken &Tok = getTok();
3023 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3037 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3040 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3041 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3045 if (BadNum || CRNum > 15)
3046 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3050 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3057 const AsmToken &Tok = getTok();
3059 unsigned MaxVal = 63;
3064 const MCExpr *ImmVal;
3065 if (getParser().parseExpression(ImmVal))
3070 return TokError(
"immediate value expected for prefetch operand");
3073 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3076 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3077 Operands.push_back(AArch64Operand::CreatePrefetch(
3078 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3084 return TokError(
"prefetch hint expected");
3086 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3088 return TokError(
"prefetch hint expected");
3090 Operands.push_back(AArch64Operand::CreatePrefetch(
3097template <
bool IsSVEPrefetch>
3100 const AsmToken &Tok = getTok();
3102 auto LookupByName = [](StringRef
N) {
3103 if (IsSVEPrefetch) {
3104 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3105 return std::optional<unsigned>(Res->Encoding);
3106 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3107 return std::optional<unsigned>(Res->Encoding);
3108 return std::optional<unsigned>();
3111 auto LookupByEncoding = [](
unsigned E) {
3112 if (IsSVEPrefetch) {
3113 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3114 return std::optional<StringRef>(
3115 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3116 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3117 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3118 return std::optional<StringRef>();
3120 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3126 const MCExpr *ImmVal;
3127 if (getParser().parseExpression(ImmVal))
3132 return TokError(
"immediate value expected for prefetch operand");
3135 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3138 auto PRFM = LookupByEncoding(MCE->
getValue());
3139 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3145 return TokError(
"prefetch hint expected");
3147 auto PRFM = LookupByName(Tok.
getString());
3149 return TokError(
"prefetch hint expected");
3151 Operands.push_back(AArch64Operand::CreatePrefetch(
3158 SMLoc StartLoc = getLoc();
3164 auto RegTok = getTok();
3165 if (!tryParseScalarRegister(RegNum).isSuccess())
3168 if (RegNum != AArch64::XZR) {
3169 getLexer().UnLex(RegTok);
3176 if (!tryParseScalarRegister(RegNum).isSuccess())
3177 return TokError(
"expected register operand");
3179 if (RegNum != AArch64::XZR)
3180 return TokError(
"xzr must be followed by xzr");
3184 Operands.push_back(AArch64Operand::CreateReg(
3185 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3193 const AsmToken &Tok = getTok();
3195 return TokError(
"invalid operand for instruction");
3197 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3199 return TokError(
"invalid operand for instruction");
3201 Operands.push_back(AArch64Operand::CreateTIndexHint(
3211 const MCExpr *Expr =
nullptr;
3217 if (parseSymbolicImmVal(Expr))
3223 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3232 return Error(S,
"gotpage label reference not allowed an addend");
3244 return Error(S,
"page or gotpage label reference expected");
3261 const MCExpr *Expr =
nullptr;
3270 if (parseSymbolicImmVal(Expr))
3276 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3288 return Error(S,
"unexpected adr label");
3298template <
bool AddFPZeroAsLiteral>
3307 const AsmToken &Tok = getTok();
3311 return TokError(
"invalid floating point immediate");
3316 if (Tok.
getIntVal() > 255 || isNegative)
3317 return TokError(
"encoded floating point value out of range");
3321 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3324 APFloat RealVal(APFloat::IEEEdouble());
3326 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3328 return TokError(
"invalid floating point representation");
3331 RealVal.changeSign();
3333 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3337 Operands.push_back(AArch64Operand::CreateFPImm(
3338 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3362 const MCExpr *
Imm =
nullptr;
3363 if (parseSymbolicImmVal(
Imm))
3374 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3378 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3384 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3385 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3393 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3395 int64_t ShiftAmount = getTok().getIntVal();
3397 if (ShiftAmount < 0)
3398 return Error(getLoc(),
"positive shift amount required");
3402 if (ShiftAmount == 0 &&
Imm !=
nullptr) {
3408 Operands.push_back(AArch64Operand::CreateShiftedImm(
Imm, ShiftAmount, S,
3416AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3450 Suggestion =
"nfrst";
3457 bool invertCondCode) {
3459 const AsmToken &Tok = getTok();
3463 std::string Suggestion;
3466 std::string
Msg =
"invalid condition code";
3467 if (!Suggestion.empty())
3468 Msg +=
", did you mean " + Suggestion +
"?";
3469 return TokError(
Msg);
3473 if (invertCondCode) {
3475 return TokError(
"condition codes AL and NV are invalid for this instruction");
3480 AArch64Operand::CreateCondCode(
CC, S, getLoc(),
getContext()));
3485 const AsmToken &Tok = getTok();
3489 return TokError(
"invalid operand for instruction");
3491 unsigned PStateImm = -1;
3492 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3495 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3496 PStateImm = SVCR->Encoding;
3505 const AsmToken &Tok = getTok();
3510 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3512 unsigned ElementWidth = 0;
3513 auto DotPosition =
Name.find(
'.');
3515 const auto &KindRes =
3519 "Expected the register to be followed by element width suffix");
3520 ElementWidth = KindRes->second;
3522 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3523 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3528 if (parseOperand(
Operands,
false,
false))
3535 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3539 size_t DotPosition =
Name.find(
'.');
3542 StringRef Head =
Name.take_front(DotPosition);
3543 StringRef
Tail =
Name.drop_front(DotPosition);
3544 StringRef RowOrColumn = Head.
take_back();
3546 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3547 .Case(
"h", MatrixKind::Row)
3548 .Case(
"v", MatrixKind::Col)
3549 .Default(MatrixKind::Tile);
3555 "Expected the register to be followed by element width suffix");
3556 unsigned ElementWidth = KindRes->second;
3560 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3566 if (parseOperand(
Operands,
false,
false))
3576 const AsmToken &Tok = getTok();
3579 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3608 return TokError(
"expected #imm after shift specifier");
3614 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3623 return Error(
E,
"expected integer shift amount");
3625 const MCExpr *ImmVal;
3626 if (getParser().parseExpression(ImmVal))
3631 return Error(
E,
"expected constant '#imm' after shift specifier");
3634 Operands.push_back(AArch64Operand::CreateShiftExtend(
3640 {{
"crc"}, {AArch64::FeatureCRC}},
3641 {{
"sm4"}, {AArch64::FeatureSM4}},
3642 {{
"sha3"}, {AArch64::FeatureSHA3}},
3643 {{
"sha2"}, {AArch64::FeatureSHA2}},
3644 {{
"aes"}, {AArch64::FeatureAES}},
3645 {{
"crypto"}, {AArch64::FeatureCrypto}},
3646 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3647 {{
"simd"}, {AArch64::FeatureNEON}},
3648 {{
"ras"}, {AArch64::FeatureRAS}},
3649 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3650 {{
"lse"}, {AArch64::FeatureLSE}},
3651 {{
"predres"}, {AArch64::FeaturePredRes}},
3652 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3653 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3654 {{
"mte"}, {AArch64::FeatureMTE}},
3655 {{
"memtag"}, {AArch64::FeatureMTE}},
3656 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3657 {{
"pan"}, {AArch64::FeaturePAN}},
3658 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3659 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3660 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3661 {{
"rng"}, {AArch64::FeatureRandGen}},
3662 {{
"sve"}, {AArch64::FeatureSVE}},
3663 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3664 {{
"sve2"}, {AArch64::FeatureSVE2}},
3665 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3666 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3667 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3668 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3669 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3670 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3671 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3673 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3674 AArch64::FeatureSVE2}},
3675 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3676 {{
"ls64"}, {AArch64::FeatureLS64}},
3677 {{
"xs"}, {AArch64::FeatureXS}},
3678 {{
"pauth"}, {AArch64::FeaturePAuth}},
3679 {{
"flagm"}, {AArch64::FeatureFlagM}},
3680 {{
"rme"}, {AArch64::FeatureRME}},
3681 {{
"sme"}, {AArch64::FeatureSME}},
3682 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3683 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3684 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3685 {{
"sme2"}, {AArch64::FeatureSME2}},
3686 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3687 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3688 {{
"hbc"}, {AArch64::FeatureHBC}},
3689 {{
"mops"}, {AArch64::FeatureMOPS}},
3690 {{
"mec"}, {AArch64::FeatureMEC}},
3691 {{
"the"}, {AArch64::FeatureTHE}},
3692 {{
"d128"}, {AArch64::FeatureD128}},
3693 {{
"lse128"}, {AArch64::FeatureLSE128}},
3694 {{
"ite"}, {AArch64::FeatureITE}},
3695 {{
"cssc"}, {AArch64::FeatureCSSC}},
3696 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3697 {{
"gcs"}, {AArch64::FeatureGCS}},
3698 {{
"bf16"}, {AArch64::FeatureBF16}},
3699 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3700 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3701 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3702 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3703 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3704 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3705 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3706 {{
"lor"}, {AArch64::FeatureLOR}},
3707 {{
"profile"}, {AArch64::FeatureSPE}},
3711 {{
"rdm"}, {AArch64::FeatureRDM}},
3712 {{
"rdma"}, {AArch64::FeatureRDM}},
3713 {{
"sb"}, {AArch64::FeatureSB}},
3714 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3715 {{
"fp8"}, {AArch64::FeatureFP8}},
3716 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3717 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3718 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3719 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3720 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3721 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3722 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3723 {{
"lut"}, {AArch64::FeatureLUT}},
3724 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3725 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3726 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3727 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3728 {{
"cpa"}, {AArch64::FeatureCPA}},
3729 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3730 {{
"pops"}, {AArch64::FeaturePoPS}},
3731 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3732 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3733 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3734 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3735 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3736 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3737 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3738 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3739 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3740 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3741 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3742 {{
"lsui"}, {AArch64::FeatureLSUI}},
3743 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3744 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3745 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3746 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3747 {{
"lscp"}, {AArch64::FeatureLSCP}},
3748 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3749 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3750 {{
"gcie"}, {AArch64::FeatureGCIE}},
3751 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3752 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3753 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3754 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3755 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3756 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3757 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3758 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3759 {{
"tev"}, {AArch64::FeatureTEV}},
3760 {{
"btie"}, {AArch64::FeatureBTIE}},
3761 {{
"hinte"}, {AArch64::FeatureHINTE}},
3762 {{
"dit"}, {AArch64::FeatureDIT}},
3763 {{
"brbe"}, {AArch64::FeatureBRBE}},
3764 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3765 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3766 {{
"jscvt"}, {AArch64::FeatureJS}},
3767 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3768 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3769 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3770 {{
"cflt"}, {AArch64::FeatureCFLT}},
3771 {{
"lsc64b"}, {AArch64::FeatureLSC64B}},
3772 {{
"sve-lrcpc"}, {AArch64::FeatureSVE_LRCPC}},
3773 {{
"sve-perm256"}, {AArch64::FeatureSVE_PERM256}},
3774 {{
"sme-f16f8f16"}, {AArch64::FeatureSMEF16F8F16}},
3775 {{
"fpv2"}, {AArch64::FeatureFPv2}},
3780 if (FBS[AArch64::HasV8_0aOps])
3782 if (FBS[AArch64::HasV8_1aOps])
3784 else if (FBS[AArch64::HasV8_2aOps])
3786 else if (FBS[AArch64::HasV8_3aOps])
3788 else if (FBS[AArch64::HasV8_4aOps])
3790 else if (FBS[AArch64::HasV8_5aOps])
3792 else if (FBS[AArch64::HasV8_6aOps])
3794 else if (FBS[AArch64::HasV8_7aOps])
3796 else if (FBS[AArch64::HasV8_8aOps])
3798 else if (FBS[AArch64::HasV8_9aOps])
3800 else if (FBS[AArch64::HasV9_0aOps])
3802 else if (FBS[AArch64::HasV9_1aOps])
3804 else if (FBS[AArch64::HasV9_2aOps])
3806 else if (FBS[AArch64::HasV9_3aOps])
3808 else if (FBS[AArch64::HasV9_4aOps])
3810 else if (FBS[AArch64::HasV9_5aOps])
3812 else if (FBS[AArch64::HasV9_6aOps])
3814 else if (FBS[AArch64::HasV9_7aOps])
3816 else if (FBS[AArch64::HasV9_8aOps])
3818 else if (FBS[AArch64::HasV8_0rOps])
3827 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3833 const uint16_t Op2 = Encoding & 7;
3834 const uint16_t Cm = (Encoding & 0x78) >> 3;
3835 const uint16_t Cn = (Encoding & 0x780) >> 7;
3836 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3841 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3843 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3845 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3848 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3854bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3856 if (
Name.contains(
'.'))
3857 return TokError(
"invalid operand");
3862 const AsmToken &Tok = getTok();
3865 bool ExpectRegister =
true;
3866 bool OptionalRegister =
false;
3867 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3868 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3870 if (Mnemonic ==
"ic") {
3871 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3873 return TokError(
"invalid operand for IC instruction");
3874 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3875 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3878 return TokError(Str);
3882 }
else if (Mnemonic ==
"dc") {
3883 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3885 return TokError(
"invalid operand for DC instruction");
3886 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3887 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3890 return TokError(Str);
3893 }
else if (Mnemonic ==
"at") {
3894 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3896 return TokError(
"invalid operand for AT instruction");
3897 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3898 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3901 return TokError(Str);
3904 }
else if (Mnemonic ==
"tlbi") {
3905 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3907 return TokError(
"invalid operand for TLBI instruction");
3908 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3909 std::string Str(
"TLBI " +
3910 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3913 return TokError(Str);
3915 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3916 if (hasAll || hasTLBID)
3917 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3919 }
else if (Mnemonic ==
"gic") {
3920 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3922 return TokError(
"invalid operand for GIC instruction");
3923 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3924 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3927 return TokError(Str);
3931 }
else if (Mnemonic ==
"gsb") {
3932 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3934 return TokError(
"invalid operand for GSB instruction");
3935 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3936 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3939 return TokError(Str);
3941 ExpectRegister =
false;
3943 }
else if (Mnemonic ==
"plbi") {
3944 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3946 return TokError(
"invalid operand for PLBI instruction");
3947 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3948 std::string Str(
"PLBI " +
3949 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3952 return TokError(Str);
3954 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3955 if (hasAll || hasTLBID)
3956 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3958 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3959 Mnemonic ==
"cosp") {
3961 if (
Op.lower() !=
"rctx")
3962 return TokError(
"invalid operand for prediction restriction instruction");
3964 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3965 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3967 if (Mnemonic ==
"cosp" && !hasSpecres2)
3968 return TokError(
"COSP requires: predres2");
3970 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3972 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3973 : Mnemonic ==
"dvp" ? 0b101
3974 : Mnemonic ==
"cosp" ? 0b110
3975 : Mnemonic ==
"cpp" ? 0b111
3978 "Invalid mnemonic for prediction restriction instruction");
3979 const auto SYS_3_7_3 = 0b01101110011;
3980 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3982 createSysAlias(Encoding,
Operands, S);
3987 bool HasRegister =
false;
3992 return TokError(
"expected register operand");
3996 if (!OptionalRegister) {
3997 if (ExpectRegister && !HasRegister)
3998 return TokError(
"specified " + Mnemonic +
" op requires a register");
3999 else if (!ExpectRegister && HasRegister)
4000 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4012bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4017 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4020 SMLoc startLoc = getLoc();
4021 const AsmToken ®Tok = getTok();
4023 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4025 return TokError(
"expected register operand");
4027 Operands.push_back(AArch64Operand::CreateReg(
4028 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4035 const AsmToken &operandTok = getTok();
4037 SMLoc S2 = operandTok.
getLoc();
4040 if (Mnemonic ==
"gicr") {
4041 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4043 return Error(S2,
"invalid operand for GICR instruction");
4044 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4045 std::string Str(
"GICR " +
4046 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4049 return Error(S2, Str);
4062bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4064 if (
Name.contains(
'.'))
4065 return TokError(
"invalid operand");
4069 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4071 const AsmToken &Tok = getTok();
4075 if (Mnemonic ==
"tlbip") {
4076 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4078 return TokError(
"invalid operand for TLBIP instruction");
4081 std::string Str(
"instruction requires: ");
4083 return TokError(Str);
4094 return TokError(
"expected register identifier");
4099 return TokError(
"specified " + Mnemonic +
4100 " op requires a pair of registers");
4109 MCAsmParser &Parser = getParser();
4110 const AsmToken &Tok = getTok();
4114 const MCExpr *ImmVal;
4115 SMLoc ExprLoc = getLoc();
4116 AsmToken IntTok = Tok;
4117 if (getParser().parseExpression(ImmVal))
4121 return Error(ExprLoc,
"immediate value expected for barrier operand");
4123 if (Mnemonic ==
"dsb" &&
Value > 15) {
4131 return Error(ExprLoc,
"barrier operand out of range");
4132 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4133 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4134 Operands.push_back(AArch64Operand::CreateBarrier(
4140 return TokError(
"invalid operand for instruction");
4143 auto DB = AArch64DB::lookupDBByName(Operand);
4145 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4146 return TokError(
"'sy' or #imm operand expected");
4148 if (Mnemonic ==
"dsb") {
4153 return TokError(
"invalid barrier option name");
4157 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4166 const AsmToken &Tok = getTok();
4168 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4169 if (Mnemonic !=
"dsb")
4174 const MCExpr *ImmVal;
4175 SMLoc ExprLoc = getLoc();
4176 if (getParser().parseExpression(ImmVal))
4180 return Error(ExprLoc,
"immediate value expected for barrier operand");
4185 return Error(ExprLoc,
"barrier operand out of range");
4186 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4187 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4188 Operands.push_back(AArch64Operand::CreateBarrier(
4194 return TokError(
"invalid operand for instruction");
4197 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4200 return TokError(
"invalid barrier option name");
4203 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4211 const AsmToken &Tok = getTok();
4216 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4220 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4221 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4222 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4223 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4227 unsigned PStateImm = -1;
4228 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4229 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4230 PStateImm = PState15->Encoding;
4232 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4233 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4234 PStateImm = PState1->Encoding;
4238 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4254 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4262 unsigned ElementWidth = KindRes->second;
4264 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4272 return tryParseVectorIndex(
Operands).isFailure();
4276 SMLoc SIdx = getLoc();
4278 const MCExpr *ImmVal;
4279 if (getParser().parseExpression(ImmVal))
4283 return TokError(
"immediate value expected for vector index");
4290 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4301ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4303 RegKind MatchKind) {
4304 const AsmToken &Tok = getTok();
4313 StringRef Head =
Name.slice(Start,
Next);
4314 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4320 return TokError(
"invalid vector kind qualifier");
4331ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4333 ParseStatus Status =
4334 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4336 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4341template <RegKind RK>
4345 const SMLoc S = getLoc();
4348 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4356 unsigned ElementWidth = KindRes->second;
4357 Operands.push_back(AArch64Operand::CreateVectorReg(
4358 RegNum, RK, ElementWidth, S,
4362 if (RK == RegKind::SVEPredicateAsCounter) {
4363 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4369 if (parseOperand(
Operands,
false,
false))
4380 return Error(S,
"not expecting size suffix");
4388 auto Pred = getTok().getString().lower();
4389 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4390 return Error(getLoc(),
"expecting 'z' predication");
4392 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4393 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4396 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4406 if (!tryParseNeonVectorRegister(
Operands))
4409 if (tryParseZTOperand(
Operands).isSuccess())
4413 if (tryParseGPROperand<false>(
Operands).isSuccess())
4419bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4420 bool HasELFModifier =
false;
4422 SMLoc Loc = getLexer().getLoc();
4424 HasELFModifier =
true;
4427 return TokError(
"expect relocation specifier in operand after ':'");
4429 std::string LowerCase = getTok().getIdentifier().lower();
4430 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4485 return TokError(
"expect relocation specifier in operand after ':'");
4489 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4493 if (getParser().parseExpression(ImmVal))
4501 if (!HasELFModifier &&
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4502 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4512 if (getParser().parsePrimaryExpr(Term, EndLoc))
4524 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4525 unsigned &ElementWidth) -> ParseStatus {
4526 StringRef
Name = getTok().getString();
4527 size_t DotPosition =
Name.find(
'.');
4535 StringRef
Tail =
Name.drop_front(DotPosition);
4536 const std::optional<std::pair<int, int>> &KindRes =
4540 "Expected the register to be followed by element width suffix");
4541 ElementWidth = KindRes->second;
4548 auto LCurly = getTok();
4553 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4559 if (getTok().getString().equals_insensitive(
"za")) {
4565 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4570 SMLoc TileLoc = getLoc();
4572 unsigned FirstReg, ElementWidth;
4573 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4574 if (!ParseRes.isSuccess()) {
4575 getLexer().UnLex(LCurly);
4579 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4581 unsigned PrevReg = FirstReg;
4583 SmallSet<unsigned, 8> DRegs;
4584 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4586 SmallSet<unsigned, 8> SeenRegs;
4587 SeenRegs.
insert(FirstReg);
4591 unsigned Reg, NextElementWidth;
4592 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4593 if (!ParseRes.isSuccess())
4597 if (ElementWidth != NextElementWidth)
4598 return Error(TileLoc,
"mismatched register size suffix");
4601 Warning(TileLoc,
"tile list not in ascending order");
4604 Warning(TileLoc,
"duplicate tile in list");
4607 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4616 unsigned RegMask = 0;
4617 for (
auto Reg : DRegs)
4621 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4626template <RegKind VectorKind>
4629 MCAsmParser &Parser = getParser();
4634 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4635 bool NoMatchIsError) -> ParseStatus {
4636 auto RegTok = getTok();
4637 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4638 if (ParseRes.isSuccess()) {
4645 RegTok.getString().equals_insensitive(
"zt0"))
4649 (ParseRes.isNoMatch() && NoMatchIsError &&
4650 !RegTok.getString().starts_with_insensitive(
"za")))
4651 return Error(Loc,
"vector register expected");
4656 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4658 auto LCurly = getTok();
4662 MCRegister FirstReg;
4663 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4667 if (ParseRes.isNoMatch())
4670 if (!ParseRes.isSuccess())
4673 MCRegister PrevReg = FirstReg;
4676 unsigned Stride = 1;
4678 SMLoc Loc = getLoc();
4682 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4683 if (!ParseRes.isSuccess())
4687 if (Kind != NextKind)
4688 return Error(Loc,
"mismatched register size suffix");
4691 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4693 if (Space == 0 || Space > 3)
4694 return Error(Loc,
"invalid number of vectors");
4699 bool HasCalculatedStride =
false;
4701 SMLoc Loc = getLoc();
4704 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4705 if (!ParseRes.isSuccess())
4709 if (Kind != NextKind)
4710 return Error(Loc,
"mismatched register size suffix");
4712 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4713 unsigned PrevRegVal =
4714 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4715 if (!HasCalculatedStride) {
4716 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4717 : (NumRegs - (PrevRegVal - RegVal));
4718 HasCalculatedStride =
true;
4722 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4723 return Error(Loc,
"registers must have the same sequential stride");
4734 return Error(S,
"invalid number of vectors");
4736 unsigned NumElements = 0;
4737 unsigned ElementWidth = 0;
4738 if (!
Kind.empty()) {
4740 std::tie(NumElements, ElementWidth) = *VK;
4743 Operands.push_back(AArch64Operand::CreateVectorList(
4744 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4748 ParseStatus Res = tryParseVectorIndex(
Operands);
4759 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4760 if (!ParseRes.isSuccess())
4763 return tryParseVectorIndex(
Operands).isFailure();
4767 SMLoc StartLoc = getLoc();
4770 ParseStatus Res = tryParseScalarRegister(RegNum);
4775 Operands.push_back(AArch64Operand::CreateReg(
4776 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4783 return Error(getLoc(),
"index must be absent or #0");
4785 const MCExpr *ImmVal;
4788 return Error(getLoc(),
"index must be absent or #0");
4790 Operands.push_back(AArch64Operand::CreateReg(
4791 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4796 SMLoc StartLoc = getLoc();
4797 const AsmToken &Tok = getTok();
4800 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4805 Operands.push_back(AArch64Operand::CreateReg(
4806 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4812 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4813 const MCExpr *ImmVal;
4814 if (getParser().parseExpression(ImmVal))
4818 return TokError(
"immediate value expected for vector index");
4819 Operands.push_back(AArch64Operand::CreateImm(
4823 if (parseOptionalMulOperand(
Operands))
4828 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4833template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4835 SMLoc StartLoc = getLoc();
4838 ParseStatus Res = tryParseScalarRegister(RegNum);
4844 Operands.push_back(AArch64Operand::CreateReg(
4845 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4854 Res = tryParseOptionalShiftExtend(ExtOpnd);
4858 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4859 Operands.push_back(AArch64Operand::CreateReg(
4860 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4861 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4862 Ext->hasShiftExtendAmount()));
4868 MCAsmParser &Parser = getParser();
4876 if (!getTok().getString().equals_insensitive(
"mul") ||
4877 !(NextIsVL || NextIsHash))
4881 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4886 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4896 const MCExpr *ImmVal;
4899 Operands.push_back(AArch64Operand::CreateImm(
4906 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4910 StringRef &VecGroup) {
4911 MCAsmParser &Parser = getParser();
4912 auto Tok = Parser.
getTok();
4917 .Case(
"vgx2",
"vgx2")
4918 .Case(
"vgx4",
"vgx4")
4930 auto Tok = getTok();
4937 .Case(
"csync",
"csync")
4940 .Case(
"keep",
"keep")
4944 .Case(
"stshstrm",
"stshstrm")
4945 .Case(
"strm",
"strm")
4958 bool invertCondCode) {
4959 MCAsmParser &Parser = getParser();
4962 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4976 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4978 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4981 getLexer().UnLex(SavedTok);
4985 switch (getLexer().getKind()) {
4989 if (parseSymbolicImmVal(Expr))
4990 return Error(S,
"invalid operand");
4994 return parseOptionalShiftExtend(getTok());
4998 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
5003 return parseOperand(
Operands,
false,
false);
5006 if (!parseNeonVectorList(
Operands))
5010 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5015 return parseOperand(
Operands,
false,
false);
5020 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
5022 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5032 AsmToken SavedTok = getTok();
5037 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5041 Res = tryParseOptionalShiftExtend(
Operands);
5044 getLexer().UnLex(SavedTok);
5051 if (!parseOptionalMulOperand(
Operands))
5056 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5057 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5058 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh" ||
5060 return parseKeywordOperand(
Operands);
5064 const MCExpr *IdVal, *
Term;
5066 if (getParser().parseExpression(IdVal))
5068 if (getParser().parseAtSpecifier(IdVal,
E))
5070 std::optional<MCBinaryExpr::Opcode> Opcode;
5076 if (getParser().parsePrimaryExpr(Term,
E))
5083 return parseOptionalShiftExtend(getTok());
5094 bool isNegative =
false;
5106 const AsmToken &Tok = getTok();
5110 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5111 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5112 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5113 return TokError(
"unexpected floating point literal");
5114 else if (IntVal != 0 || isNegative)
5115 return TokError(
"expected floating-point constant #0.0");
5123 const MCExpr *ImmVal;
5124 if (parseSymbolicImmVal(ImmVal))
5131 return parseOptionalShiftExtend(Tok);
5134 SMLoc Loc = getLoc();
5135 if (Mnemonic !=
"ldr")
5136 return TokError(
"unexpected token in operand");
5138 const MCExpr *SubExprVal;
5139 if (getParser().parseExpression(SubExprVal))
5143 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5144 return Error(Loc,
"Only valid when first operand is register");
5146 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5154 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5159 if (ShiftAmt <= MaxShiftAmt &&
Imm <= 0xFFFF) {
5160 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5161 Operands.push_back(AArch64Operand::CreateImm(
5165 ShiftAmt,
true, S,
E, Ctx));
5168 APInt Simm = APInt(64,
Imm << ShiftAmt);
5171 return Error(Loc,
"Immediate too large for register");
5174 const MCExpr *CPLoc =
5175 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5176 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5182bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5183 const MCExpr *Expr =
nullptr;
5185 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5188 if (check(!
Value, L,
"expected constant expression"))
5194bool AArch64AsmParser::parseComma() {
5202bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5206 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register"))
5211 unsigned RangeEnd =
Last;
5212 if (
Base == AArch64::X0) {
5213 if (
Last == AArch64::FP) {
5214 RangeEnd = AArch64::X28;
5215 if (
Reg == AArch64::FP) {
5220 if (
Last == AArch64::LR) {
5221 RangeEnd = AArch64::X28;
5222 if (
Reg == AArch64::FP) {
5225 }
else if (
Reg == AArch64::LR) {
5233 Twine(
"expected register in range ") +
5241bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5242 const MCParsedAsmOperand &Op2)
const {
5243 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5244 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5246 if (AOp1.isVectorList() && AOp2.isVectorList())
5247 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5248 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5249 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5251 if (!AOp1.isReg() || !AOp2.isReg())
5254 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5255 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5258 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5259 "Testing equality of non-scalar registers not supported");
5262 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5264 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5266 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5268 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5275bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5276 StringRef Name, SMLoc NameLoc,
5278 Name = StringSwitch<StringRef>(
Name.lower())
5279 .Case(
"beq",
"b.eq")
5280 .Case(
"bne",
"b.ne")
5281 .Case(
"bhs",
"b.hs")
5282 .Case(
"bcs",
"b.cs")
5283 .Case(
"blo",
"b.lo")
5284 .Case(
"bcc",
"b.cc")
5285 .Case(
"bmi",
"b.mi")
5286 .Case(
"bpl",
"b.pl")
5287 .Case(
"bvs",
"b.vs")
5288 .Case(
"bvc",
"b.vc")
5289 .Case(
"bhi",
"b.hi")
5290 .Case(
"bls",
"b.ls")
5291 .Case(
"bge",
"b.ge")
5292 .Case(
"blt",
"b.lt")
5293 .Case(
"bgt",
"b.gt")
5294 .Case(
"ble",
"b.le")
5295 .Case(
"bal",
"b.al")
5296 .Case(
"bnv",
"b.nv")
5301 getTok().getIdentifier().lower() ==
".req") {
5302 parseDirectiveReq(Name, NameLoc);
5310 StringRef Head =
Name.slice(Start,
Next);
5314 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5315 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5316 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5317 return parseSysAlias(Head, NameLoc,
Operands);
5321 return parseSyslAlias(Head, NameLoc,
Operands);
5324 if (Head ==
"tlbip")
5325 return parseSyspAlias(Head, NameLoc,
Operands);
5331 if ((Head ==
"b" || Head ==
"bc" || Head ==
"flt") &&
5335 Head =
Name.slice(Start + 1,
Next);
5339 std::string Suggestion;
5342 std::string
Msg =
"invalid condition code";
5343 if (!Suggestion.empty())
5344 Msg +=
", did you mean " + Suggestion +
"?";
5350 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc,
getContext()));
5360 Operands.push_back(AArch64Operand::CreateToken(
5366 bool condCodeFourthOperand =
5367 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5368 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5369 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5377 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5378 bool condCodeThirdOperand =
5379 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5387 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5388 (
N == 3 && condCodeThirdOperand) ||
5389 (
N == 2 && condCodeSecondOperand),
5390 condCodeSecondOperand || condCodeThirdOperand)) {
5410 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5413 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5416 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5429 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5430 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5431 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5432 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5433 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5434 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5435 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5447bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5448 SmallVectorImpl<SMLoc> &Loc) {
5449 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5456 PrefixInfo
Prefix = NextPrefix;
5457 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5468 return Error(IDLoc,
"instruction is unpredictable when following a"
5469 " movprfx, suggest replacing movprfx with mov");
5473 return Error(Loc[0],
"instruction is unpredictable when following a"
5474 " movprfx writing to a different destination");
5481 return Error(Loc[0],
"instruction is unpredictable when following a"
5482 " movprfx and destination also used as non-destructive"
5486 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5487 if (
Prefix.isPredicated()) {
5501 return Error(IDLoc,
"instruction is unpredictable when following a"
5502 " predicated movprfx, suggest using unpredicated movprfx");
5506 return Error(IDLoc,
"instruction is unpredictable when following a"
5507 " predicated movprfx using a different general predicate");
5511 return Error(IDLoc,
"instruction is unpredictable when following a"
5512 " predicated movprfx with a different element size");
5518 if (IsWindowsArm64EC) {
5524 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5525 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5526 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5527 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5528 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5529 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5530 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5531 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5532 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5533 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5535 " is disallowed on ARM64EC.");
5545 case AArch64::LDPSWpre:
5546 case AArch64::LDPWpost:
5547 case AArch64::LDPWpre:
5548 case AArch64::LDPXpost:
5549 case AArch64::LDPXpre: {
5554 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5555 "is also a destination");
5557 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5558 "is also a destination");
5561 case AArch64::LDR_ZA:
5562 case AArch64::STR_ZA: {
5565 return Error(Loc[1],
5566 "unpredictable instruction, immediate and offset mismatch.");
5569 case AArch64::LDPDi:
5570 case AArch64::LDPQi:
5571 case AArch64::LDPSi:
5572 case AArch64::LDPSWi:
5573 case AArch64::LDPWi:
5574 case AArch64::LDPXi: {
5578 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5581 case AArch64::LDPDpost:
5582 case AArch64::LDPDpre:
5583 case AArch64::LDPQpost:
5584 case AArch64::LDPQpre:
5585 case AArch64::LDPSpost:
5586 case AArch64::LDPSpre:
5587 case AArch64::LDPSWpost: {
5591 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5594 case AArch64::STPDpost:
5595 case AArch64::STPDpre:
5596 case AArch64::STPQpost:
5597 case AArch64::STPQpre:
5598 case AArch64::STPSpost:
5599 case AArch64::STPSpre:
5600 case AArch64::STPWpost:
5601 case AArch64::STPWpre:
5602 case AArch64::STPXpost:
5603 case AArch64::STPXpre: {
5608 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5609 "is also a source");
5611 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5612 "is also a source");
5615 case AArch64::LDRBBpre:
5616 case AArch64::LDRBpre:
5617 case AArch64::LDRHHpre:
5618 case AArch64::LDRHpre:
5619 case AArch64::LDRSBWpre:
5620 case AArch64::LDRSBXpre:
5621 case AArch64::LDRSHWpre:
5622 case AArch64::LDRSHXpre:
5623 case AArch64::LDRSWpre:
5624 case AArch64::LDRWpre:
5625 case AArch64::LDRXpre:
5626 case AArch64::LDRBBpost:
5627 case AArch64::LDRBpost:
5628 case AArch64::LDRHHpost:
5629 case AArch64::LDRHpost:
5630 case AArch64::LDRSBWpost:
5631 case AArch64::LDRSBXpost:
5632 case AArch64::LDRSHWpost:
5633 case AArch64::LDRSHXpost:
5634 case AArch64::LDRSWpost:
5635 case AArch64::LDRWpost:
5636 case AArch64::LDRXpost: {
5640 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5641 "is also a source");
5644 case AArch64::STRBBpost:
5645 case AArch64::STRBpost:
5646 case AArch64::STRHHpost:
5647 case AArch64::STRHpost:
5648 case AArch64::STRWpost:
5649 case AArch64::STRXpost:
5650 case AArch64::STRBBpre:
5651 case AArch64::STRBpre:
5652 case AArch64::STRHHpre:
5653 case AArch64::STRHpre:
5654 case AArch64::STRWpre:
5655 case AArch64::STRXpre: {
5659 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5660 "is also a source");
5663 case AArch64::STXRB:
5664 case AArch64::STXRH:
5665 case AArch64::STXRW:
5666 case AArch64::STXRX:
5667 case AArch64::STLXRB:
5668 case AArch64::STLXRH:
5669 case AArch64::STLXRW:
5670 case AArch64::STLXRX: {
5676 return Error(Loc[0],
5677 "unpredictable STXR instruction, status is also a source");
5680 case AArch64::STXPW:
5681 case AArch64::STXPX:
5682 case AArch64::STLXPW:
5683 case AArch64::STLXPX: {
5690 return Error(Loc[0],
5691 "unpredictable STXP instruction, status is also a source");
5694 case AArch64::LDRABwriteback:
5695 case AArch64::LDRAAwriteback: {
5699 return Error(Loc[0],
5700 "unpredictable LDRA instruction, writeback base"
5701 " is also a destination");
5708 case AArch64::CPYFP:
5709 case AArch64::CPYFPWN:
5710 case AArch64::CPYFPRN:
5711 case AArch64::CPYFPN:
5712 case AArch64::CPYFPWT:
5713 case AArch64::CPYFPWTWN:
5714 case AArch64::CPYFPWTRN:
5715 case AArch64::CPYFPWTN:
5716 case AArch64::CPYFPRT:
5717 case AArch64::CPYFPRTWN:
5718 case AArch64::CPYFPRTRN:
5719 case AArch64::CPYFPRTN:
5720 case AArch64::CPYFPT:
5721 case AArch64::CPYFPTWN:
5722 case AArch64::CPYFPTRN:
5723 case AArch64::CPYFPTN:
5724 case AArch64::CPYFM:
5725 case AArch64::CPYFMWN:
5726 case AArch64::CPYFMRN:
5727 case AArch64::CPYFMN:
5728 case AArch64::CPYFMWT:
5729 case AArch64::CPYFMWTWN:
5730 case AArch64::CPYFMWTRN:
5731 case AArch64::CPYFMWTN:
5732 case AArch64::CPYFMRT:
5733 case AArch64::CPYFMRTWN:
5734 case AArch64::CPYFMRTRN:
5735 case AArch64::CPYFMRTN:
5736 case AArch64::CPYFMT:
5737 case AArch64::CPYFMTWN:
5738 case AArch64::CPYFMTRN:
5739 case AArch64::CPYFMTN:
5740 case AArch64::CPYFE:
5741 case AArch64::CPYFEWN:
5742 case AArch64::CPYFERN:
5743 case AArch64::CPYFEN:
5744 case AArch64::CPYFEWT:
5745 case AArch64::CPYFEWTWN:
5746 case AArch64::CPYFEWTRN:
5747 case AArch64::CPYFEWTN:
5748 case AArch64::CPYFERT:
5749 case AArch64::CPYFERTWN:
5750 case AArch64::CPYFERTRN:
5751 case AArch64::CPYFERTN:
5752 case AArch64::CPYFET:
5753 case AArch64::CPYFETWN:
5754 case AArch64::CPYFETRN:
5755 case AArch64::CPYFETN:
5757 case AArch64::CPYPWN:
5758 case AArch64::CPYPRN:
5759 case AArch64::CPYPN:
5760 case AArch64::CPYPWT:
5761 case AArch64::CPYPWTWN:
5762 case AArch64::CPYPWTRN:
5763 case AArch64::CPYPWTN:
5764 case AArch64::CPYPRT:
5765 case AArch64::CPYPRTWN:
5766 case AArch64::CPYPRTRN:
5767 case AArch64::CPYPRTN:
5768 case AArch64::CPYPT:
5769 case AArch64::CPYPTWN:
5770 case AArch64::CPYPTRN:
5771 case AArch64::CPYPTN:
5773 case AArch64::CPYMWN:
5774 case AArch64::CPYMRN:
5775 case AArch64::CPYMN:
5776 case AArch64::CPYMWT:
5777 case AArch64::CPYMWTWN:
5778 case AArch64::CPYMWTRN:
5779 case AArch64::CPYMWTN:
5780 case AArch64::CPYMRT:
5781 case AArch64::CPYMRTWN:
5782 case AArch64::CPYMRTRN:
5783 case AArch64::CPYMRTN:
5784 case AArch64::CPYMT:
5785 case AArch64::CPYMTWN:
5786 case AArch64::CPYMTRN:
5787 case AArch64::CPYMTN:
5789 case AArch64::CPYEWN:
5790 case AArch64::CPYERN:
5791 case AArch64::CPYEN:
5792 case AArch64::CPYEWT:
5793 case AArch64::CPYEWTWN:
5794 case AArch64::CPYEWTRN:
5795 case AArch64::CPYEWTN:
5796 case AArch64::CPYERT:
5797 case AArch64::CPYERTWN:
5798 case AArch64::CPYERTRN:
5799 case AArch64::CPYERTN:
5800 case AArch64::CPYET:
5801 case AArch64::CPYETWN:
5802 case AArch64::CPYETRN:
5803 case AArch64::CPYETN: {
5814 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5815 " registers are the same");
5817 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5818 " registers are the same");
5820 return Error(Loc[0],
"invalid CPY instruction, source and size"
5821 " registers are the same");
5825 case AArch64::SETPT:
5826 case AArch64::SETPN:
5827 case AArch64::SETPTN:
5829 case AArch64::SETMT:
5830 case AArch64::SETMN:
5831 case AArch64::SETMTN:
5833 case AArch64::SETET:
5834 case AArch64::SETEN:
5835 case AArch64::SETETN:
5836 case AArch64::SETGP:
5837 case AArch64::SETGPT:
5838 case AArch64::SETGPN:
5839 case AArch64::SETGPTN:
5840 case AArch64::SETGM:
5841 case AArch64::SETGMT:
5842 case AArch64::SETGMN:
5843 case AArch64::SETGMTN:
5844 case AArch64::MOPSSETGE:
5845 case AArch64::MOPSSETGET:
5846 case AArch64::MOPSSETGEN:
5847 case AArch64::MOPSSETGETN: {
5857 return Error(Loc[0],
"invalid SET instruction, destination and size"
5858 " registers are the same");
5860 return Error(Loc[0],
"invalid SET instruction, destination and source"
5861 " registers are the same");
5863 return Error(Loc[0],
"invalid SET instruction, source and size"
5864 " registers are the same");
5867 case AArch64::SETGOP:
5868 case AArch64::SETGOPT:
5869 case AArch64::SETGOPN:
5870 case AArch64::SETGOPTN:
5871 case AArch64::SETGOM:
5872 case AArch64::SETGOMT:
5873 case AArch64::SETGOMN:
5874 case AArch64::SETGOMTN:
5875 case AArch64::SETGOE:
5876 case AArch64::SETGOET:
5877 case AArch64::SETGOEN:
5878 case AArch64::SETGOETN: {
5887 return Error(Loc[0],
"invalid SET instruction, destination and size"
5888 " registers are the same");
5897 case AArch64::ADDSWri:
5898 case AArch64::ADDSXri:
5899 case AArch64::ADDWri:
5900 case AArch64::ADDXri:
5901 case AArch64::SUBSWri:
5902 case AArch64::SUBSXri:
5903 case AArch64::SUBWri:
5904 case AArch64::SUBXri: {
5912 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5937 return Error(Loc.
back(),
"invalid immediate expression");
5950 unsigned VariantID = 0);
5952bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5956 case Match_InvalidTiedOperand: {
5958 if (
Op.isVectorList())
5959 return Error(
Loc,
"operand must match destination register list");
5961 assert(
Op.isReg() &&
"Unexpected operand type");
5962 switch (
Op.getRegEqualityTy()) {
5963 case RegConstraintEqualityTy::EqualsSubReg:
5964 return Error(
Loc,
"operand must be 64-bit form of destination register");
5965 case RegConstraintEqualityTy::EqualsSuperReg:
5966 return Error(
Loc,
"operand must be 32-bit form of destination register");
5967 case RegConstraintEqualityTy::EqualsReg:
5968 return Error(
Loc,
"operand must match destination register");
5972 case Match_MissingFeature:
5974 "instruction requires a CPU feature not currently enabled");
5975 case Match_InvalidOperand:
5976 return Error(Loc,
"invalid operand for instruction");
5977 case Match_InvalidSuffix:
5978 return Error(Loc,
"invalid type suffix for instruction");
5979 case Match_InvalidCondCode:
5980 return Error(Loc,
"expected AArch64 condition code");
5981 case Match_AddSubRegExtendSmall:
5983 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5984 case Match_AddSubRegExtendLarge:
5986 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5987 case Match_AddSubSecondSource:
5989 "expected compatible register, symbol or integer in range [0, 4095]");
5990 case Match_LogicalSecondSource:
5991 return Error(Loc,
"expected compatible register or logical immediate");
5992 case Match_InvalidMovImm32Shift:
5993 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5994 case Match_InvalidMovImm64Shift:
5995 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5996 case Match_AddSubRegShift32:
5998 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5999 case Match_AddSubRegShift64:
6001 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
6002 case Match_InvalidFPImm:
6004 "expected compatible register or floating-point constant");
6005 case Match_InvalidSImm6:
6006 return Error(Loc,
"immediate must be an integer in range [-32, 31].");
6007 case Match_InvalidSImm5:
6008 return Error(Loc,
"immediate must be an integer in range [-16, 15].");
6009 case Match_InvalidSImm4s1:
6010 return Error(Loc,
"immediate must be an integer in range [-8, 7].");
6011 case Match_InvalidSImm4s2:
6012 return Error(Loc,
"immediate must be a multiple of 2 in range [-16, 14].");
6013 case Match_InvalidSImm4s3:
6014 return Error(Loc,
"immediate must be a multiple of 3 in range [-24, 21].");
6015 case Match_InvalidSImm4s4:
6016 return Error(Loc,
"immediate must be a multiple of 4 in range [-32, 28].");
6017 case Match_InvalidSImm4s16:
6019 "immediate must be a multiple of 16 in range [-128, 112].");
6020 case Match_InvalidSImm4s32:
6022 "immediate must be a multiple of 32 in range [-256, 224].");
6023 case Match_InvalidSImm6s1:
6024 return Error(Loc,
"immediate must be an integer in range [-32, 31].");
6025 case Match_InvalidSImm8:
6026 return Error(Loc,
"immediate must be an integer in range [-128, 127].");
6027 case Match_InvalidSImm9:
6028 return Error(Loc,
"immediate must be an integer in range [-256, 255].");
6029 case Match_InvalidSImm9s16:
6031 "immediate must be a multiple of 16 in range [-4096, 4080].");
6032 case Match_InvalidSImm10s8:
6034 "immediate must be a multiple of 8 in range [-4096, 4088].");
6035 case Match_InvalidSImm7s4:
6037 "immediate must be a multiple of 4 in range [-256, 252].");
6038 case Match_InvalidSImm7s8:
6040 "immediate must be a multiple of 8 in range [-512, 504].");
6041 case Match_InvalidSImm7s16:
6043 "immediate must be a multiple of 16 in range [-1024, 1008].");
6044 case Match_InvalidUImm5s8:
6045 return Error(Loc,
"immediate must be a multiple of 8 in range [0, 248].");
6046 case Match_InvalidUImm3s8:
6047 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6048 case Match_InvalidUImm5s4:
6049 return Error(Loc,
"immediate must be a multiple of 4 in range [0, 124].");
6050 case Match_InvalidUImm5s2:
6051 return Error(Loc,
"immediate must be a multiple of 2 in range [0, 62].");
6052 case Match_InvalidUImm6s8:
6053 return Error(Loc,
"immediate must be a multiple of 8 in range [0, 504].");
6054 case Match_InvalidUImm6s16:
6055 return Error(Loc,
"immediate must be a multiple of 16 in range [0, 1008].");
6056 case Match_InvalidUImm8s32:
6057 return Error(Loc,
"immediate must be a multiple of 32 in range [0, 8160].");
6058 case Match_InvalidUImm6s4:
6059 return Error(Loc,
"immediate must be a multiple of 4 in range [0, 252].");
6060 case Match_InvalidUImm6s2:
6061 return Error(Loc,
"immediate must be a multiple of 2 in range [0, 126].");
6062 case Match_InvalidUImm6s1:
6063 return Error(Loc,
"immediate must be in range [0, 63].");
6064 case Match_InvalidMemoryWExtend8:
6066 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6067 case Match_InvalidMemoryWExtend16:
6069 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6070 case Match_InvalidMemoryWExtend32:
6072 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6073 case Match_InvalidMemoryWExtend64:
6075 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6076 case Match_InvalidMemoryWExtend128:
6078 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6079 case Match_InvalidMemoryXExtend8:
6081 "expected 'lsl' or 'sxtx' with optional shift of #0");
6082 case Match_InvalidMemoryXExtend16:
6084 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6085 case Match_InvalidMemoryXExtend32:
6087 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6088 case Match_InvalidMemoryXExtend64:
6090 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6091 case Match_InvalidMemoryXExtend128:
6093 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6094 case Match_InvalidUImm12Offset1:
6095 return Error(Loc,
"offset must be an integer in range [0, 4095].");
6096 case Match_InvalidUImm12Offset2:
6097 return Error(Loc,
"offset must be a multiple of 2 in range [0, 8190].");
6098 case Match_InvalidUImm12Offset4:
6099 return Error(Loc,
"offset must be a multiple of 4 in range [0, 16380].");
6100 case Match_InvalidUImm12Offset8:
6101 return Error(Loc,
"offset must be a multiple of 8 in range [0, 32760].");
6102 case Match_InvalidUImm12Offset16:
6103 return Error(Loc,
"offset must be a multiple of 16 in range [0, 65520].");
6104 case Match_InvalidImm0_0:
6105 return Error(Loc,
"immediate must be 0.");
6106 case Match_InvalidImm0_1:
6107 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6108 case Match_InvalidImm0_3:
6109 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6110 case Match_InvalidImm0_7:
6111 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6112 case Match_InvalidImm0_15:
6113 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6114 case Match_InvalidImm0_31:
6115 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6116 case Match_InvalidImm0_63:
6117 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6118 case Match_InvalidImm0_127:
6119 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6120 case Match_InvalidImm0_255:
6121 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6122 case Match_InvalidImm0_511:
6123 return Error(Loc,
"immediate must be an integer in range [0, 511].");
6124 case Match_InvalidImm0_65535:
6125 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6126 case Match_InvalidHinteUImm16:
6128 "immediate must be an integer in range [0, 65535], excluding "
6129 "values in range [12319, 16383] where (value - 12319) is a "
6131 case Match_InvalidImm1_8:
6132 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6133 case Match_InvalidImm1_16:
6134 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6135 case Match_InvalidImm1_32:
6136 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6137 case Match_InvalidImm1_64:
6138 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6139 case Match_InvalidImm1_512:
6140 return Error(Loc,
"immediate must be an integer in range [1, 512].");
6141 case Match_InvalidImmM1_62:
6142 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6143 case Match_InvalidImmM1_510:
6144 return Error(Loc,
"immediate must be an integer in range [-1, 510].");
6145 case Match_InvalidImmM255_256:
6146 return Error(Loc,
"immediate must be an integer in range [-255, 256].");
6147 case Match_InvalidImmM257_254:
6148 return Error(Loc,
"immediate must be an integer in range [-257, 254].");
6149 case Match_InvalidVecSelRange0s2:
6150 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6151 case Match_InvalidVecSelRange1s2:
6152 return Error(Loc,
"vector select offset must be an immediate range of the "
6153 "form <immf>:<imml>, where the first "
6154 "immediate is a multiple of 2 in the range [0, 2], and "
6155 "the second immediate is immf + 1.");
6156 case Match_InvalidVecSelRange2s2:
6157 case Match_InvalidVecSelRange3s2:
6160 "vector select offset must be an immediate range of the form "
6162 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6164 "depending on the instruction, and the second immediate is immf + 1.");
6165 case Match_InvalidVecSelRange0s4:
6166 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6167 case Match_InvalidVecSelRange1s4:
6168 case Match_InvalidVecSelRange2s4:
6171 "vector select offset must be an immediate range of the form "
6173 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6175 "depending on the instruction, and the second immediate is immf + 3.");
6176 case Match_InvalidSVEAddSubImm8:
6177 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6178 " with a shift amount of 0");
6179 case Match_InvalidSVEAddSubImm16:
6180 case Match_InvalidSVEAddSubImm32:
6181 case Match_InvalidSVEAddSubImm64:
6182 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6183 "multiple of 256 in range [256, 65280]");
6184 case Match_InvalidSVECpyImm8:
6185 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6186 " with a shift amount of 0");
6187 case Match_InvalidSVECpyImm16:
6188 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6189 "multiple of 256 in range [-32768, 65280]");
6190 case Match_InvalidSVECpyImm32:
6191 case Match_InvalidSVECpyImm64:
6192 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6193 "multiple of 256 in range [-32768, 32512]");
6194 case Match_InvalidIndexRange0_0:
6195 return Error(Loc,
"expected lane specifier '[0]'");
6196 case Match_InvalidIndexRange1_1:
6197 return Error(Loc,
"expected lane specifier '[1]'");
6198 case Match_InvalidIndexRange0_15:
6199 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6200 case Match_InvalidIndexRange0_7:
6201 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6202 case Match_InvalidIndexRange0_3:
6203 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6204 case Match_InvalidIndexRange0_1:
6205 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6206 case Match_InvalidSVEIndexRange0_63:
6207 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6208 case Match_InvalidSVEIndexRange0_31:
6209 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6210 case Match_InvalidSVEIndexRange0_15:
6211 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6212 case Match_InvalidSVEIndexRange0_7:
6213 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6214 case Match_InvalidSVEIndexRange0_3:
6215 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6216 case Match_InvalidLabel:
6217 return Error(Loc,
"expected label or encodable integer pc offset");
6219 return Error(Loc,
"expected readable system register");
6221 case Match_InvalidSVCR:
6222 return Error(Loc,
"expected writable system register or pstate");
6223 case Match_InvalidComplexRotationEven:
6224 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6225 case Match_InvalidComplexRotationOdd:
6226 return Error(Loc,
"complex rotation must be 90 or 270.");
6227 case Match_MnemonicFail: {
6230 ComputeAvailableFeatures(STI->getFeatureBits()));
6231 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6233 case Match_InvalidGPR64shifted8:
6234 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6235 case Match_InvalidGPR64shifted16:
6236 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6237 case Match_InvalidGPR64shifted32:
6238 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6239 case Match_InvalidGPR64shifted64:
6240 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6241 case Match_InvalidGPR64shifted128:
6243 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6244 case Match_InvalidGPR64NoXZRshifted8:
6245 return Error(Loc,
"register must be x0..x30 without shift");
6246 case Match_InvalidGPR64NoXZRshifted16:
6247 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6248 case Match_InvalidGPR64NoXZRshifted32:
6249 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6250 case Match_InvalidGPR64NoXZRshifted64:
6251 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6252 case Match_InvalidGPR64NoXZRshifted128:
6253 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6254 case Match_InvalidZPR32UXTW8:
6255 case Match_InvalidZPR32SXTW8:
6256 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6257 case Match_InvalidZPR32UXTW16:
6258 case Match_InvalidZPR32SXTW16:
6259 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6260 case Match_InvalidZPR32UXTW32:
6261 case Match_InvalidZPR32SXTW32:
6262 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6263 case Match_InvalidZPR32UXTW64:
6264 case Match_InvalidZPR32SXTW64:
6265 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6266 case Match_InvalidZPR64UXTW8:
6267 case Match_InvalidZPR64SXTW8:
6268 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6269 case Match_InvalidZPR64UXTW16:
6270 case Match_InvalidZPR64SXTW16:
6271 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6272 case Match_InvalidZPR64UXTW32:
6273 case Match_InvalidZPR64SXTW32:
6274 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6275 case Match_InvalidZPR64UXTW64:
6276 case Match_InvalidZPR64SXTW64:
6277 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6278 case Match_InvalidZPR32LSL8:
6279 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6280 case Match_InvalidZPR32LSL16:
6281 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6282 case Match_InvalidZPR32LSL32:
6283 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6284 case Match_InvalidZPR32LSL64:
6285 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6286 case Match_InvalidZPR64LSL8:
6287 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6288 case Match_InvalidZPR64LSL16:
6289 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6290 case Match_InvalidZPR64LSL32:
6291 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6292 case Match_InvalidZPR64LSL64:
6293 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6294 case Match_InvalidZPR0:
6295 return Error(Loc,
"expected register without element width suffix");
6296 case Match_InvalidZPR8:
6297 case Match_InvalidZPR16:
6298 case Match_InvalidZPR32:
6299 case Match_InvalidZPR64:
6300 case Match_InvalidZPR128:
6301 return Error(Loc,
"invalid element width");
6302 case Match_InvalidZPR_3b8:
6303 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6304 case Match_InvalidZPR_3b16:
6305 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6306 case Match_InvalidZPR_3b32:
6307 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6308 case Match_InvalidZPR_4b8:
6310 "Invalid restricted vector register, expected z0.b..z15.b");
6311 case Match_InvalidZPR_4b16:
6312 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6313 case Match_InvalidZPR_4b32:
6314 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6315 case Match_InvalidZPR_4b64:
6316 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6317 case Match_InvalidZPRMul2_Lo8:
6318 return Error(Loc,
"Invalid restricted vector register, expected even "
6319 "register in z0.b..z14.b");
6320 case Match_InvalidZPRMul2_Hi8:
6321 return Error(Loc,
"Invalid restricted vector register, expected even "
6322 "register in z16.b..z30.b");
6323 case Match_InvalidZPRMul2_Lo16:
6324 return Error(Loc,
"Invalid restricted vector register, expected even "
6325 "register in z0.h..z14.h");
6326 case Match_InvalidZPRMul2_Hi16:
6327 return Error(Loc,
"Invalid restricted vector register, expected even "
6328 "register in z16.h..z30.h");
6329 case Match_InvalidZPRMul2_Lo32:
6330 return Error(Loc,
"Invalid restricted vector register, expected even "
6331 "register in z0.s..z14.s");
6332 case Match_InvalidZPRMul2_Hi32:
6333 return Error(Loc,
"Invalid restricted vector register, expected even "
6334 "register in z16.s..z30.s");
6335 case Match_InvalidZPRMul2_Lo64:
6336 return Error(Loc,
"Invalid restricted vector register, expected even "
6337 "register in z0.d..z14.d");
6338 case Match_InvalidZPRMul2_Hi64:
6339 return Error(Loc,
"Invalid restricted vector register, expected even "
6340 "register in z16.d..z30.d");
6341 case Match_InvalidZPR_K0:
6342 return Error(Loc,
"invalid restricted vector register, expected register "
6343 "in z20..z23 or z28..z31");
6344 case Match_InvalidZPR_K8:
6345 return Error(Loc,
"invalid restricted vector register, expected register "
6346 "in z20.b..z23.b or z28.b..z31.b");
6347 case Match_InvalidSVEPattern:
6348 return Error(Loc,
"invalid predicate pattern");
6349 case Match_InvalidSVEPPRorPNRAnyReg:
6350 case Match_InvalidSVEPPRorPNRBReg:
6351 case Match_InvalidSVEPredicateAnyReg:
6352 case Match_InvalidSVEPredicateBReg:
6353 case Match_InvalidSVEPredicateHReg:
6354 case Match_InvalidSVEPredicateSReg:
6355 case Match_InvalidSVEPredicateDReg:
6356 return Error(Loc,
"invalid predicate register.");
6357 case Match_InvalidSVEPredicate3bAnyReg:
6358 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6359 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6360 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6361 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6362 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6363 return Error(Loc,
"Invalid predicate register, expected PN in range "
6364 "pn8..pn15 with element suffix.");
6365 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6366 return Error(Loc,
"invalid restricted predicate-as-counter register "
6367 "expected pn8..pn15");
6368 case Match_InvalidSVEPNPredicateBReg:
6369 case Match_InvalidSVEPNPredicateHReg:
6370 case Match_InvalidSVEPNPredicateSReg:
6371 case Match_InvalidSVEPNPredicateDReg:
6372 return Error(Loc,
"Invalid predicate register, expected PN in range "
6373 "pn0..pn15 with element suffix.");
6374 case Match_InvalidSVEVecLenSpecifier:
6375 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6376 case Match_InvalidSVEPredicateListMul2x8:
6377 case Match_InvalidSVEPredicateListMul2x16:
6378 case Match_InvalidSVEPredicateListMul2x32:
6379 case Match_InvalidSVEPredicateListMul2x64:
6380 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6381 "predicate registers, where the first vector is a multiple of 2 "
6382 "and with correct element type");
6383 case Match_InvalidSVEExactFPImmOperandHalfOne:
6384 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6385 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6386 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6387 case Match_InvalidSVEExactFPImmOperandZeroOne:
6388 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6389 case Match_InvalidMatrixTileVectorH8:
6390 case Match_InvalidMatrixTileVectorV8:
6391 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6392 case Match_InvalidMatrixTileVectorH16:
6393 case Match_InvalidMatrixTileVectorV16:
6395 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6396 case Match_InvalidMatrixTileVectorH32:
6397 case Match_InvalidMatrixTileVectorV32:
6399 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6400 case Match_InvalidMatrixTileVectorH64:
6401 case Match_InvalidMatrixTileVectorV64:
6403 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6404 case Match_InvalidMatrixTileVectorH128:
6405 case Match_InvalidMatrixTileVectorV128:
6407 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6408 case Match_InvalidMatrixTile16:
6409 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6410 case Match_InvalidMatrixTile32:
6411 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6412 case Match_InvalidMatrixTile64:
6413 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6414 case Match_InvalidMatrix:
6415 return Error(Loc,
"invalid matrix operand, expected za");
6416 case Match_InvalidMatrix8:
6417 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6418 case Match_InvalidMatrix16:
6419 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6420 case Match_InvalidMatrix32:
6421 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6422 case Match_InvalidMatrix64:
6423 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6424 case Match_InvalidMatrixIndexGPR32_12_15:
6425 return Error(Loc,
"operand must be a register in range [w12, w15]");
6426 case Match_InvalidMatrixIndexGPR32_8_11:
6427 return Error(Loc,
"operand must be a register in range [w8, w11]");
6428 case Match_InvalidSVEVectorList2x8Mul2:
6429 case Match_InvalidSVEVectorList2x16Mul2:
6430 case Match_InvalidSVEVectorList2x32Mul2:
6431 case Match_InvalidSVEVectorList2x64Mul2:
6432 case Match_InvalidSVEVectorList2x128Mul2:
6433 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6434 "SVE vectors, where the first vector is a multiple of 2 "
6435 "and with matching element types");
6436 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6437 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6438 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6439 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6440 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6441 "SVE vectors in the range z0-z14, where the first vector "
6442 "is a multiple of 2 "
6443 "and with matching element types");
6444 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6445 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6446 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6447 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6449 "Invalid vector list, expected list with 2 consecutive "
6450 "SVE vectors in the range z16-z30, where the first vector "
6451 "is a multiple of 2 "
6452 "and with matching element types");
6453 case Match_InvalidSVEVectorList4x8Mul4:
6454 case Match_InvalidSVEVectorList4x16Mul4:
6455 case Match_InvalidSVEVectorList4x32Mul4:
6456 case Match_InvalidSVEVectorList4x64Mul4:
6457 case Match_InvalidSVEVectorList4x128Mul4:
6458 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6459 "SVE vectors, where the first vector is a multiple of 4 "
6460 "and with matching element types");
6461 case Match_InvalidSVEVectorList3x0_3b:
6462 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6463 "SVE vectors starting at z0-z7");
6464 case Match_InvalidLookupTable:
6465 return Error(Loc,
"Invalid lookup table, expected zt0");
6466 case Match_InvalidSVEVectorListStrided2x8:
6467 case Match_InvalidSVEVectorListStrided2x16:
6468 case Match_InvalidSVEVectorListStrided2x32:
6469 case Match_InvalidSVEVectorListStrided2x64:
6472 "Invalid vector list, expected list with each SVE vector in the list "
6473 "8 registers apart, and the first register in the range [z0, z7] or "
6474 "[z16, z23] and with correct element type");
6475 case Match_InvalidSVEVectorListStrided4x8:
6476 case Match_InvalidSVEVectorListStrided4x16:
6477 case Match_InvalidSVEVectorListStrided4x32:
6478 case Match_InvalidSVEVectorListStrided4x64:
6481 "Invalid vector list, expected list with each SVE vector in the list "
6482 "4 registers apart, and the first register in the range [z0, z3] or "
6483 "[z16, z19] and with correct element type");
6484 case Match_AddSubLSLImm3ShiftLarge:
6486 "expected 'lsl' with optional integer in range [0, 7]");
6494bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6498 bool MatchingInlineAsm) {
6500 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6501 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6504 unsigned NumOperands =
Operands.size();
6506 if (NumOperands == 4 && Tok ==
"lsl") {
6507 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6508 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6509 if (Op2.isScalarReg() && Op3.isImm()) {
6515 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6517 NewOp3Val = (32 - Op3Val) & 0x1f;
6518 NewOp4Val = 31 - Op3Val;
6520 NewOp3Val = (64 - Op3Val) & 0x3f;
6521 NewOp4Val = 63 - Op3Val;
6528 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6529 Operands.push_back(AArch64Operand::CreateImm(
6530 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6531 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6535 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6537 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6538 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6539 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6541 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6545 if (LSBCE && WidthCE) {
6550 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6556 if (LSB >= RegWidth)
6557 return Error(LSBOp.getStartLoc(),
6558 "expected integer in range [0, 31]");
6559 if (Width < 1 || Width > RegWidth)
6560 return Error(WidthOp.getStartLoc(),
6561 "expected integer in range [1, 32]");
6565 ImmR = (32 - LSB) & 0x1f;
6567 ImmR = (64 - LSB) & 0x3f;
6571 if (ImmR != 0 && ImmS >= ImmR)
6572 return Error(WidthOp.getStartLoc(),
6573 "requested insert overflows register");
6578 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6579 Operands[2] = AArch64Operand::CreateReg(
6580 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6582 Operands[3] = AArch64Operand::CreateImm(
6583 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6585 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6589 }
else if (NumOperands == 5) {
6592 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6593 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6594 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6595 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6597 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6601 if (Op3CE && Op4CE) {
6606 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6612 if (Op3Val >= RegWidth)
6613 return Error(Op3.getStartLoc(),
6614 "expected integer in range [0, 31]");
6615 if (Op4Val < 1 || Op4Val > RegWidth)
6616 return Error(Op4.getStartLoc(),
6617 "expected integer in range [1, 32]");
6621 NewOp3Val = (32 - Op3Val) & 0x1f;
6623 NewOp3Val = (64 - Op3Val) & 0x3f;
6627 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6628 return Error(Op4.getStartLoc(),
6629 "requested insert overflows register");
6631 const MCExpr *NewOp3 =
6633 const MCExpr *NewOp4 =
6635 Operands[3] = AArch64Operand::CreateImm(
6636 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6637 Operands[4] = AArch64Operand::CreateImm(
6638 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6640 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6642 else if (Tok ==
"sbfiz")
6643 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6645 else if (Tok ==
"ubfiz")
6646 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6655 }
else if (NumOperands == 5 &&
6656 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6657 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6658 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6659 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6661 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6665 if (Op3CE && Op4CE) {
6670 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6676 if (Op3Val >= RegWidth)
6677 return Error(Op3.getStartLoc(),
6678 "expected integer in range [0, 31]");
6679 if (Op4Val < 1 || Op4Val > RegWidth)
6680 return Error(Op4.getStartLoc(),
6681 "expected integer in range [1, 32]");
6683 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6685 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6686 return Error(Op4.getStartLoc(),
6687 "requested extract overflows register");
6689 const MCExpr *NewOp4 =
6691 Operands[4] = AArch64Operand::CreateImm(
6692 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6694 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6696 else if (Tok ==
"sbfx")
6697 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6699 else if (Tok ==
"ubfx")
6700 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6713 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6714 NumOperands == 4 && Tok ==
"movi") {
6715 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6716 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6717 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6718 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6719 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6720 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6721 if (Suffix.
lower() ==
".2d" &&
6723 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6724 " correctly on this CPU, converting to equivalent movi.16b");
6726 unsigned Idx = Op1.isToken() ? 1 : 2;
6728 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6736 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6739 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6740 if (
Op.isScalarReg()) {
6742 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6743 Op.getStartLoc(),
Op.getEndLoc(),
6748 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6749 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6750 if (
Op.isScalarReg() &&
6751 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6755 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6756 if (
Op.isScalarReg()) {
6758 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6765 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6766 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6767 if (
Op.isScalarReg() &&
6768 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6772 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6773 if (
Op.isScalarReg()) {
6775 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6783 FeatureBitset MissingFeatures;
6786 unsigned MatchResult =
6787 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6788 MatchingInlineAsm, 1);
6792 if (MatchResult != Match_Success) {
6795 auto ShortFormNEONErrorInfo = ErrorInfo;
6796 auto ShortFormNEONMatchResult = MatchResult;
6797 auto ShortFormNEONMissingFeatures = MissingFeatures;
6800 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6801 MatchingInlineAsm, 0);
6806 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6808 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6809 MatchResult = ShortFormNEONMatchResult;
6810 ErrorInfo = ShortFormNEONErrorInfo;
6811 MissingFeatures = ShortFormNEONMissingFeatures;
6815 switch (MatchResult) {
6816 case Match_Success: {
6820 for (
unsigned i = 1; i < NumOperands; ++i)
6822 if (validateInstruction(Inst, IDLoc, OperandLocs))
6826 Out.emitInstruction(Inst, getSTI());
6829 case Match_MissingFeature: {
6830 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6833 std::string
Msg =
"instruction requires:";
6834 for (
unsigned Feature : MissingFeatures) {
6840 case Match_MnemonicFail:
6841 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6842 case Match_InvalidOperand: {
6843 SMLoc ErrorLoc = IDLoc;
6845 if (ErrorInfo != ~0ULL) {
6847 return Error(IDLoc,
"too few operands for instruction",
6848 SMRange(IDLoc, getTok().getLoc()));
6850 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6851 if (ErrorLoc == SMLoc())
6856 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6857 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6858 MatchResult = Match_InvalidSuffix;
6860 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6862 case Match_InvalidTiedOperand:
6863 case Match_InvalidUImm12Offset1:
6864 case Match_InvalidUImm12Offset2:
6865 case Match_InvalidUImm12Offset4:
6866 case Match_InvalidUImm12Offset8:
6867 case Match_InvalidUImm12Offset16:
6868 case Match_InvalidCondCode:
6869 case Match_AddSubLSLImm3ShiftLarge:
6870 case Match_AddSubRegExtendSmall:
6871 case Match_AddSubRegExtendLarge:
6872 case Match_AddSubSecondSource:
6873 case Match_LogicalSecondSource:
6874 case Match_AddSubRegShift32:
6875 case Match_AddSubRegShift64:
6876 case Match_InvalidMovImm32Shift:
6877 case Match_InvalidMovImm64Shift:
6878 case Match_InvalidFPImm:
6879 case Match_InvalidMemoryWExtend8:
6880 case Match_InvalidMemoryWExtend16:
6881 case Match_InvalidMemoryWExtend32:
6882 case Match_InvalidMemoryWExtend64:
6883 case Match_InvalidMemoryWExtend128:
6884 case Match_InvalidMemoryXExtend8:
6885 case Match_InvalidMemoryXExtend16:
6886 case Match_InvalidMemoryXExtend32:
6887 case Match_InvalidMemoryXExtend64:
6888 case Match_InvalidMemoryXExtend128:
6889 case Match_InvalidSImm4s1:
6890 case Match_InvalidSImm4s2:
6891 case Match_InvalidSImm4s3:
6892 case Match_InvalidSImm4s4:
6893 case Match_InvalidSImm6s1:
6894 case Match_InvalidSImm4s16:
6895 case Match_InvalidSImm4s32:
6896 case Match_InvalidSImm7s4:
6897 case Match_InvalidSImm7s8:
6898 case Match_InvalidSImm7s16:
6899 case Match_InvalidUImm5s8:
6900 case Match_InvalidUImm3s8:
6901 case Match_InvalidUImm5s4:
6902 case Match_InvalidUImm5s2:
6903 case Match_InvalidUImm6s1:
6904 case Match_InvalidUImm6s2:
6905 case Match_InvalidUImm6s4:
6906 case Match_InvalidUImm6s8:
6907 case Match_InvalidUImm6s16:
6908 case Match_InvalidUImm8s32:
6909 case Match_InvalidSImm6:
6910 case Match_InvalidSImm5:
6911 case Match_InvalidSImm8:
6912 case Match_InvalidSImm9:
6913 case Match_InvalidSImm9s16:
6914 case Match_InvalidSImm10s8:
6915 case Match_InvalidImm0_0:
6916 case Match_InvalidImm0_1:
6917 case Match_InvalidImm0_3:
6918 case Match_InvalidImm0_7:
6919 case Match_InvalidImm0_15:
6920 case Match_InvalidImm0_31:
6921 case Match_InvalidImm0_63:
6922 case Match_InvalidImm0_127:
6923 case Match_InvalidImm0_255:
6924 case Match_InvalidImm0_511:
6925 case Match_InvalidImm0_65535:
6926 case Match_InvalidHinteUImm16:
6927 case Match_InvalidImm1_8:
6928 case Match_InvalidImm1_16:
6929 case Match_InvalidImm1_32:
6930 case Match_InvalidImm1_64:
6931 case Match_InvalidImm1_512:
6932 case Match_InvalidImmM1_62:
6933 case Match_InvalidImmM1_510:
6934 case Match_InvalidImmM255_256:
6935 case Match_InvalidImmM257_254:
6936 case Match_InvalidVecSelRange0s2:
6937 case Match_InvalidVecSelRange1s2:
6938 case Match_InvalidVecSelRange2s2:
6939 case Match_InvalidVecSelRange3s2:
6940 case Match_InvalidVecSelRange0s4:
6941 case Match_InvalidVecSelRange1s4:
6942 case Match_InvalidVecSelRange2s4:
6943 case Match_InvalidSVEAddSubImm8:
6944 case Match_InvalidSVEAddSubImm16:
6945 case Match_InvalidSVEAddSubImm32:
6946 case Match_InvalidSVEAddSubImm64:
6947 case Match_InvalidSVECpyImm8:
6948 case Match_InvalidSVECpyImm16:
6949 case Match_InvalidSVECpyImm32:
6950 case Match_InvalidSVECpyImm64:
6951 case Match_InvalidIndexRange0_0:
6952 case Match_InvalidIndexRange1_1:
6953 case Match_InvalidIndexRange0_15:
6954 case Match_InvalidIndexRange0_7:
6955 case Match_InvalidIndexRange0_3:
6956 case Match_InvalidIndexRange0_1:
6957 case Match_InvalidSVEIndexRange0_63:
6958 case Match_InvalidSVEIndexRange0_31:
6959 case Match_InvalidSVEIndexRange0_15:
6960 case Match_InvalidSVEIndexRange0_7:
6961 case Match_InvalidSVEIndexRange0_3:
6962 case Match_InvalidLabel:
6963 case Match_InvalidComplexRotationEven:
6964 case Match_InvalidComplexRotationOdd:
6965 case Match_InvalidGPR64shifted8:
6966 case Match_InvalidGPR64shifted16:
6967 case Match_InvalidGPR64shifted32:
6968 case Match_InvalidGPR64shifted64:
6969 case Match_InvalidGPR64shifted128:
6970 case Match_InvalidGPR64NoXZRshifted8:
6971 case Match_InvalidGPR64NoXZRshifted16:
6972 case Match_InvalidGPR64NoXZRshifted32:
6973 case Match_InvalidGPR64NoXZRshifted64:
6974 case Match_InvalidGPR64NoXZRshifted128:
6975 case Match_InvalidZPR32UXTW8:
6976 case Match_InvalidZPR32UXTW16:
6977 case Match_InvalidZPR32UXTW32:
6978 case Match_InvalidZPR32UXTW64:
6979 case Match_InvalidZPR32SXTW8:
6980 case Match_InvalidZPR32SXTW16:
6981 case Match_InvalidZPR32SXTW32:
6982 case Match_InvalidZPR32SXTW64:
6983 case Match_InvalidZPR64UXTW8:
6984 case Match_InvalidZPR64SXTW8:
6985 case Match_InvalidZPR64UXTW16:
6986 case Match_InvalidZPR64SXTW16:
6987 case Match_InvalidZPR64UXTW32:
6988 case Match_InvalidZPR64SXTW32:
6989 case Match_InvalidZPR64UXTW64:
6990 case Match_InvalidZPR64SXTW64:
6991 case Match_InvalidZPR32LSL8:
6992 case Match_InvalidZPR32LSL16:
6993 case Match_InvalidZPR32LSL32:
6994 case Match_InvalidZPR32LSL64:
6995 case Match_InvalidZPR64LSL8:
6996 case Match_InvalidZPR64LSL16:
6997 case Match_InvalidZPR64LSL32:
6998 case Match_InvalidZPR64LSL64:
6999 case Match_InvalidZPR0:
7000 case Match_InvalidZPR8:
7001 case Match_InvalidZPR16:
7002 case Match_InvalidZPR32:
7003 case Match_InvalidZPR64:
7004 case Match_InvalidZPR128:
7005 case Match_InvalidZPR_3b8:
7006 case Match_InvalidZPR_3b16:
7007 case Match_InvalidZPR_3b32:
7008 case Match_InvalidZPR_4b8:
7009 case Match_InvalidZPR_4b16:
7010 case Match_InvalidZPR_4b32:
7011 case Match_InvalidZPR_4b64:
7012 case Match_InvalidSVEPPRorPNRAnyReg:
7013 case Match_InvalidSVEPPRorPNRBReg:
7014 case Match_InvalidSVEPredicateAnyReg:
7015 case Match_InvalidSVEPattern:
7016 case Match_InvalidSVEVecLenSpecifier:
7017 case Match_InvalidSVEPredicateBReg:
7018 case Match_InvalidSVEPredicateHReg:
7019 case Match_InvalidSVEPredicateSReg:
7020 case Match_InvalidSVEPredicateDReg:
7021 case Match_InvalidSVEPredicate3bAnyReg:
7022 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7023 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7024 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7025 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7026 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7027 case Match_InvalidSVEPNPredicateBReg:
7028 case Match_InvalidSVEPNPredicateHReg:
7029 case Match_InvalidSVEPNPredicateSReg:
7030 case Match_InvalidSVEPNPredicateDReg:
7031 case Match_InvalidSVEPredicateListMul2x8:
7032 case Match_InvalidSVEPredicateListMul2x16:
7033 case Match_InvalidSVEPredicateListMul2x32:
7034 case Match_InvalidSVEPredicateListMul2x64:
7035 case Match_InvalidSVEExactFPImmOperandHalfOne:
7036 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7037 case Match_InvalidSVEExactFPImmOperandZeroOne:
7038 case Match_InvalidMatrixTile16:
7039 case Match_InvalidMatrixTile32:
7040 case Match_InvalidMatrixTile64:
7041 case Match_InvalidMatrix:
7042 case Match_InvalidMatrix8:
7043 case Match_InvalidMatrix16:
7044 case Match_InvalidMatrix32:
7045 case Match_InvalidMatrix64:
7046 case Match_InvalidMatrixTileVectorH8:
7047 case Match_InvalidMatrixTileVectorH16:
7048 case Match_InvalidMatrixTileVectorH32:
7049 case Match_InvalidMatrixTileVectorH64:
7050 case Match_InvalidMatrixTileVectorH128:
7051 case Match_InvalidMatrixTileVectorV8:
7052 case Match_InvalidMatrixTileVectorV16:
7053 case Match_InvalidMatrixTileVectorV32:
7054 case Match_InvalidMatrixTileVectorV64:
7055 case Match_InvalidMatrixTileVectorV128:
7056 case Match_InvalidSVCR:
7057 case Match_InvalidMatrixIndexGPR32_12_15:
7058 case Match_InvalidMatrixIndexGPR32_8_11:
7059 case Match_InvalidLookupTable:
7060 case Match_InvalidZPRMul2_Lo8:
7061 case Match_InvalidZPRMul2_Hi8:
7062 case Match_InvalidZPRMul2_Lo16:
7063 case Match_InvalidZPRMul2_Hi16:
7064 case Match_InvalidZPRMul2_Lo32:
7065 case Match_InvalidZPRMul2_Hi32:
7066 case Match_InvalidZPRMul2_Lo64:
7067 case Match_InvalidZPRMul2_Hi64:
7068 case Match_InvalidZPR_K0:
7069 case Match_InvalidZPR_K8:
7070 case Match_InvalidSVEVectorList2x8Mul2:
7071 case Match_InvalidSVEVectorList2x16Mul2:
7072 case Match_InvalidSVEVectorList2x32Mul2:
7073 case Match_InvalidSVEVectorList2x64Mul2:
7074 case Match_InvalidSVEVectorList2x128Mul2:
7075 case Match_InvalidSVEVectorList4x8Mul4:
7076 case Match_InvalidSVEVectorList4x16Mul4:
7077 case Match_InvalidSVEVectorList4x32Mul4:
7078 case Match_InvalidSVEVectorList4x64Mul4:
7079 case Match_InvalidSVEVectorList4x128Mul4:
7080 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7081 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7082 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7083 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7084 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7085 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7086 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7087 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7088 case Match_InvalidSVEVectorList3x0_3b:
7089 case Match_InvalidSVEVectorListStrided2x8:
7090 case Match_InvalidSVEVectorListStrided2x16:
7091 case Match_InvalidSVEVectorListStrided2x32:
7092 case Match_InvalidSVEVectorListStrided2x64:
7093 case Match_InvalidSVEVectorListStrided4x8:
7094 case Match_InvalidSVEVectorListStrided4x16:
7095 case Match_InvalidSVEVectorListStrided4x32:
7096 case Match_InvalidSVEVectorListStrided4x64:
7100 return Error(IDLoc,
"too few operands for instruction",
7101 SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
7104 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
7105 if (ErrorLoc == SMLoc())
7107 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7115bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7122 SMLoc Loc = DirectiveID.
getLoc();
7123 if (IDVal ==
".arch")
7124 parseDirectiveArch(Loc);
7125 else if (IDVal ==
".cpu")
7126 parseDirectiveCPU(Loc);
7127 else if (IDVal ==
".tlsdesccall")
7128 parseDirectiveTLSDescCall(Loc,
false);
7129 else if (IDVal ==
".tlsauthdesccall")
7130 parseDirectiveTLSDescCall(Loc,
true);
7131 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7132 parseDirectiveLtorg(Loc);
7133 else if (IDVal ==
".unreq")
7134 parseDirectiveUnreq(Loc);
7135 else if (IDVal ==
".inst")
7136 parseDirectiveInst(Loc);
7137 else if (IDVal ==
".cfi_negate_ra_state")
7138 parseDirectiveCFINegateRAState();
7139 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7140 parseDirectiveCFINegateRAStateWithPC();
7141 else if (IDVal ==
".cfi_set_ra_state")
7142 parseDirectiveCFILLVMSetRAState();
7143 else if (IDVal ==
".cfi_b_key_frame")
7144 parseDirectiveCFIBKeyFrame();
7145 else if (IDVal ==
".cfi_mte_tagged_frame")
7146 parseDirectiveCFIMTETaggedFrame();
7147 else if (IDVal ==
".cfi_non_hint_pauth_frame")
7148 parseDirectiveCFINonHintPAuthFrame();
7149 else if (IDVal ==
".arch_extension")
7150 parseDirectiveArchExtension(Loc);
7151 else if (IDVal ==
".variant_pcs")
7152 parseDirectiveVariantPCS(Loc);
7155 parseDirectiveLOH(IDVal, Loc);
7158 }
else if (IsCOFF) {
7159 if (IDVal ==
".seh_stackalloc")
7160 parseDirectiveSEHAllocStack(Loc);
7161 else if (IDVal ==
".seh_endprologue")
7162 parseDirectiveSEHPrologEnd(Loc);
7163 else if (IDVal ==
".seh_end_c")
7164 parseDirectiveSEHEndC(Loc);
7165 else if (IDVal ==
".seh_save_r19r20_x")
7166 parseDirectiveSEHSaveR19R20X(Loc);
7167 else if (IDVal ==
".seh_save_fplr")
7168 parseDirectiveSEHSaveFPLR(Loc);
7169 else if (IDVal ==
".seh_save_fplr_x")
7170 parseDirectiveSEHSaveFPLRX(Loc);
7171 else if (IDVal ==
".seh_save_reg")
7172 parseDirectiveSEHSaveReg(Loc);
7173 else if (IDVal ==
".seh_save_reg_x")
7174 parseDirectiveSEHSaveRegX(Loc);
7175 else if (IDVal ==
".seh_save_regp")
7176 parseDirectiveSEHSaveRegP(Loc);
7177 else if (IDVal ==
".seh_save_regp_x")
7178 parseDirectiveSEHSaveRegPX(Loc);
7179 else if (IDVal ==
".seh_save_lrpair")
7180 parseDirectiveSEHSaveLRPair(Loc);
7181 else if (IDVal ==
".seh_save_freg")
7182 parseDirectiveSEHSaveFReg(Loc);
7183 else if (IDVal ==
".seh_save_freg_x")
7184 parseDirectiveSEHSaveFRegX(Loc);
7185 else if (IDVal ==
".seh_save_fregp")
7186 parseDirectiveSEHSaveFRegP(Loc);
7187 else if (IDVal ==
".seh_save_fregp_x")
7188 parseDirectiveSEHSaveFRegPX(Loc);
7189 else if (IDVal ==
".seh_set_fp")
7190 parseDirectiveSEHSetFP(Loc);
7191 else if (IDVal ==
".seh_add_fp")
7192 parseDirectiveSEHAddFP(Loc);
7193 else if (IDVal ==
".seh_nop")
7194 parseDirectiveSEHNop(Loc);
7195 else if (IDVal ==
".seh_save_next")
7196 parseDirectiveSEHSaveNext(Loc);
7197 else if (IDVal ==
".seh_startepilogue")
7198 parseDirectiveSEHEpilogStart(Loc);
7199 else if (IDVal ==
".seh_endepilogue")
7200 parseDirectiveSEHEpilogEnd(Loc);
7201 else if (IDVal ==
".seh_trap_frame")
7202 parseDirectiveSEHTrapFrame(Loc);
7203 else if (IDVal ==
".seh_pushframe")
7204 parseDirectiveSEHMachineFrame(Loc);
7205 else if (IDVal ==
".seh_context")
7206 parseDirectiveSEHContext(Loc);
7207 else if (IDVal ==
".seh_ec_context")
7208 parseDirectiveSEHECContext(Loc);
7209 else if (IDVal ==
".seh_clear_unwound_to_call")
7210 parseDirectiveSEHClearUnwoundToCall(Loc);
7211 else if (IDVal ==
".seh_pac_sign_lr")
7212 parseDirectiveSEHPACSignLR(Loc);
7213 else if (IDVal ==
".seh_save_any_reg")
7214 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7215 else if (IDVal ==
".seh_save_any_reg_p")
7216 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7217 else if (IDVal ==
".seh_save_any_reg_x")
7218 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7219 else if (IDVal ==
".seh_save_any_reg_px")
7220 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7221 else if (IDVal ==
".seh_allocz")
7222 parseDirectiveSEHAllocZ(Loc);
7223 else if (IDVal ==
".seh_save_zreg")
7224 parseDirectiveSEHSaveZReg(Loc);
7225 else if (IDVal ==
".seh_save_preg")
7226 parseDirectiveSEHSavePReg(Loc);
7230 if (IDVal ==
".aeabi_subsection")
7231 parseDirectiveAeabiSubSectionHeader(Loc);
7232 else if (IDVal ==
".aeabi_attribute")
7233 parseDirectiveAeabiAArch64Attr(Loc);
7246 if (!NoCrypto && Crypto) {
7249 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7250 ArchInfo == AArch64::ARMV8_3A) {
7254 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7255 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7256 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7257 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7258 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7259 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7265 }
else if (NoCrypto) {
7268 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7269 ArchInfo == AArch64::ARMV8_3A) {
7270 RequestedExtensions.
push_back(
"nosha2");
7273 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7274 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7275 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7276 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7277 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7278 ArchInfo == AArch64::ARMV9_4A) {
7280 RequestedExtensions.
push_back(
"nosha3");
7281 RequestedExtensions.
push_back(
"nosha2");
7293bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7294 SMLoc CurLoc = getLoc();
7296 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7297 StringRef Arch, ExtensionString;
7298 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7302 return Error(CurLoc,
"unknown arch name");
7308 std::vector<StringRef> AArch64Features;
7309 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7312 MCSubtargetInfo &STI = copySTI();
7313 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7315 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7318 if (!ExtensionString.
empty())
7319 ExtensionString.
split(RequestedExtensions,
'+');
7324 for (
auto Name : RequestedExtensions) {
7328 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7335 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7343 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7344 setAvailableFeatures(Features);
7346 getTargetStreamer().emitDirectiveArch(Name);
7352bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7353 SMLoc ExtLoc = getLoc();
7355 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7360 bool EnableFeature =
true;
7361 StringRef
Name = FullName;
7362 if (
Name.starts_with_insensitive(
"no")) {
7363 EnableFeature =
false;
7372 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7374 MCSubtargetInfo &STI = copySTI();
7379 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7380 setAvailableFeatures(Features);
7382 getTargetStreamer().emitDirectiveArchExtension(FullName);
7388bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7389 SMLoc CurLoc = getLoc();
7391 StringRef CPU, ExtensionString;
7392 std::tie(CPU, ExtensionString) =
7393 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7399 if (!ExtensionString.
empty())
7400 ExtensionString.
split(RequestedExtensions,
'+');
7404 Error(CurLoc,
"unknown CPU name");
7409 MCSubtargetInfo &STI = copySTI();
7413 for (
auto Name : RequestedExtensions) {
7417 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7424 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7432 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7433 setAvailableFeatures(Features);
7439bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7441 return Error(Loc,
"expected expression following '.inst' directive");
7443 auto parseOp = [&]() ->
bool {
7445 const MCExpr *Expr =
nullptr;
7446 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7449 if (check(!
Value, L,
"expected constant expression"))
7451 getTargetStreamer().emitInst(
Value->getValue());
7455 return parseMany(parseOp);
7461bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth) {
7463 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7474 Inst.
setOpcode(IsAuth ? AArch64::TLSAUTHDESCCALL : AArch64::TLSDESCCALL);
7477 getParser().getStreamer().emitInstruction(Inst, getSTI());
7483bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7487 return TokError(
"expected an identifier or a number in directive");
7490 int64_t
Id = getTok().getIntVal();
7492 return TokError(
"invalid numeric identifier in directive");
7495 StringRef
Name = getTok().getIdentifier();
7501 return TokError(
"invalid identifier in directive");
7509 assert(NbArgs != -1 &&
"Invalid number of arguments");
7512 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7514 if (getParser().parseIdentifier(Name))
7515 return TokError(
"expected identifier in directive");
7518 if (Idx + 1 == NbArgs)
7526 getStreamer().emitLOHDirective(Kind, Args);
7532bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7535 getTargetStreamer().emitCurrentConstantPool();
7541bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7543 SMLoc SRegLoc = getLoc();
7544 RegKind RegisterKind = RegKind::Scalar;
7546 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7550 RegisterKind = RegKind::NeonVector;
7551 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7557 return Error(SRegLoc,
"vector register without type specifier expected");
7562 RegisterKind = RegKind::SVEDataVector;
7564 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7570 return Error(SRegLoc,
7571 "sve vector register without type specifier expected");
7576 RegisterKind = RegKind::SVEPredicateVector;
7577 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7583 return Error(SRegLoc,
7584 "sve predicate register without type specifier expected");
7588 return Error(SRegLoc,
"register name or alias expected");
7594 auto pair = std::make_pair(RegisterKind, RegNum);
7595 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7596 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7603bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7605 return TokError(
"unexpected input in .unreq directive.");
7606 RegisterReqs.
erase(getTok().getIdentifier().lower());
7611bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7614 getStreamer().emitCFINegateRAState();
7618bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7621 getStreamer().emitCFINegateRAStateWithPC();
7628bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7630 if (getParser().parseAbsoluteExpression(State))
7635 SMLoc ExprLoc = getLoc();
7636 if (getParser().parseExpression(Expr))
7641 getStreamer().emitCFILLVMSetRAState(
7642 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7644 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7648 "expected an integer offset or a symbol for .cfi_set_ra_state");
7655bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7658 getStreamer().emitCFIBKeyFrame();
7664bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7667 getStreamer().emitCFIMTETaggedFrame();
7673bool AArch64AsmParser::parseDirectiveCFINonHintPAuthFrame() {
7676 getStreamer().emitCFINonHintPAuthFrame();
7682bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7684 if (getParser().parseIdentifier(Name))
7685 return TokError(
"expected symbol name");
7688 getTargetStreamer().emitDirectiveVariantPCS(
7695bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7697 if (parseImmExpr(
Size))
7699 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7705bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7706 getTargetStreamer().emitARM64WinCFIPrologEnd();
7710bool AArch64AsmParser::parseDirectiveSEHEndC(SMLoc L) {
7711 getTargetStreamer().emitARM64WinCFIEndC();
7717bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7719 if (parseImmExpr(
Offset))
7721 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7727bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7729 if (parseImmExpr(
Offset))
7731 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7737bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7739 if (parseImmExpr(
Offset))
7741 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7747bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7750 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7751 parseComma() || parseImmExpr(
Offset))
7753 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7759bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7762 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7763 parseComma() || parseImmExpr(
Offset))
7765 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7771bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7774 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7775 parseComma() || parseImmExpr(
Offset))
7777 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7783bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7786 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7787 parseComma() || parseImmExpr(
Offset))
7789 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7795bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7799 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7800 parseComma() || parseImmExpr(
Offset))
7802 if (check(((
Reg - 19) % 2 != 0), L,
7803 "expected register with even offset from x19"))
7805 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7811bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7814 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7815 parseComma() || parseImmExpr(
Offset))
7817 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7823bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7826 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7827 parseComma() || parseImmExpr(
Offset))
7829 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7835bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7838 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7839 parseComma() || parseImmExpr(
Offset))
7841 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7847bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7850 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7851 parseComma() || parseImmExpr(
Offset))
7853 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7859bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7860 getTargetStreamer().emitARM64WinCFISetFP();
7866bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7868 if (parseImmExpr(
Size))
7870 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7876bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7877 getTargetStreamer().emitARM64WinCFINop();
7883bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7884 getTargetStreamer().emitARM64WinCFISaveNext();
7890bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7891 getTargetStreamer().emitARM64WinCFIEpilogStart();
7897bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7898 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7904bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7905 getTargetStreamer().emitARM64WinCFITrapFrame();
7911bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7912 getTargetStreamer().emitARM64WinCFIMachineFrame();
7918bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7919 getTargetStreamer().emitARM64WinCFIContext();
7925bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7926 getTargetStreamer().emitARM64WinCFIECContext();
7932bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7933 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7939bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7940 getTargetStreamer().emitARM64WinCFIPACSignLR();
7949bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7954 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register") ||
7955 parseComma() || parseImmExpr(
Offset))
7958 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7959 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7960 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7961 return Error(L,
"invalid save_any_reg offset");
7962 unsigned EncodedReg;
7963 if (
Reg == AArch64::FP)
7965 else if (
Reg == AArch64::LR)
7968 EncodedReg =
Reg - AArch64::X0;
7970 if (
Reg == AArch64::LR)
7971 return Error(Start,
"lr cannot be paired with another register");
7973 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7975 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7978 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7980 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7982 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7983 unsigned EncodedReg =
Reg - AArch64::D0;
7984 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7985 return Error(L,
"invalid save_any_reg offset");
7987 if (
Reg == AArch64::D31)
7988 return Error(Start,
"d31 cannot be paired with another register");
7990 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7992 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7995 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7997 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7999 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
8000 unsigned EncodedReg =
Reg - AArch64::Q0;
8002 return Error(L,
"invalid save_any_reg offset");
8004 if (
Reg == AArch64::Q31)
8005 return Error(Start,
"q31 cannot be paired with another register");
8007 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
8009 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
8012 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
8014 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
8017 return Error(Start,
"save_any_reg register must be x, q or d register");
8024bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8026 if (parseImmExpr(
Offset))
8028 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8034bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8039 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8042 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8043 "expected register in range z8 to z23"))
8045 if (parseComma() || parseImmExpr(
Offset))
8047 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8053bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8058 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8061 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8062 "expected register in range p4 to p15"))
8064 if (parseComma() || parseImmExpr(
Offset))
8066 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8070bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8076 MCAsmParser &Parser = getParser();
8079 StringRef SubsectionName;
8090 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8091 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8096 if (SubsectionExists) {
8097 getTargetStreamer().emitAttributesSubsection(
8100 SubsectionExists->IsOptional),
8102 SubsectionExists->ParameterType));
8108 "Could not switch to subsection '" + SubsectionName +
8109 "' using subsection name, subsection has not been defined");
8132 if (SubsectionExists) {
8133 if (IsOptional != SubsectionExists->IsOptional) {
8135 "optionality mismatch! subsection '" + SubsectionName +
8136 "' already exists with optionality defined as '" +
8138 SubsectionExists->IsOptional) +
8146 "optionality parameter not found, expected required|optional");
8153 "aeabi_feature_and_bits must be marked as optional");
8160 "aeabi_pauthabi must be marked as required");
8180 if (SubsectionExists) {
8181 if (
Type != SubsectionExists->ParameterType) {
8183 "type mismatch! subsection '" + SubsectionName +
8184 "' already exists with type defined as '" +
8186 SubsectionExists->ParameterType) +
8194 "type parameter not found, expected uleb128|ntbs");
8202 SubsectionName +
" must be marked as ULEB128");
8211 "attributes subsection header directive");
8215 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8220bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8224 MCAsmParser &Parser = getParser();
8226 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8227 getTargetStreamer().getActiveAttributesSubsection();
8228 if (
nullptr == ActiveSubsection) {
8230 "no active subsection, build attribute can not be added");
8233 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8234 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8242 ActiveSubsectionName)
8245 StringRef TagStr =
"";
8248 Tag = getTok().getIntVal();
8251 switch (ActiveSubsectionID) {
8256 "' \nExcept for public subsections, "
8257 "tags have to be an unsigned int.");
8264 TagStr +
"' for subsection '" +
8265 ActiveSubsectionName +
"'");
8273 TagStr +
"' for subsection '" +
8274 ActiveSubsectionName +
"'");
8292 unsigned ValueInt = unsigned(-1);
8293 std::string ValueStr =
"";
8298 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8301 ValueInt = getTok().getIntVal();
8306 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8314 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8325 if (0 != ValueInt && 1 != ValueInt) {
8327 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8328 "' options are 0|1");
8337 "unexpected token for AArch64 build attributes tag and value "
8338 "attribute directive");
8342 if (
unsigned(-1) != ValueInt) {
8343 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8345 if (
"" != ValueStr) {
8346 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8352bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8353 SMLoc Loc = getLoc();
8355 return TokError(
"expected '%' relocation specifier");
8356 StringRef
Identifier = getParser().getTok().getIdentifier();
8359 return TokError(
"invalid relocation specifier");
8365 const MCExpr *SubExpr;
8366 if (getParser().parseParenExpression(SubExpr,
E))
8373bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8376 return parseExprWithSpecifier(Res, EndLoc);
8378 if (getParser().parseExpression(Res))
8380 MCAsmParser &Parser = getParser();
8384 return Error(getLoc(),
"expected relocation specifier");
8387 SMLoc Loc = getLoc();
8389 if (Identifier ==
"auth")
8390 return parseAuthExpr(Res, EndLoc);
8394 if (Identifier ==
"got")
8398 return Error(Loc,
"invalid relocation specifier");
8403 return Error(Loc,
"@ specifier only allowed after a symbol");
8406 std::optional<MCBinaryExpr::Opcode> Opcode;
8414 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8425bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8426 MCAsmParser &Parser = getParser();
8434 return TokError(
"expected key name");
8439 return TokError(
"invalid key '" + KeyStr +
"'");
8446 return TokError(
"expected integer discriminator");
8450 return TokError(
"integer discriminator " + Twine(Discriminator) +
8451 " out of range [0, 0xFFFF]");
8454 bool UseAddressDiversity =
false;
8459 return TokError(
"expected 'addr'");
8460 UseAddressDiversity =
true;
8469 UseAddressDiversity, Ctx, Res->
getLoc());
8473bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8482 ELFSpec = AE->getSpecifier();
8483 Expr = AE->getSubExpr();
8523#define GET_REGISTER_MATCHER
8524#define GET_SUBTARGET_FEATURE_NAME
8525#define GET_MATCHER_IMPLEMENTATION
8526#define GET_MNEMONIC_SPELL_CHECKER
8527#include "AArch64GenAsmMatcher.inc"
8533 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8535 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8537 return Match_InvalidOperand;
8540 return Match_InvalidOperand;
8541 if (CE->getValue() == ExpectedVal)
8542 return Match_Success;
8543 return Match_InvalidOperand;
8548 return Match_InvalidOperand;
8554 if (
Op.isTokenEqual(
"za"))
8555 return Match_Success;
8556 return Match_InvalidOperand;
8562#define MATCH_HASH(N) \
8563 case MCK__HASH_##N: \
8564 return MatchesOpImmediate(N);
8590#define MATCH_HASH_MINUS(N) \
8591 case MCK__HASH__MINUS_##N: \
8592 return MatchesOpImmediate(-N);
8596#undef MATCH_HASH_MINUS
8605 return Error(S,
"expected register");
8607 MCRegister FirstReg;
8608 ParseStatus Res = tryParseScalarRegister(FirstReg);
8610 return Error(S,
"expected first even register of a consecutive same-size "
8611 "even/odd register pair");
8613 const MCRegisterClass &WRegClass =
8614 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8615 const MCRegisterClass &XRegClass =
8616 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8618 bool isXReg = XRegClass.
contains(FirstReg),
8619 isWReg = WRegClass.
contains(FirstReg);
8620 if (!isXReg && !isWReg)
8621 return Error(S,
"expected first even register of a consecutive same-size "
8622 "even/odd register pair");
8624 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8627 if (FirstEncoding & 0x1)
8628 return Error(S,
"expected first even register of a consecutive same-size "
8629 "even/odd register pair");
8632 return Error(getLoc(),
"expected comma");
8637 MCRegister SecondReg;
8638 Res = tryParseScalarRegister(SecondReg);
8640 return Error(
E,
"expected second odd register of a consecutive same-size "
8641 "even/odd register pair");
8644 (isXReg && !XRegClass.
contains(SecondReg)) ||
8645 (isWReg && !WRegClass.
contains(SecondReg)))
8646 return Error(
E,
"expected second odd register of a consecutive same-size "
8647 "even/odd register pair");
8652 FirstReg, AArch64::sube64,
8653 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8656 FirstReg, AArch64::sube32,
8657 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8660 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8666template <
bool ParseShiftExtend,
bool ParseSuffix>
8668 const SMLoc S = getLoc();
8674 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8679 if (ParseSuffix &&
Kind.empty())
8686 unsigned ElementWidth = KindRes->second;
8690 Operands.push_back(AArch64Operand::CreateVectorReg(
8691 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8693 ParseStatus Res = tryParseVectorIndex(
Operands);
8704 Res = tryParseOptionalShiftExtend(ExtOpnd);
8708 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8709 Operands.push_back(AArch64Operand::CreateVectorReg(
8710 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8711 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8712 Ext->hasShiftExtendAmount()));
8718 SMLoc
SS = getLoc();
8719 const AsmToken &TokE = getTok();
8724 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8729 int64_t Pattern = Pat->Encoding;
8730 assert(Pattern >= 0 && Pattern < 32);
8742 SMLoc
SS = getLoc();
8743 const AsmToken &TokE = getTok();
8745 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8751 Pattern = Pat->Encoding;
8752 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8762 SMLoc
SS = getLoc();
8765 if (!tryParseScalarRegister(XReg).isSuccess())
8771 XReg, AArch64::x8sub_0,
8772 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8775 "expected an even-numbered x-register in the range [x0,x22]");
8778 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8792 if (getParser().parseExpression(ImmF))
8802 SMLoc
E = getTok().getLoc();
8804 if (getParser().parseExpression(ImmL))
8811 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
SmallVector< MachineOperand, 4 > Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
APInt bitcastToAPInt() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void UnLex(AsmToken const &Token)
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
const MCRegisterDesc & get(MCRegister Reg) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
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.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
LLVM_ABI std::string lower() const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI SubsectionType getTypeID(StringRef Type)
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
LLVM_ABI StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
LLVM_ABI StringRef getSubsectionTypeUnknownError()
LLVM_ABI SubsectionOptional getOptionalID(StringRef Optional)
LLVM_ABI StringRef getSubsectionOptionalUnknownError()
LLVM_ABI FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
LLVM_ABI VendorID getVendorID(StringRef const Vendor)
LLVM_ABI PauthABITags getPauthABITagsID(StringRef PauthABITag)
LLVM_ABI StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
uint32_t parseGenericRegister(StringRef Name)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool isSVEAddSubImm(int64_t Imm)
Returns true if Imm is valid for ADD/SUB.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static bool isSVECpyImm(int64_t Imm)
Returns true if Imm is valid for CPY/DUP.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
VectorKind
Distinguishes the vector flavors that ABIs have to treat differently.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static int MCLOHNameToId(StringRef Name)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
@ End
Run the machine verifier once, at the end of the pipeline.
StringTable::Offset ArchFeature
AArch64::ExtensionBitset DefaultExts
Compile-time data representation of enum entries.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
bool haveFeatures(FeatureBitset ActiveFeatures) const