73 SVEPredicateAsCounter,
79enum class MatrixKind { Array, Tile, Row, Col };
81enum RegConstraintEqualityTy {
92 StringMap<std::pair<RegKind, MCRegister>> RegisterReqs;
96 static PrefixInfo CreateFromInst(
const MCInst &Inst,
uint64_t TSFlags) {
99 case AArch64::MOVPRFX_ZZ:
103 case AArch64::MOVPRFX_ZPmZ_B:
104 case AArch64::MOVPRFX_ZPmZ_H:
105 case AArch64::MOVPRFX_ZPmZ_S:
106 case AArch64::MOVPRFX_ZPmZ_D:
111 "No destructive element size set for movprfx");
115 case AArch64::MOVPRFX_ZPzZ_B:
116 case AArch64::MOVPRFX_ZPzZ_H:
117 case AArch64::MOVPRFX_ZPzZ_S:
118 case AArch64::MOVPRFX_ZPzZ_D:
123 "No destructive element size set for movprfx");
134 PrefixInfo() =
default;
135 bool isActive()
const {
return Active; }
137 unsigned getElementSize()
const {
141 MCRegister getDstReg()
const {
return Dst; }
142 MCRegister getPgReg()
const {
149 bool Predicated =
false;
150 unsigned ElementSize;
155 AArch64TargetStreamer &getTargetStreamer() {
156 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
157 return static_cast<AArch64TargetStreamer &
>(TS);
160 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
167 std::string &Suggestion);
169 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
171 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
177 bool invertCondCode);
178 bool parseImmExpr(int64_t &Out);
180 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool showMatchError(SMLoc Loc,
unsigned ErrCode,
uint64_t ErrorInfo,
186 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
187 bool parseDataExpr(
const MCExpr *&Res)
override;
188 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
190 bool parseDirectiveArch(SMLoc L);
191 bool parseDirectiveArchExtension(SMLoc L);
192 bool parseDirectiveCPU(SMLoc L);
193 bool parseDirectiveInst(SMLoc L);
195 bool parseDirectiveTLSDescCall(SMLoc L);
197 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
198 bool parseDirectiveLtorg(SMLoc L);
200 bool parseDirectiveReq(StringRef Name, SMLoc L);
201 bool parseDirectiveUnreq(SMLoc L);
202 bool parseDirectiveCFINegateRAState();
203 bool parseDirectiveCFINegateRAStateWithPC();
204 bool parseDirectiveCFILLVMSetRAState();
205 bool parseDirectiveCFIBKeyFrame();
206 bool parseDirectiveCFIMTETaggedFrame();
208 bool parseDirectiveVariantPCS(SMLoc L);
210 bool parseDirectiveSEHAllocStack(SMLoc L);
211 bool parseDirectiveSEHPrologEnd(SMLoc L);
212 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
213 bool parseDirectiveSEHSaveFPLR(SMLoc L);
214 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
215 bool parseDirectiveSEHSaveReg(SMLoc L);
216 bool parseDirectiveSEHSaveRegX(SMLoc L);
217 bool parseDirectiveSEHSaveRegP(SMLoc L);
218 bool parseDirectiveSEHSaveRegPX(SMLoc L);
219 bool parseDirectiveSEHSaveLRPair(SMLoc L);
220 bool parseDirectiveSEHSaveFReg(SMLoc L);
221 bool parseDirectiveSEHSaveFRegX(SMLoc L);
222 bool parseDirectiveSEHSaveFRegP(SMLoc L);
223 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
224 bool parseDirectiveSEHSetFP(SMLoc L);
225 bool parseDirectiveSEHAddFP(SMLoc L);
226 bool parseDirectiveSEHNop(SMLoc L);
227 bool parseDirectiveSEHSaveNext(SMLoc L);
228 bool parseDirectiveSEHEpilogStart(SMLoc L);
229 bool parseDirectiveSEHEpilogEnd(SMLoc L);
230 bool parseDirectiveSEHTrapFrame(SMLoc L);
231 bool parseDirectiveSEHMachineFrame(SMLoc L);
232 bool parseDirectiveSEHContext(SMLoc L);
233 bool parseDirectiveSEHECContext(SMLoc L);
234 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
235 bool parseDirectiveSEHPACSignLR(SMLoc L);
236 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
237 bool parseDirectiveSEHAllocZ(SMLoc L);
238 bool parseDirectiveSEHSaveZReg(SMLoc L);
239 bool parseDirectiveSEHSavePReg(SMLoc L);
240 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
241 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
243 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
244 SmallVectorImpl<SMLoc> &Loc);
245 unsigned getNumRegsForRegKind(RegKind K);
246 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
249 bool MatchingInlineAsm)
override;
253#define GET_ASSEMBLER_HEADER
254#include "AArch64GenAsmMatcher.inc"
268 template <
bool IsSVEPrefetch = false>
274 template <
bool AddFPZeroAsLiteral>
282 template <
bool ParseShiftExtend,
283 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
286 template <
bool ParseShiftExtend,
bool ParseSuffix>
288 template <RegKind RK>
292 template <RegKind VectorKind>
294 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>
bool isSImm()
const {
782 return bool(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>
bool isUImm12Offset()
const {
893 return isSymbolicUImm12Offset(
getImm());
896 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
899 template <
int N,
int M>
900 bool isImmInRange()
const {
907 return (Val >=
N && Val <= M);
910 bool isHinteUImm16()
const {
917 return Val >= 0 && Val <= 65535 &&
918 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
923 template <
typename T>
924 bool isLogicalImm()
const {
941 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
943 bool isImmRange()
const {
return Kind == k_ImmRange; }
948 template <
unsigned W
idth>
949 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
950 if (isShiftedImm() && Width == getShiftedImmShift())
952 return std::make_pair(
CE->getValue(), Width);
956 int64_t Val =
CE->getValue();
958 return std::make_pair(Val >> Width, Width);
960 return std::make_pair(Val, 0u);
966 bool isAddSubImm()
const {
967 if (!isShiftedImm() && !isImm())
973 if (isShiftedImm()) {
974 unsigned Shift = ShiftedImm.ShiftAmount;
975 Expr = ShiftedImm.Val;
976 if (Shift != 0 && Shift != 12)
985 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1001 if (
auto ShiftedVal = getShiftedVal<12>())
1002 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1009 bool isAddSubImmNeg()
const {
1010 if (!isShiftedImm() && !isImm())
1014 if (
auto ShiftedVal = getShiftedVal<12>())
1015 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1025 template <
typename T>
1026 DiagnosticPredicate isSVECpyImm()
const {
1030 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1031 std::is_same<int8_t, T>::value;
1032 if (
auto ShiftedImm = getShiftedVal<8>())
1033 if (!(IsByte && ShiftedImm->second) &&
1035 << ShiftedImm->second))
1044 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1048 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1049 std::is_same<int8_t, T>::value;
1050 if (
auto ShiftedImm = getShiftedVal<8>())
1051 if (!(IsByte && ShiftedImm->second) &&
1053 << ShiftedImm->second))
1059 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1060 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1067 bool isSIMDImmType10()
const {
1077 bool isBranchTarget()
const {
1086 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1087 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1097 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1107 bool isMovWSymbolG3()
const {
1111 bool isMovWSymbolG2()
const {
1118 bool isMovWSymbolG1()
const {
1126 bool isMovWSymbolG0()
const {
1134 template<
int RegW
idth,
int Shift>
1135 bool isMOVZMovAlias()
const {
1136 if (!isImm())
return false;
1149 template<
int RegW
idth,
int Shift>
1150 bool isMOVNMovAlias()
const {
1151 if (!isImm())
return false;
1154 if (!CE)
return false;
1160 bool isFPImm()
const {
1161 return Kind == k_FPImm &&
1165 bool isBarrier()
const {
1166 return Kind == k_Barrier && !getBarriernXSModifier();
1168 bool isBarriernXS()
const {
1169 return Kind == k_Barrier && getBarriernXSModifier();
1171 bool isSysReg()
const {
return Kind == k_SysReg; }
1173 bool isMRSSystemRegister()
const {
1174 if (!isSysReg())
return false;
1176 return SysReg.MRSReg != -1U;
1179 bool isMSRSystemRegister()
const {
1180 if (!isSysReg())
return false;
1181 return SysReg.MSRReg != -1U;
1184 bool isSystemPStateFieldWithImm0_1()
const {
1185 if (!isSysReg())
return false;
1186 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1189 bool isSystemPStateFieldWithImm0_15()
const {
1192 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1195 bool isSVCR()
const {
1198 return SVCR.PStateField != -1U;
1201 bool isReg()
const override {
1202 return Kind == k_Register;
1205 bool isVectorList()
const {
return Kind == k_VectorList; }
1207 bool isScalarReg()
const {
1208 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1211 bool isNeonVectorReg()
const {
1212 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1215 bool isNeonVectorRegLo()
const {
1216 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1217 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1218 .contains(
Reg.Reg) ||
1219 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1220 .contains(
Reg.Reg));
1223 bool isNeonVectorReg0to7()
const {
1224 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1225 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1226 .contains(
Reg.Reg));
1229 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1230 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1232 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1235 case AArch64::PPRRegClassID:
1236 case AArch64::PPR_3bRegClassID:
1237 case AArch64::PPR_p8to15RegClassID:
1238 case AArch64::PNRRegClassID:
1239 case AArch64::PNR_p8to15RegClassID:
1240 case AArch64::PPRorPNRRegClassID:
1241 RK = RegKind::SVEPredicateAsCounter;
1247 return (Kind == k_Register &&
Reg.Kind == RK) &&
1248 getAArch64MCRegisterClass(Class).contains(
getReg());
1251 template <
unsigned Class>
bool isSVEVectorReg()
const {
1254 case AArch64::ZPRRegClassID:
1255 case AArch64::ZPR_3bRegClassID:
1256 case AArch64::ZPR_4bRegClassID:
1257 case AArch64::ZPRMul2_LoRegClassID:
1258 case AArch64::ZPRMul2_HiRegClassID:
1259 case AArch64::ZPR_KRegClassID:
1260 RK = RegKind::SVEDataVector;
1262 case AArch64::PPRRegClassID:
1263 case AArch64::PPR_3bRegClassID:
1264 case AArch64::PPR_p8to15RegClassID:
1265 case AArch64::PNRRegClassID:
1266 case AArch64::PNR_p8to15RegClassID:
1267 case AArch64::PPRorPNRRegClassID:
1268 RK = RegKind::SVEPredicateVector;
1274 return (Kind == k_Register &&
Reg.Kind == RK) &&
1275 getAArch64MCRegisterClass(Class).contains(
getReg());
1278 template <
unsigned Class>
bool isFPRasZPR()
const {
1279 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1280 getAArch64MCRegisterClass(Class).contains(
getReg());
1283 template <
int ElementW
idth,
unsigned Class>
1284 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1285 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1288 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1294 template <
int ElementW
idth,
unsigned Class>
1295 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1296 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1297 Reg.Kind != RegKind::SVEPredicateVector))
1300 if ((isSVEPredicateAsCounterReg<Class>() ||
1301 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1302 Reg.ElementWidth == ElementWidth)
1308 template <
int ElementW
idth,
unsigned Class>
1309 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1310 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1313 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1319 template <
int ElementW
idth,
unsigned Class>
1320 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1321 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1324 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1330 template <
int ElementWidth,
unsigned Class,
1332 bool ShiftWidthAlwaysSame>
1333 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1334 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1335 if (!VectorMatch.isMatch())
1341 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1344 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1347 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1353 bool isGPR32as64()
const {
1354 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1355 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1359 bool isGPR64as32()
const {
1360 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1361 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1365 bool isGPR64x8()
const {
1366 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1367 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1371 bool isWSeqPair()
const {
1372 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1373 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1377 bool isXSeqPair()
const {
1378 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1379 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1383 bool isSyspXzrPair()
const {
1387 template<
int64_t Angle,
int64_t Remainder>
1388 DiagnosticPredicate isComplexRotation()
const {
1397 if (
Value % Angle == Remainder &&
Value <= 270)
1402 template <
unsigned RegClassID>
bool isGPR64()
const {
1403 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1404 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1407 template <
unsigned RegClassID,
int ExtW
idth>
1408 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1409 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1413 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1420 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1421 bool isImplicitlyTypedVectorList()
const {
1422 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1423 VectorList.NumElements == 0 &&
1424 VectorList.RegisterKind == VectorKind &&
1425 (!IsConsecutive || (VectorList.Stride == 1));
1428 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1429 unsigned ElementWidth,
unsigned Stride = 1>
1430 bool isTypedVectorList()
const {
1431 if (Kind != k_VectorList)
1433 if (VectorList.Count != NumRegs)
1435 if (VectorList.RegisterKind != VectorKind)
1437 if (VectorList.ElementWidth != ElementWidth)
1439 if (VectorList.Stride != Stride)
1441 return VectorList.NumElements == NumElements;
1444 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1445 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1447 DiagnosticPredicate isTypedVectorListInRange()
const {
1449 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1452 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1453 (VectorList.Reg - FirstReg) % Multiple != 0)
1458 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1459 unsigned ElementWidth>
1460 DiagnosticPredicate isTypedVectorListStrided()
const {
1461 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1462 ElementWidth, Stride>();
1465 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1466 ((VectorList.Reg >= AArch64::Z16) &&
1467 (VectorList.Reg < (AArch64::Z16 + Stride))))
1472 template <
int Min,
int Max>
1473 DiagnosticPredicate isVectorIndex()
const {
1474 if (Kind != k_VectorIndex)
1476 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1481 bool isToken()
const override {
return Kind == k_Token; }
1483 bool isTokenEqual(StringRef Str)
const {
1484 return Kind == k_Token &&
getToken() == Str;
1486 bool isSysCR()
const {
return Kind == k_SysCR; }
1487 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1488 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1489 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1490 bool isShifter()
const {
1491 if (!isShiftExtend())
1500 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1501 if (Kind != k_FPImm)
1504 if (getFPImmIsExact()) {
1506 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1508 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1511 APFloat RealVal(APFloat::IEEEdouble());
1513 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1514 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1517 if (
getFPImm().bitwiseIsEqual(RealVal))
1524 template <
unsigned ImmA,
unsigned ImmB>
1525 DiagnosticPredicate isExactFPImm()
const {
1527 if ((Res = isExactFPImm<ImmA>()))
1529 if ((Res = isExactFPImm<ImmB>()))
1534 bool isExtend()
const {
1535 if (!isShiftExtend())
1544 getShiftExtendAmount() <= 4;
1547 bool isExtend64()
const {
1557 bool isExtendLSL64()
const {
1563 getShiftExtendAmount() <= 4;
1566 bool isLSLImm3Shift()
const {
1567 if (!isShiftExtend())
1573 template<
int W
idth>
bool isMemXExtend()
const {
1578 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1579 getShiftExtendAmount() == 0);
1582 template<
int W
idth>
bool isMemWExtend()
const {
1587 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1588 getShiftExtendAmount() == 0);
1591 template <
unsigned w
idth>
1592 bool isArithmeticShifter()
const {
1602 template <
unsigned w
idth>
1603 bool isLogicalShifter()
const {
1611 getShiftExtendAmount() < width;
1614 bool isMovImm32Shifter()
const {
1622 uint64_t Val = getShiftExtendAmount();
1623 return (Val == 0 || Val == 16);
1626 bool isMovImm64Shifter()
const {
1634 uint64_t Val = getShiftExtendAmount();
1635 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1638 bool isLogicalVecShifter()
const {
1643 unsigned Shift = getShiftExtendAmount();
1645 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1648 bool isLogicalVecHalfWordShifter()
const {
1649 if (!isLogicalVecShifter())
1653 unsigned Shift = getShiftExtendAmount();
1655 (Shift == 0 || Shift == 8);
1658 bool isMoveVecShifter()
const {
1659 if (!isShiftExtend())
1663 unsigned Shift = getShiftExtendAmount();
1665 (Shift == 8 || Shift == 16);
1674 bool isSImm9OffsetFB()
const {
1675 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1678 bool isAdrpLabel()
const {
1685 int64_t Val =
CE->getValue();
1686 int64_t Min = - (4096 * (1LL << (21 - 1)));
1687 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1688 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1694 bool isAdrLabel()
const {
1701 int64_t Val =
CE->getValue();
1702 int64_t Min = - (1LL << (21 - 1));
1703 int64_t
Max = ((1LL << (21 - 1)) - 1);
1704 return Val >= Min && Val <=
Max;
1710 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1711 DiagnosticPredicate isMatrixRegOperand()
const {
1714 if (getMatrixKind() != Kind ||
1715 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1716 EltSize != getMatrixElementWidth())
1721 bool isPAuthPCRelLabel16Operand()
const {
1733 return (Val <= 0) && (Val > -(1 << 18));
1736 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1746 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1747 assert(
N == 1 &&
"Invalid number of operands!");
1751 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1752 assert(
N == 1 &&
"Invalid number of operands!");
1756 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1757 assert(
N == 1 &&
"Invalid number of operands!");
1759 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1761 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1768 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1769 assert(
N == 1 &&
"Invalid number of operands!");
1771 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1773 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1780 template <
int W
idth>
1781 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1784 case 8:
Base = AArch64::B0;
break;
1785 case 16:
Base = AArch64::H0;
break;
1786 case 32:
Base = AArch64::S0;
break;
1787 case 64:
Base = AArch64::D0;
break;
1788 case 128:
Base = AArch64::Q0;
break;
1795 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1796 assert(
N == 1 &&
"Invalid number of operands!");
1799 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1800 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1804 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1805 assert(
N == 1 &&
"Invalid number of operands!");
1810 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1811 assert(
N == 1 &&
"Invalid number of operands!");
1812 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1817 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1818 assert(
N == 1 &&
"Invalid number of operands!");
1819 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1824 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1825 assert(
N == 1 &&
"Invalid number of operands!");
1829 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1830 assert(
N == 1 &&
"Invalid number of operands!");
1834 enum VecListIndexType {
1835 VecListIdx_DReg = 0,
1836 VecListIdx_QReg = 1,
1837 VecListIdx_ZReg = 2,
1838 VecListIdx_PReg = 3,
1841 template <VecListIndexType RegTy,
unsigned NumRegs,
1842 bool IsConsecutive =
false>
1843 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1844 assert(
N == 1 &&
"Invalid number of operands!");
1845 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1846 "Expected consecutive registers");
1847 static const unsigned FirstRegs[][5] = {
1849 AArch64::D0, AArch64::D0_D1,
1850 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1852 AArch64::Q0, AArch64::Q0_Q1,
1853 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1855 AArch64::Z0, AArch64::Z0_Z1,
1856 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1858 AArch64::P0, AArch64::P0_P1 }
1861 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1862 " NumRegs must be <= 4 for ZRegs");
1864 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1865 " NumRegs must be <= 2 for PRegs");
1867 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1869 FirstRegs[(
unsigned)RegTy][0]));
1872 template <
unsigned NumRegs>
1873 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1874 assert(
N == 1 &&
"Invalid number of operands!");
1875 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1879 if (getVectorListStart() < AArch64::Z16) {
1880 assert((getVectorListStart() < AArch64::Z8) &&
1881 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1883 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1885 assert((getVectorListStart() < AArch64::Z24) &&
1886 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1888 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1892 if (getVectorListStart() < AArch64::Z16) {
1893 assert((getVectorListStart() < AArch64::Z4) &&
1894 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1896 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1898 assert((getVectorListStart() < AArch64::Z20) &&
1899 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1901 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1909 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1910 assert(
N == 1 &&
"Invalid number of operands!");
1911 unsigned RegMask = getMatrixTileListRegMask();
1912 assert(RegMask <= 0xFF &&
"Invalid mask!");
1916 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1917 assert(
N == 1 &&
"Invalid number of operands!");
1921 template <
unsigned ImmIs0,
unsigned ImmIs1>
1922 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1923 assert(
N == 1 &&
"Invalid number of operands!");
1924 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1928 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1929 assert(
N == 1 &&
"Invalid number of operands!");
1936 template <
int Shift>
1937 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1938 assert(
N == 2 &&
"Invalid number of operands!");
1939 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1942 }
else if (isShiftedImm()) {
1943 addExpr(Inst, getShiftedImmVal());
1951 template <
int Shift>
1952 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1953 assert(
N == 2 &&
"Invalid number of operands!");
1954 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1961 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1962 assert(
N == 1 &&
"Invalid number of operands!");
1966 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1967 assert(
N == 1 &&
"Invalid number of operands!");
1975 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1976 addImmOperands(Inst,
N);
1980 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1981 assert(
N == 1 &&
"Invalid number of operands!");
1991 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1992 assert(
N == 1 &&
"Invalid number of operands!");
1997 template <
int Scale>
1998 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
1999 assert(
N == 1 &&
"Invalid number of operands!");
2004 template <
int Scale>
2005 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2006 assert(
N == 1 &&
"Invalid number of operands!");
2010 template <
typename T>
2011 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2012 assert(
N == 1 &&
"Invalid number of operands!");
2014 std::make_unsigned_t<T> Val = MCE->
getValue();
2019 template <
typename T>
2020 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2021 assert(
N == 1 &&
"Invalid number of operands!");
2023 std::make_unsigned_t<T> Val = ~MCE->getValue();
2028 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2029 assert(
N == 1 &&
"Invalid number of operands!");
2035 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2039 assert(
N == 1 &&
"Invalid number of operands!");
2045 assert(MCE &&
"Invalid constant immediate operand!");
2049 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2053 assert(
N == 1 &&
"Invalid number of operands!");
2062 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2066 assert(
N == 1 &&
"Invalid number of operands!");
2072 assert(MCE &&
"Invalid constant immediate operand!");
2076 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2080 assert(
N == 1 &&
"Invalid number of operands!");
2086 assert(MCE &&
"Invalid constant immediate operand!");
2090 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2094 assert(
N == 1 &&
"Invalid number of operands!");
2100 assert(MCE &&
"Invalid constant immediate operand!");
2104 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2105 assert(
N == 1 &&
"Invalid number of operands!");
2110 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2111 assert(
N == 1 &&
"Invalid number of operands!");
2115 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2116 assert(
N == 1 &&
"Invalid number of operands!");
2120 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2121 assert(
N == 1 &&
"Invalid number of operands!");
2126 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2127 assert(
N == 1 &&
"Invalid number of operands!");
2132 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2133 assert(
N == 1 &&
"Invalid number of operands!");
2138 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2139 assert(
N == 1 &&
"Invalid number of operands!");
2144 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2145 assert(
N == 1 &&
"Invalid number of operands!");
2150 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2151 assert(
N == 1 &&
"Invalid number of operands!");
2155 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2156 assert(
N == 1 &&
"Invalid number of operands!");
2160 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2161 assert(
N == 1 &&
"Invalid number of operands!");
2165 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2166 assert(
N == 1 &&
"Invalid number of operands!");
2172 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2173 assert(
N == 1 &&
"Invalid number of operands!");
2174 unsigned Imm = getShiftExtendAmount();
2178 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2179 assert(
N == 1 &&
"Invalid number of operands!");
2184 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2187 if (
Reg != AArch64::XZR)
2193 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2194 assert(
N == 1 &&
"Invalid number of operands!");
2201 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2202 assert(
N == 1 &&
"Invalid number of operands!");
2209 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2210 assert(
N == 2 &&
"Invalid number of operands!");
2221 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2222 assert(
N == 2 &&
"Invalid number of operands!");
2230 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2231 assert(
N == 1 &&
"Invalid number of operands!");
2243 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2244 assert(
N == 1 &&
"Invalid number of operands!");
2251 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2252 assert(
N == 1 &&
"Invalid number of operands!");
2257 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2258 assert(
N == 1 &&
"Invalid number of operands!");
2263 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2265 static std::unique_ptr<AArch64Operand>
2266 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2267 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2268 Op->Tok.Data = Str.data();
2269 Op->Tok.Length = Str.size();
2270 Op->Tok.IsSuffix = IsSuffix;
2276 static std::unique_ptr<AArch64Operand>
2277 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2278 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2280 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2281 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2283 Op->Reg.Kind = Kind;
2284 Op->Reg.ElementWidth = 0;
2285 Op->Reg.EqualityTy = EqTy;
2286 Op->Reg.ShiftExtend.Type = ExtTy;
2287 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2288 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2294 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2295 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2297 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2298 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2299 Kind == RegKind::SVEPredicateVector ||
2300 Kind == RegKind::SVEPredicateAsCounter) &&
2301 "Invalid vector kind");
2302 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2304 Op->Reg.ElementWidth = ElementWidth;
2308 static std::unique_ptr<AArch64Operand>
2309 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2310 unsigned NumElements,
unsigned ElementWidth,
2311 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2312 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2313 Op->VectorList.Reg =
Reg;
2315 Op->VectorList.Stride = Stride;
2316 Op->VectorList.NumElements = NumElements;
2317 Op->VectorList.ElementWidth = ElementWidth;
2318 Op->VectorList.RegisterKind = RegisterKind;
2324 static std::unique_ptr<AArch64Operand>
2325 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2326 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2327 Op->VectorIndex.Val = Idx;
2333 static std::unique_ptr<AArch64Operand>
2334 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2335 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2336 Op->MatrixTileList.RegMask = RegMask;
2342 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2343 const unsigned ElementWidth) {
2344 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2346 {{0, AArch64::ZAB0},
2347 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2348 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2349 {{8, AArch64::ZAB0},
2350 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2351 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2352 {{16, AArch64::ZAH0},
2353 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2354 {{16, AArch64::ZAH1},
2355 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2356 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2357 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2358 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2359 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2362 if (ElementWidth == 64)
2365 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2366 assert(!Regs.empty() &&
"Invalid tile or element width!");
2371 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2372 SMLoc
E, MCContext &Ctx) {
2373 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2380 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2381 unsigned ShiftAmount,
2384 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2385 Op->ShiftedImm .Val = Val;
2386 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2392 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2393 unsigned Last, SMLoc S,
2396 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2398 Op->ImmRange.Last =
Last;
2403 static std::unique_ptr<AArch64Operand>
2405 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2406 Op->CondCode.Code =
Code;
2412 static std::unique_ptr<AArch64Operand>
2413 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2414 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2416 Op->FPImm.IsExact = IsExact;
2422 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2426 bool HasnXSModifier) {
2427 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2428 Op->Barrier.Val = Val;
2429 Op->Barrier.Data = Str.data();
2430 Op->Barrier.Length = Str.size();
2431 Op->Barrier.HasnXSModifier = HasnXSModifier;
2437 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2440 uint32_t PStateField,
2442 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2443 Op->SysReg.Data = Str.data();
2444 Op->SysReg.Length = Str.size();
2445 Op->SysReg.MRSReg = MRSReg;
2446 Op->SysReg.MSRReg = MSRReg;
2447 Op->SysReg.PStateField = PStateField;
2453 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2454 SMLoc
E, MCContext &Ctx) {
2455 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2456 Op->SysCRImm.Val = Val;
2462 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2466 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2467 Op->Prefetch.Val = Val;
2468 Op->Barrier.Data = Str.data();
2469 Op->Barrier.Length = Str.size();
2475 static std::unique_ptr<AArch64Operand>
2476 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2477 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2478 Op->TIndexHint.Val = Val;
2479 Op->TIndexHint.Data = Str.data();
2480 Op->TIndexHint.Length = Str.size();
2486 static std::unique_ptr<AArch64Operand>
2487 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2488 SMLoc S, SMLoc
E, MCContext &Ctx) {
2489 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2490 Op->MatrixReg.Reg =
Reg;
2491 Op->MatrixReg.ElementWidth = ElementWidth;
2492 Op->MatrixReg.Kind = Kind;
2498 static std::unique_ptr<AArch64Operand>
2499 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2500 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2501 Op->SVCR.PStateField = PStateField;
2502 Op->SVCR.Data = Str.data();
2503 Op->SVCR.Length = Str.size();
2509 static std::unique_ptr<AArch64Operand>
2511 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2512 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2513 Op->ShiftExtend.Type = ShOp;
2514 Op->ShiftExtend.Amount = Val;
2515 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2527 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2528 if (!getFPImmIsExact())
2533 StringRef
Name = getBarrierName();
2535 OS <<
"<barrier " <<
Name <<
">";
2537 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2543 case k_ShiftedImm: {
2544 unsigned Shift = getShiftedImmShift();
2545 OS <<
"<shiftedimm ";
2552 OS << getFirstImmVal();
2553 OS <<
":" << getLastImmVal() <<
">";
2559 case k_VectorList: {
2560 OS <<
"<vectorlist ";
2561 MCRegister
Reg = getVectorListStart();
2562 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2563 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2568 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2571 OS <<
"<sysreg: " << getSysReg() <<
'>';
2577 OS <<
"c" << getSysCR();
2580 StringRef
Name = getPrefetchName();
2582 OS <<
"<prfop " <<
Name <<
">";
2584 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2588 OS << getTIndexHintName();
2590 case k_MatrixRegister:
2591 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2593 case k_MatrixTileList: {
2594 OS <<
"<matrixlist ";
2595 unsigned RegMask = getMatrixTileListRegMask();
2596 unsigned MaxBits = 8;
2597 for (
unsigned I = MaxBits;
I > 0; --
I)
2598 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2607 OS <<
"<register " <<
getReg().
id() <<
">";
2608 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2613 << getShiftExtendAmount();
2614 if (!hasShiftExtendAmount())
2630 .
Case(
"v0", AArch64::Q0)
2631 .
Case(
"v1", AArch64::Q1)
2632 .
Case(
"v2", AArch64::Q2)
2633 .
Case(
"v3", AArch64::Q3)
2634 .
Case(
"v4", AArch64::Q4)
2635 .
Case(
"v5", AArch64::Q5)
2636 .
Case(
"v6", AArch64::Q6)
2637 .
Case(
"v7", AArch64::Q7)
2638 .
Case(
"v8", AArch64::Q8)
2639 .
Case(
"v9", AArch64::Q9)
2640 .
Case(
"v10", AArch64::Q10)
2641 .
Case(
"v11", AArch64::Q11)
2642 .
Case(
"v12", AArch64::Q12)
2643 .
Case(
"v13", AArch64::Q13)
2644 .
Case(
"v14", AArch64::Q14)
2645 .
Case(
"v15", AArch64::Q15)
2646 .
Case(
"v16", AArch64::Q16)
2647 .
Case(
"v17", AArch64::Q17)
2648 .
Case(
"v18", AArch64::Q18)
2649 .
Case(
"v19", AArch64::Q19)
2650 .
Case(
"v20", AArch64::Q20)
2651 .
Case(
"v21", AArch64::Q21)
2652 .
Case(
"v22", AArch64::Q22)
2653 .
Case(
"v23", AArch64::Q23)
2654 .
Case(
"v24", AArch64::Q24)
2655 .
Case(
"v25", AArch64::Q25)
2656 .
Case(
"v26", AArch64::Q26)
2657 .
Case(
"v27", AArch64::Q27)
2658 .
Case(
"v28", AArch64::Q28)
2659 .
Case(
"v29", AArch64::Q29)
2660 .
Case(
"v30", AArch64::Q30)
2661 .
Case(
"v31", AArch64::Q31)
2670 RegKind VectorKind) {
2671 std::pair<int, int> Res = {-1, -1};
2673 switch (VectorKind) {
2674 case RegKind::NeonVector:
2677 .Case(
".1d", {1, 64})
2678 .Case(
".1q", {1, 128})
2680 .Case(
".2h", {2, 16})
2681 .Case(
".2b", {2, 8})
2682 .Case(
".2s", {2, 32})
2683 .Case(
".2d", {2, 64})
2686 .Case(
".4b", {4, 8})
2687 .Case(
".4h", {4, 16})
2688 .Case(
".4s", {4, 32})
2689 .Case(
".8b", {8, 8})
2690 .Case(
".8h", {8, 16})
2691 .Case(
".16b", {16, 8})
2696 .Case(
".h", {0, 16})
2697 .Case(
".s", {0, 32})
2698 .Case(
".d", {0, 64})
2701 case RegKind::SVEPredicateAsCounter:
2702 case RegKind::SVEPredicateVector:
2703 case RegKind::SVEDataVector:
2704 case RegKind::Matrix:
2708 .Case(
".h", {0, 16})
2709 .Case(
".s", {0, 32})
2710 .Case(
".d", {0, 64})
2711 .Case(
".q", {0, 128})
2718 if (Res == std::make_pair(-1, -1))
2719 return std::nullopt;
2721 return std::optional<std::pair<int, int>>(Res);
2730 .
Case(
"z0", AArch64::Z0)
2731 .
Case(
"z1", AArch64::Z1)
2732 .
Case(
"z2", AArch64::Z2)
2733 .
Case(
"z3", AArch64::Z3)
2734 .
Case(
"z4", AArch64::Z4)
2735 .
Case(
"z5", AArch64::Z5)
2736 .
Case(
"z6", AArch64::Z6)
2737 .
Case(
"z7", AArch64::Z7)
2738 .
Case(
"z8", AArch64::Z8)
2739 .
Case(
"z9", AArch64::Z9)
2740 .
Case(
"z10", AArch64::Z10)
2741 .
Case(
"z11", AArch64::Z11)
2742 .
Case(
"z12", AArch64::Z12)
2743 .
Case(
"z13", AArch64::Z13)
2744 .
Case(
"z14", AArch64::Z14)
2745 .
Case(
"z15", AArch64::Z15)
2746 .
Case(
"z16", AArch64::Z16)
2747 .
Case(
"z17", AArch64::Z17)
2748 .
Case(
"z18", AArch64::Z18)
2749 .
Case(
"z19", AArch64::Z19)
2750 .
Case(
"z20", AArch64::Z20)
2751 .
Case(
"z21", AArch64::Z21)
2752 .
Case(
"z22", AArch64::Z22)
2753 .
Case(
"z23", AArch64::Z23)
2754 .
Case(
"z24", AArch64::Z24)
2755 .
Case(
"z25", AArch64::Z25)
2756 .
Case(
"z26", AArch64::Z26)
2757 .
Case(
"z27", AArch64::Z27)
2758 .
Case(
"z28", AArch64::Z28)
2759 .
Case(
"z29", AArch64::Z29)
2760 .
Case(
"z30", AArch64::Z30)
2761 .
Case(
"z31", AArch64::Z31)
2767 .
Case(
"p0", AArch64::P0)
2768 .
Case(
"p1", AArch64::P1)
2769 .
Case(
"p2", AArch64::P2)
2770 .
Case(
"p3", AArch64::P3)
2771 .
Case(
"p4", AArch64::P4)
2772 .
Case(
"p5", AArch64::P5)
2773 .
Case(
"p6", AArch64::P6)
2774 .
Case(
"p7", AArch64::P7)
2775 .
Case(
"p8", AArch64::P8)
2776 .
Case(
"p9", AArch64::P9)
2777 .
Case(
"p10", AArch64::P10)
2778 .
Case(
"p11", AArch64::P11)
2779 .
Case(
"p12", AArch64::P12)
2780 .
Case(
"p13", AArch64::P13)
2781 .
Case(
"p14", AArch64::P14)
2782 .
Case(
"p15", AArch64::P15)
2788 .
Case(
"pn0", AArch64::PN0)
2789 .
Case(
"pn1", AArch64::PN1)
2790 .
Case(
"pn2", AArch64::PN2)
2791 .
Case(
"pn3", AArch64::PN3)
2792 .
Case(
"pn4", AArch64::PN4)
2793 .
Case(
"pn5", AArch64::PN5)
2794 .
Case(
"pn6", AArch64::PN6)
2795 .
Case(
"pn7", AArch64::PN7)
2796 .
Case(
"pn8", AArch64::PN8)
2797 .
Case(
"pn9", AArch64::PN9)
2798 .
Case(
"pn10", AArch64::PN10)
2799 .
Case(
"pn11", AArch64::PN11)
2800 .
Case(
"pn12", AArch64::PN12)
2801 .
Case(
"pn13", AArch64::PN13)
2802 .
Case(
"pn14", AArch64::PN14)
2803 .
Case(
"pn15", AArch64::PN15)
2809 .
Case(
"za0.d", AArch64::ZAD0)
2810 .
Case(
"za1.d", AArch64::ZAD1)
2811 .
Case(
"za2.d", AArch64::ZAD2)
2812 .
Case(
"za3.d", AArch64::ZAD3)
2813 .
Case(
"za4.d", AArch64::ZAD4)
2814 .
Case(
"za5.d", AArch64::ZAD5)
2815 .
Case(
"za6.d", AArch64::ZAD6)
2816 .
Case(
"za7.d", AArch64::ZAD7)
2817 .
Case(
"za0.s", AArch64::ZAS0)
2818 .
Case(
"za1.s", AArch64::ZAS1)
2819 .
Case(
"za2.s", AArch64::ZAS2)
2820 .
Case(
"za3.s", AArch64::ZAS3)
2821 .
Case(
"za0.h", AArch64::ZAH0)
2822 .
Case(
"za1.h", AArch64::ZAH1)
2823 .
Case(
"za0.b", AArch64::ZAB0)
2829 .
Case(
"za", AArch64::ZA)
2830 .
Case(
"za0.q", AArch64::ZAQ0)
2831 .
Case(
"za1.q", AArch64::ZAQ1)
2832 .
Case(
"za2.q", AArch64::ZAQ2)
2833 .
Case(
"za3.q", AArch64::ZAQ3)
2834 .
Case(
"za4.q", AArch64::ZAQ4)
2835 .
Case(
"za5.q", AArch64::ZAQ5)
2836 .
Case(
"za6.q", AArch64::ZAQ6)
2837 .
Case(
"za7.q", AArch64::ZAQ7)
2838 .
Case(
"za8.q", AArch64::ZAQ8)
2839 .
Case(
"za9.q", AArch64::ZAQ9)
2840 .
Case(
"za10.q", AArch64::ZAQ10)
2841 .
Case(
"za11.q", AArch64::ZAQ11)
2842 .
Case(
"za12.q", AArch64::ZAQ12)
2843 .
Case(
"za13.q", AArch64::ZAQ13)
2844 .
Case(
"za14.q", AArch64::ZAQ14)
2845 .
Case(
"za15.q", AArch64::ZAQ15)
2846 .
Case(
"za0.d", AArch64::ZAD0)
2847 .
Case(
"za1.d", AArch64::ZAD1)
2848 .
Case(
"za2.d", AArch64::ZAD2)
2849 .
Case(
"za3.d", AArch64::ZAD3)
2850 .
Case(
"za4.d", AArch64::ZAD4)
2851 .
Case(
"za5.d", AArch64::ZAD5)
2852 .
Case(
"za6.d", AArch64::ZAD6)
2853 .
Case(
"za7.d", AArch64::ZAD7)
2854 .
Case(
"za0.s", AArch64::ZAS0)
2855 .
Case(
"za1.s", AArch64::ZAS1)
2856 .
Case(
"za2.s", AArch64::ZAS2)
2857 .
Case(
"za3.s", AArch64::ZAS3)
2858 .
Case(
"za0.h", AArch64::ZAH0)
2859 .
Case(
"za1.h", AArch64::ZAH1)
2860 .
Case(
"za0.b", AArch64::ZAB0)
2861 .
Case(
"za0h.q", AArch64::ZAQ0)
2862 .
Case(
"za1h.q", AArch64::ZAQ1)
2863 .
Case(
"za2h.q", AArch64::ZAQ2)
2864 .
Case(
"za3h.q", AArch64::ZAQ3)
2865 .
Case(
"za4h.q", AArch64::ZAQ4)
2866 .
Case(
"za5h.q", AArch64::ZAQ5)
2867 .
Case(
"za6h.q", AArch64::ZAQ6)
2868 .
Case(
"za7h.q", AArch64::ZAQ7)
2869 .
Case(
"za8h.q", AArch64::ZAQ8)
2870 .
Case(
"za9h.q", AArch64::ZAQ9)
2871 .
Case(
"za10h.q", AArch64::ZAQ10)
2872 .
Case(
"za11h.q", AArch64::ZAQ11)
2873 .
Case(
"za12h.q", AArch64::ZAQ12)
2874 .
Case(
"za13h.q", AArch64::ZAQ13)
2875 .
Case(
"za14h.q", AArch64::ZAQ14)
2876 .
Case(
"za15h.q", AArch64::ZAQ15)
2877 .
Case(
"za0h.d", AArch64::ZAD0)
2878 .
Case(
"za1h.d", AArch64::ZAD1)
2879 .
Case(
"za2h.d", AArch64::ZAD2)
2880 .
Case(
"za3h.d", AArch64::ZAD3)
2881 .
Case(
"za4h.d", AArch64::ZAD4)
2882 .
Case(
"za5h.d", AArch64::ZAD5)
2883 .
Case(
"za6h.d", AArch64::ZAD6)
2884 .
Case(
"za7h.d", AArch64::ZAD7)
2885 .
Case(
"za0h.s", AArch64::ZAS0)
2886 .
Case(
"za1h.s", AArch64::ZAS1)
2887 .
Case(
"za2h.s", AArch64::ZAS2)
2888 .
Case(
"za3h.s", AArch64::ZAS3)
2889 .
Case(
"za0h.h", AArch64::ZAH0)
2890 .
Case(
"za1h.h", AArch64::ZAH1)
2891 .
Case(
"za0h.b", AArch64::ZAB0)
2892 .
Case(
"za0v.q", AArch64::ZAQ0)
2893 .
Case(
"za1v.q", AArch64::ZAQ1)
2894 .
Case(
"za2v.q", AArch64::ZAQ2)
2895 .
Case(
"za3v.q", AArch64::ZAQ3)
2896 .
Case(
"za4v.q", AArch64::ZAQ4)
2897 .
Case(
"za5v.q", AArch64::ZAQ5)
2898 .
Case(
"za6v.q", AArch64::ZAQ6)
2899 .
Case(
"za7v.q", AArch64::ZAQ7)
2900 .
Case(
"za8v.q", AArch64::ZAQ8)
2901 .
Case(
"za9v.q", AArch64::ZAQ9)
2902 .
Case(
"za10v.q", AArch64::ZAQ10)
2903 .
Case(
"za11v.q", AArch64::ZAQ11)
2904 .
Case(
"za12v.q", AArch64::ZAQ12)
2905 .
Case(
"za13v.q", AArch64::ZAQ13)
2906 .
Case(
"za14v.q", AArch64::ZAQ14)
2907 .
Case(
"za15v.q", AArch64::ZAQ15)
2908 .
Case(
"za0v.d", AArch64::ZAD0)
2909 .
Case(
"za1v.d", AArch64::ZAD1)
2910 .
Case(
"za2v.d", AArch64::ZAD2)
2911 .
Case(
"za3v.d", AArch64::ZAD3)
2912 .
Case(
"za4v.d", AArch64::ZAD4)
2913 .
Case(
"za5v.d", AArch64::ZAD5)
2914 .
Case(
"za6v.d", AArch64::ZAD6)
2915 .
Case(
"za7v.d", AArch64::ZAD7)
2916 .
Case(
"za0v.s", AArch64::ZAS0)
2917 .
Case(
"za1v.s", AArch64::ZAS1)
2918 .
Case(
"za2v.s", AArch64::ZAS2)
2919 .
Case(
"za3v.s", AArch64::ZAS3)
2920 .
Case(
"za0v.h", AArch64::ZAH0)
2921 .
Case(
"za1v.h", AArch64::ZAH1)
2922 .
Case(
"za0v.b", AArch64::ZAB0)
2926bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2928 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2931ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2933 StartLoc = getLoc();
2934 ParseStatus Res = tryParseScalarRegister(
Reg);
2940MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2942 MCRegister
Reg = MCRegister();
2944 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2947 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2950 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2953 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2956 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2958 if (
Name.equals_insensitive(
"zt0"))
2959 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2963 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2967 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2968 .Case(
"fp", AArch64::FP)
2969 .Case(
"lr", AArch64::LR)
2970 .Case(
"x31", AArch64::XZR)
2971 .Case(
"w31", AArch64::WZR)
2973 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2979 if (Entry == RegisterReqs.
end())
2980 return MCRegister();
2983 if (Kind ==
Entry->getValue().first)
2989unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2991 case RegKind::Scalar:
2992 case RegKind::NeonVector:
2993 case RegKind::SVEDataVector:
2995 case RegKind::Matrix:
2996 case RegKind::SVEPredicateVector:
2997 case RegKind::SVEPredicateAsCounter:
2999 case RegKind::LookupTable:
3008ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3009 const AsmToken &Tok = getTok();
3014 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3028 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3031 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3032 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3036 if (BadNum || CRNum > 15)
3037 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3041 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3048 const AsmToken &Tok = getTok();
3050 unsigned MaxVal = 63;
3055 const MCExpr *ImmVal;
3056 if (getParser().parseExpression(ImmVal))
3061 return TokError(
"immediate value expected for prefetch operand");
3064 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3067 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3068 Operands.push_back(AArch64Operand::CreatePrefetch(
3069 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3075 return TokError(
"prefetch hint expected");
3077 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3079 return TokError(
"prefetch hint expected");
3081 Operands.push_back(AArch64Operand::CreatePrefetch(
3088template <
bool IsSVEPrefetch>
3091 const AsmToken &Tok = getTok();
3093 auto LookupByName = [](StringRef
N) {
3094 if (IsSVEPrefetch) {
3095 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3096 return std::optional<unsigned>(Res->Encoding);
3097 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3098 return std::optional<unsigned>(Res->Encoding);
3099 return std::optional<unsigned>();
3102 auto LookupByEncoding = [](
unsigned E) {
3103 if (IsSVEPrefetch) {
3104 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3105 return std::optional<StringRef>(
3106 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3107 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3108 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3109 return std::optional<StringRef>();
3111 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3117 const MCExpr *ImmVal;
3118 if (getParser().parseExpression(ImmVal))
3123 return TokError(
"immediate value expected for prefetch operand");
3126 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3129 auto PRFM = LookupByEncoding(MCE->
getValue());
3130 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3136 return TokError(
"prefetch hint expected");
3138 auto PRFM = LookupByName(Tok.
getString());
3140 return TokError(
"prefetch hint expected");
3142 Operands.push_back(AArch64Operand::CreatePrefetch(
3149 SMLoc StartLoc = getLoc();
3155 auto RegTok = getTok();
3156 if (!tryParseScalarRegister(RegNum).isSuccess())
3159 if (RegNum != AArch64::XZR) {
3160 getLexer().UnLex(RegTok);
3167 if (!tryParseScalarRegister(RegNum).isSuccess())
3168 return TokError(
"expected register operand");
3170 if (RegNum != AArch64::XZR)
3171 return TokError(
"xzr must be followed by xzr");
3175 Operands.push_back(AArch64Operand::CreateReg(
3176 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3184 const AsmToken &Tok = getTok();
3186 return TokError(
"invalid operand for instruction");
3188 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3190 return TokError(
"invalid operand for instruction");
3192 Operands.push_back(AArch64Operand::CreateTIndexHint(
3202 const MCExpr *Expr =
nullptr;
3208 if (parseSymbolicImmVal(Expr))
3214 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3223 return Error(S,
"gotpage label reference not allowed an addend");
3235 return Error(S,
"page or gotpage label reference expected");
3252 const MCExpr *Expr =
nullptr;
3261 if (parseSymbolicImmVal(Expr))
3267 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3279 return Error(S,
"unexpected adr label");
3289template <
bool AddFPZeroAsLiteral>
3298 const AsmToken &Tok = getTok();
3302 return TokError(
"invalid floating point immediate");
3307 if (Tok.
getIntVal() > 255 || isNegative)
3308 return TokError(
"encoded floating point value out of range");
3312 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3315 APFloat RealVal(APFloat::IEEEdouble());
3317 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3319 return TokError(
"invalid floating point representation");
3322 RealVal.changeSign();
3324 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3328 Operands.push_back(AArch64Operand::CreateFPImm(
3329 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3353 const MCExpr *
Imm =
nullptr;
3354 if (parseSymbolicImmVal(
Imm))
3365 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3369 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3375 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3376 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3384 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3386 int64_t ShiftAmount = getTok().getIntVal();
3388 if (ShiftAmount < 0)
3389 return Error(getLoc(),
"positive shift amount required");
3393 if (ShiftAmount == 0 &&
Imm !=
nullptr) {
3399 Operands.push_back(AArch64Operand::CreateShiftedImm(
Imm, ShiftAmount, S,
3407AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3441 Suggestion =
"nfrst";
3448 bool invertCondCode) {
3450 const AsmToken &Tok = getTok();
3454 std::string Suggestion;
3457 std::string
Msg =
"invalid condition code";
3458 if (!Suggestion.empty())
3459 Msg +=
", did you mean " + Suggestion +
"?";
3460 return TokError(
Msg);
3464 if (invertCondCode) {
3466 return TokError(
"condition codes AL and NV are invalid for this instruction");
3471 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3476 const AsmToken &Tok = getTok();
3480 return TokError(
"invalid operand for instruction");
3482 unsigned PStateImm = -1;
3483 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3486 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3487 PStateImm = SVCR->Encoding;
3496 const AsmToken &Tok = getTok();
3501 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3503 unsigned ElementWidth = 0;
3504 auto DotPosition =
Name.find(
'.');
3506 const auto &KindRes =
3510 "Expected the register to be followed by element width suffix");
3511 ElementWidth = KindRes->second;
3513 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3514 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3519 if (parseOperand(
Operands,
false,
false))
3526 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3530 size_t DotPosition =
Name.find(
'.');
3533 StringRef Head =
Name.take_front(DotPosition);
3534 StringRef
Tail =
Name.drop_front(DotPosition);
3535 StringRef RowOrColumn = Head.
take_back();
3537 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3538 .Case(
"h", MatrixKind::Row)
3539 .Case(
"v", MatrixKind::Col)
3540 .Default(MatrixKind::Tile);
3546 "Expected the register to be followed by element width suffix");
3547 unsigned ElementWidth = KindRes->second;
3551 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3557 if (parseOperand(
Operands,
false,
false))
3567 const AsmToken &Tok = getTok();
3570 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3599 return TokError(
"expected #imm after shift specifier");
3605 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3614 return Error(
E,
"expected integer shift amount");
3616 const MCExpr *ImmVal;
3617 if (getParser().parseExpression(ImmVal))
3622 return Error(
E,
"expected constant '#imm' after shift specifier");
3625 Operands.push_back(AArch64Operand::CreateShiftExtend(
3631 {{
"crc"}, {AArch64::FeatureCRC}},
3632 {{
"sm4"}, {AArch64::FeatureSM4}},
3633 {{
"sha3"}, {AArch64::FeatureSHA3}},
3634 {{
"sha2"}, {AArch64::FeatureSHA2}},
3635 {{
"aes"}, {AArch64::FeatureAES}},
3636 {{
"crypto"}, {AArch64::FeatureCrypto}},
3637 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3638 {{
"simd"}, {AArch64::FeatureNEON}},
3639 {{
"ras"}, {AArch64::FeatureRAS}},
3640 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3641 {{
"lse"}, {AArch64::FeatureLSE}},
3642 {{
"predres"}, {AArch64::FeaturePredRes}},
3643 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3644 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3645 {{
"mte"}, {AArch64::FeatureMTE}},
3646 {{
"memtag"}, {AArch64::FeatureMTE}},
3647 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3648 {{
"pan"}, {AArch64::FeaturePAN}},
3649 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3650 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3651 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3652 {{
"rng"}, {AArch64::FeatureRandGen}},
3653 {{
"sve"}, {AArch64::FeatureSVE}},
3654 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3655 {{
"sve2"}, {AArch64::FeatureSVE2}},
3656 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3657 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3658 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3659 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3660 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3661 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3662 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3664 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3665 AArch64::FeatureSVE2}},
3666 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3667 {{
"ls64"}, {AArch64::FeatureLS64}},
3668 {{
"xs"}, {AArch64::FeatureXS}},
3669 {{
"pauth"}, {AArch64::FeaturePAuth}},
3670 {{
"flagm"}, {AArch64::FeatureFlagM}},
3671 {{
"rme"}, {AArch64::FeatureRME}},
3672 {{
"sme"}, {AArch64::FeatureSME}},
3673 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3674 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3675 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3676 {{
"sme2"}, {AArch64::FeatureSME2}},
3677 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3678 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3679 {{
"hbc"}, {AArch64::FeatureHBC}},
3680 {{
"mops"}, {AArch64::FeatureMOPS}},
3681 {{
"mec"}, {AArch64::FeatureMEC}},
3682 {{
"the"}, {AArch64::FeatureTHE}},
3683 {{
"d128"}, {AArch64::FeatureD128}},
3684 {{
"lse128"}, {AArch64::FeatureLSE128}},
3685 {{
"ite"}, {AArch64::FeatureITE}},
3686 {{
"cssc"}, {AArch64::FeatureCSSC}},
3687 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3688 {{
"gcs"}, {AArch64::FeatureGCS}},
3689 {{
"bf16"}, {AArch64::FeatureBF16}},
3690 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3691 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3692 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3693 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3694 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3695 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3696 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3697 {{
"lor"}, {AArch64::FeatureLOR}},
3698 {{
"profile"}, {AArch64::FeatureSPE}},
3702 {{
"rdm"}, {AArch64::FeatureRDM}},
3703 {{
"rdma"}, {AArch64::FeatureRDM}},
3704 {{
"sb"}, {AArch64::FeatureSB}},
3705 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3706 {{
"fp8"}, {AArch64::FeatureFP8}},
3707 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3708 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3709 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3710 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3711 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3712 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3713 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3714 {{
"lut"}, {AArch64::FeatureLUT}},
3715 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3716 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3717 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3718 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3719 {{
"cpa"}, {AArch64::FeatureCPA}},
3720 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3721 {{
"pops"}, {AArch64::FeaturePoPS}},
3722 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3723 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3724 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3725 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3726 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3727 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3728 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3729 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3730 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3731 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3732 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3733 {{
"lsui"}, {AArch64::FeatureLSUI}},
3734 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3735 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3736 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3737 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3738 {{
"lscp"}, {AArch64::FeatureLSCP}},
3739 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3740 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3741 {{
"gcie"}, {AArch64::FeatureGCIE}},
3742 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3743 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3744 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3745 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3746 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3747 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3748 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3749 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3750 {{
"tev"}, {AArch64::FeatureTEV}},
3751 {{
"btie"}, {AArch64::FeatureBTIE}},
3752 {{
"hinte"}, {AArch64::FeatureHINTE}},
3753 {{
"dit"}, {AArch64::FeatureDIT}},
3754 {{
"brbe"}, {AArch64::FeatureBRBE}},
3755 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3756 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3757 {{
"jscvt"}, {AArch64::FeatureJS}},
3758 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3759 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3760 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3765 if (FBS[AArch64::HasV8_0aOps])
3767 if (FBS[AArch64::HasV8_1aOps])
3769 else if (FBS[AArch64::HasV8_2aOps])
3771 else if (FBS[AArch64::HasV8_3aOps])
3773 else if (FBS[AArch64::HasV8_4aOps])
3775 else if (FBS[AArch64::HasV8_5aOps])
3777 else if (FBS[AArch64::HasV8_6aOps])
3779 else if (FBS[AArch64::HasV8_7aOps])
3781 else if (FBS[AArch64::HasV8_8aOps])
3783 else if (FBS[AArch64::HasV8_9aOps])
3785 else if (FBS[AArch64::HasV9_0aOps])
3787 else if (FBS[AArch64::HasV9_1aOps])
3789 else if (FBS[AArch64::HasV9_2aOps])
3791 else if (FBS[AArch64::HasV9_3aOps])
3793 else if (FBS[AArch64::HasV9_4aOps])
3795 else if (FBS[AArch64::HasV9_5aOps])
3797 else if (FBS[AArch64::HasV9_6aOps])
3799 else if (FBS[AArch64::HasV9_7aOps])
3801 else if (FBS[AArch64::HasV8_0rOps])
3810 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3816 const uint16_t Op2 = Encoding & 7;
3817 const uint16_t Cm = (Encoding & 0x78) >> 3;
3818 const uint16_t Cn = (Encoding & 0x780) >> 7;
3819 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3824 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3826 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3828 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3831 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3837bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3839 if (
Name.contains(
'.'))
3840 return TokError(
"invalid operand");
3845 const AsmToken &Tok = getTok();
3848 bool ExpectRegister =
true;
3849 bool OptionalRegister =
false;
3850 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3851 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3853 if (Mnemonic ==
"ic") {
3854 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3856 return TokError(
"invalid operand for IC instruction");
3857 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3858 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3861 return TokError(Str);
3865 }
else if (Mnemonic ==
"dc") {
3866 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3868 return TokError(
"invalid operand for DC instruction");
3869 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3870 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3873 return TokError(Str);
3876 }
else if (Mnemonic ==
"at") {
3877 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3879 return TokError(
"invalid operand for AT instruction");
3880 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3881 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3884 return TokError(Str);
3887 }
else if (Mnemonic ==
"tlbi") {
3888 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3890 return TokError(
"invalid operand for TLBI instruction");
3891 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3892 std::string Str(
"TLBI " +
3893 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3896 return TokError(Str);
3898 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3899 if (hasAll || hasTLBID)
3900 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3902 }
else if (Mnemonic ==
"gic") {
3903 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3905 return TokError(
"invalid operand for GIC instruction");
3906 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3907 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3910 return TokError(Str);
3914 }
else if (Mnemonic ==
"gsb") {
3915 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3917 return TokError(
"invalid operand for GSB instruction");
3918 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3919 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3922 return TokError(Str);
3924 ExpectRegister =
false;
3926 }
else if (Mnemonic ==
"plbi") {
3927 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3929 return TokError(
"invalid operand for PLBI instruction");
3930 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3931 std::string Str(
"PLBI " +
3932 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3935 return TokError(Str);
3937 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3938 if (hasAll || hasTLBID)
3939 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3941 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3942 Mnemonic ==
"cosp") {
3944 if (
Op.lower() !=
"rctx")
3945 return TokError(
"invalid operand for prediction restriction instruction");
3947 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3948 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3950 if (Mnemonic ==
"cosp" && !hasSpecres2)
3951 return TokError(
"COSP requires: predres2");
3953 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3955 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3956 : Mnemonic ==
"dvp" ? 0b101
3957 : Mnemonic ==
"cosp" ? 0b110
3958 : Mnemonic ==
"cpp" ? 0b111
3961 "Invalid mnemonic for prediction restriction instruction");
3962 const auto SYS_3_7_3 = 0b01101110011;
3963 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3965 createSysAlias(Encoding,
Operands, S);
3970 bool HasRegister =
false;
3975 return TokError(
"expected register operand");
3979 if (!OptionalRegister) {
3980 if (ExpectRegister && !HasRegister)
3981 return TokError(
"specified " + Mnemonic +
" op requires a register");
3982 else if (!ExpectRegister && HasRegister)
3983 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3995bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4000 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4003 SMLoc startLoc = getLoc();
4004 const AsmToken ®Tok = getTok();
4006 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4008 return TokError(
"expected register operand");
4010 Operands.push_back(AArch64Operand::CreateReg(
4011 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4018 const AsmToken &operandTok = getTok();
4020 SMLoc S2 = operandTok.
getLoc();
4023 if (Mnemonic ==
"gicr") {
4024 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4026 return Error(S2,
"invalid operand for GICR instruction");
4027 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4028 std::string Str(
"GICR " +
4029 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4032 return Error(S2, Str);
4045bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4047 if (
Name.contains(
'.'))
4048 return TokError(
"invalid operand");
4052 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4054 const AsmToken &Tok = getTok();
4058 if (Mnemonic ==
"tlbip") {
4059 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4061 return TokError(
"invalid operand for TLBIP instruction");
4064 std::string Str(
"instruction requires: ");
4066 return TokError(Str);
4077 return TokError(
"expected register identifier");
4082 return TokError(
"specified " + Mnemonic +
4083 " op requires a pair of registers");
4092 MCAsmParser &Parser = getParser();
4093 const AsmToken &Tok = getTok();
4097 const MCExpr *ImmVal;
4098 SMLoc ExprLoc = getLoc();
4099 AsmToken IntTok = Tok;
4100 if (getParser().parseExpression(ImmVal))
4104 return Error(ExprLoc,
"immediate value expected for barrier operand");
4106 if (Mnemonic ==
"dsb" &&
Value > 15) {
4114 return Error(ExprLoc,
"barrier operand out of range");
4115 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4116 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4117 Operands.push_back(AArch64Operand::CreateBarrier(
4123 return TokError(
"invalid operand for instruction");
4126 auto DB = AArch64DB::lookupDBByName(Operand);
4128 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4129 return TokError(
"'sy' or #imm operand expected");
4131 if (Mnemonic ==
"dsb") {
4136 return TokError(
"invalid barrier option name");
4140 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4149 const AsmToken &Tok = getTok();
4151 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4152 if (Mnemonic !=
"dsb")
4157 const MCExpr *ImmVal;
4158 SMLoc ExprLoc = getLoc();
4159 if (getParser().parseExpression(ImmVal))
4163 return Error(ExprLoc,
"immediate value expected for barrier operand");
4168 return Error(ExprLoc,
"barrier operand out of range");
4169 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4170 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4171 Operands.push_back(AArch64Operand::CreateBarrier(
4177 return TokError(
"invalid operand for instruction");
4180 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4183 return TokError(
"invalid barrier option name");
4186 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4194 const AsmToken &Tok = getTok();
4199 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4203 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4204 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4205 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4206 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4210 unsigned PStateImm = -1;
4211 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4212 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4213 PStateImm = PState15->Encoding;
4215 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4216 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4217 PStateImm = PState1->Encoding;
4221 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4237 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4245 unsigned ElementWidth = KindRes->second;
4247 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4255 return tryParseVectorIndex(
Operands).isFailure();
4259 SMLoc SIdx = getLoc();
4261 const MCExpr *ImmVal;
4262 if (getParser().parseExpression(ImmVal))
4266 return TokError(
"immediate value expected for vector index");
4273 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4284ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4286 RegKind MatchKind) {
4287 const AsmToken &Tok = getTok();
4296 StringRef Head =
Name.slice(Start,
Next);
4297 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4303 return TokError(
"invalid vector kind qualifier");
4314ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4316 ParseStatus Status =
4317 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4319 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4324template <RegKind RK>
4328 const SMLoc S = getLoc();
4331 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4339 unsigned ElementWidth = KindRes->second;
4340 Operands.push_back(AArch64Operand::CreateVectorReg(
4341 RegNum, RK, ElementWidth, S,
4345 if (RK == RegKind::SVEPredicateAsCounter) {
4346 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4352 if (parseOperand(
Operands,
false,
false))
4363 return Error(S,
"not expecting size suffix");
4371 auto Pred = getTok().getString().lower();
4372 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4373 return Error(getLoc(),
"expecting 'z' predication");
4375 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4376 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4379 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4389 if (!tryParseNeonVectorRegister(
Operands))
4392 if (tryParseZTOperand(
Operands).isSuccess())
4396 if (tryParseGPROperand<false>(
Operands).isSuccess())
4402bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4403 bool HasELFModifier =
false;
4405 SMLoc Loc = getLexer().getLoc();
4407 HasELFModifier =
true;
4410 return TokError(
"expect relocation specifier in operand after ':'");
4412 std::string LowerCase = getTok().getIdentifier().lower();
4413 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4468 return TokError(
"expect relocation specifier in operand after ':'");
4472 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4476 if (getParser().parseExpression(ImmVal))
4484 if (!HasELFModifier &&
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4485 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4495 if (getParser().parsePrimaryExpr(Term, EndLoc))
4507 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4508 unsigned &ElementWidth) -> ParseStatus {
4509 StringRef
Name = getTok().getString();
4510 size_t DotPosition =
Name.find(
'.');
4518 StringRef
Tail =
Name.drop_front(DotPosition);
4519 const std::optional<std::pair<int, int>> &KindRes =
4523 "Expected the register to be followed by element width suffix");
4524 ElementWidth = KindRes->second;
4531 auto LCurly = getTok();
4536 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4542 if (getTok().getString().equals_insensitive(
"za")) {
4548 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4553 SMLoc TileLoc = getLoc();
4555 unsigned FirstReg, ElementWidth;
4556 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4557 if (!ParseRes.isSuccess()) {
4558 getLexer().UnLex(LCurly);
4562 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4564 unsigned PrevReg = FirstReg;
4566 SmallSet<unsigned, 8> DRegs;
4567 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4569 SmallSet<unsigned, 8> SeenRegs;
4570 SeenRegs.
insert(FirstReg);
4574 unsigned Reg, NextElementWidth;
4575 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4576 if (!ParseRes.isSuccess())
4580 if (ElementWidth != NextElementWidth)
4581 return Error(TileLoc,
"mismatched register size suffix");
4584 Warning(TileLoc,
"tile list not in ascending order");
4587 Warning(TileLoc,
"duplicate tile in list");
4590 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4599 unsigned RegMask = 0;
4600 for (
auto Reg : DRegs)
4604 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4609template <RegKind VectorKind>
4612 MCAsmParser &Parser = getParser();
4617 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4618 bool NoMatchIsError) -> ParseStatus {
4619 auto RegTok = getTok();
4620 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4621 if (ParseRes.isSuccess()) {
4628 RegTok.getString().equals_insensitive(
"zt0"))
4632 (ParseRes.isNoMatch() && NoMatchIsError &&
4633 !RegTok.getString().starts_with_insensitive(
"za")))
4634 return Error(Loc,
"vector register expected");
4639 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4641 auto LCurly = getTok();
4645 MCRegister FirstReg;
4646 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4650 if (ParseRes.isNoMatch())
4653 if (!ParseRes.isSuccess())
4656 MCRegister PrevReg = FirstReg;
4659 unsigned Stride = 1;
4661 SMLoc Loc = getLoc();
4665 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4666 if (!ParseRes.isSuccess())
4670 if (Kind != NextKind)
4671 return Error(Loc,
"mismatched register size suffix");
4674 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4676 if (Space == 0 || Space > 3)
4677 return Error(Loc,
"invalid number of vectors");
4682 bool HasCalculatedStride =
false;
4684 SMLoc Loc = getLoc();
4687 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4688 if (!ParseRes.isSuccess())
4692 if (Kind != NextKind)
4693 return Error(Loc,
"mismatched register size suffix");
4695 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4696 unsigned PrevRegVal =
4697 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4698 if (!HasCalculatedStride) {
4699 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4700 : (NumRegs - (PrevRegVal - RegVal));
4701 HasCalculatedStride =
true;
4705 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4706 return Error(Loc,
"registers must have the same sequential stride");
4717 return Error(S,
"invalid number of vectors");
4719 unsigned NumElements = 0;
4720 unsigned ElementWidth = 0;
4721 if (!
Kind.empty()) {
4723 std::tie(NumElements, ElementWidth) = *VK;
4726 Operands.push_back(AArch64Operand::CreateVectorList(
4727 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4731 ParseStatus Res = tryParseVectorIndex(
Operands);
4742 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4743 if (!ParseRes.isSuccess())
4746 return tryParseVectorIndex(
Operands).isFailure();
4750 SMLoc StartLoc = getLoc();
4753 ParseStatus Res = tryParseScalarRegister(RegNum);
4758 Operands.push_back(AArch64Operand::CreateReg(
4759 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4766 return Error(getLoc(),
"index must be absent or #0");
4768 const MCExpr *ImmVal;
4771 return Error(getLoc(),
"index must be absent or #0");
4773 Operands.push_back(AArch64Operand::CreateReg(
4774 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4779 SMLoc StartLoc = getLoc();
4780 const AsmToken &Tok = getTok();
4783 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4788 Operands.push_back(AArch64Operand::CreateReg(
4789 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4795 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4796 const MCExpr *ImmVal;
4797 if (getParser().parseExpression(ImmVal))
4801 return TokError(
"immediate value expected for vector index");
4802 Operands.push_back(AArch64Operand::CreateImm(
4806 if (parseOptionalMulOperand(
Operands))
4811 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4816template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4818 SMLoc StartLoc = getLoc();
4821 ParseStatus Res = tryParseScalarRegister(RegNum);
4827 Operands.push_back(AArch64Operand::CreateReg(
4828 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4837 Res = tryParseOptionalShiftExtend(ExtOpnd);
4841 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4842 Operands.push_back(AArch64Operand::CreateReg(
4843 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4844 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4845 Ext->hasShiftExtendAmount()));
4851 MCAsmParser &Parser = getParser();
4859 if (!getTok().getString().equals_insensitive(
"mul") ||
4860 !(NextIsVL || NextIsHash))
4864 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4869 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4879 const MCExpr *ImmVal;
4882 Operands.push_back(AArch64Operand::CreateImm(
4889 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4893 StringRef &VecGroup) {
4894 MCAsmParser &Parser = getParser();
4895 auto Tok = Parser.
getTok();
4900 .Case(
"vgx2",
"vgx2")
4901 .Case(
"vgx4",
"vgx4")
4913 auto Tok = getTok();
4920 .Case(
"csync",
"csync")
4923 .Case(
"keep",
"keep")
4927 .Case(
"strm",
"strm")
4940 bool invertCondCode) {
4941 MCAsmParser &Parser = getParser();
4944 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4958 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4960 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4963 getLexer().UnLex(SavedTok);
4967 switch (getLexer().getKind()) {
4971 if (parseSymbolicImmVal(Expr))
4972 return Error(S,
"invalid operand");
4976 return parseOptionalShiftExtend(getTok());
4980 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4985 return parseOperand(
Operands,
false,
false);
4988 if (!parseNeonVectorList(
Operands))
4992 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
4997 return parseOperand(
Operands,
false,
false);
5002 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
5004 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5014 AsmToken SavedTok = getTok();
5019 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5023 Res = tryParseOptionalShiftExtend(
Operands);
5026 getLexer().UnLex(SavedTok);
5033 if (!parseOptionalMulOperand(
Operands))
5038 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5039 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5040 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh")
5041 return parseKeywordOperand(
Operands);
5045 const MCExpr *IdVal, *
Term;
5047 if (getParser().parseExpression(IdVal))
5049 if (getParser().parseAtSpecifier(IdVal,
E))
5051 std::optional<MCBinaryExpr::Opcode> Opcode;
5057 if (getParser().parsePrimaryExpr(Term,
E))
5064 return parseOptionalShiftExtend(getTok());
5075 bool isNegative =
false;
5087 const AsmToken &Tok = getTok();
5091 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5092 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5093 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5094 return TokError(
"unexpected floating point literal");
5095 else if (IntVal != 0 || isNegative)
5096 return TokError(
"expected floating-point constant #0.0");
5104 const MCExpr *ImmVal;
5105 if (parseSymbolicImmVal(ImmVal))
5112 return parseOptionalShiftExtend(Tok);
5115 SMLoc Loc = getLoc();
5116 if (Mnemonic !=
"ldr")
5117 return TokError(
"unexpected token in operand");
5119 const MCExpr *SubExprVal;
5120 if (getParser().parseExpression(SubExprVal))
5124 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5125 return Error(Loc,
"Only valid when first operand is register");
5127 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5135 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5140 if (ShiftAmt <= MaxShiftAmt &&
Imm <= 0xFFFF) {
5141 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5142 Operands.push_back(AArch64Operand::CreateImm(
5146 ShiftAmt,
true, S,
E, Ctx));
5149 APInt Simm = APInt(64,
Imm << ShiftAmt);
5152 return Error(Loc,
"Immediate too large for register");
5155 const MCExpr *CPLoc =
5156 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5157 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5163bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5164 const MCExpr *Expr =
nullptr;
5166 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5169 if (check(!
Value, L,
"expected constant expression"))
5171 Out =
Value->getValue();
5175bool AArch64AsmParser::parseComma() {
5183bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5187 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5192 unsigned RangeEnd =
Last;
5193 if (
Base == AArch64::X0) {
5194 if (
Last == AArch64::FP) {
5195 RangeEnd = AArch64::X28;
5196 if (
Reg == AArch64::FP) {
5201 if (
Last == AArch64::LR) {
5202 RangeEnd = AArch64::X28;
5203 if (
Reg == AArch64::FP) {
5206 }
else if (
Reg == AArch64::LR) {
5214 Twine(
"expected register in range ") +
5222bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5223 const MCParsedAsmOperand &Op2)
const {
5224 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5225 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5227 if (AOp1.isVectorList() && AOp2.isVectorList())
5228 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5229 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5230 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5232 if (!AOp1.isReg() || !AOp2.isReg())
5235 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5236 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5239 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5240 "Testing equality of non-scalar registers not supported");
5243 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5245 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5247 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5249 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5256bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5257 StringRef Name, SMLoc NameLoc,
5259 Name = StringSwitch<StringRef>(
Name.lower())
5260 .Case(
"beq",
"b.eq")
5261 .Case(
"bne",
"b.ne")
5262 .Case(
"bhs",
"b.hs")
5263 .Case(
"bcs",
"b.cs")
5264 .Case(
"blo",
"b.lo")
5265 .Case(
"bcc",
"b.cc")
5266 .Case(
"bmi",
"b.mi")
5267 .Case(
"bpl",
"b.pl")
5268 .Case(
"bvs",
"b.vs")
5269 .Case(
"bvc",
"b.vc")
5270 .Case(
"bhi",
"b.hi")
5271 .Case(
"bls",
"b.ls")
5272 .Case(
"bge",
"b.ge")
5273 .Case(
"blt",
"b.lt")
5274 .Case(
"bgt",
"b.gt")
5275 .Case(
"ble",
"b.le")
5276 .Case(
"bal",
"b.al")
5277 .Case(
"bnv",
"b.nv")
5282 getTok().getIdentifier().lower() ==
".req") {
5283 parseDirectiveReq(Name, NameLoc);
5291 StringRef Head =
Name.slice(Start,
Next);
5295 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5296 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5297 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5298 return parseSysAlias(Head, NameLoc,
Operands);
5302 return parseSyslAlias(Head, NameLoc,
Operands);
5305 if (Head ==
"tlbip")
5306 return parseSyspAlias(Head, NameLoc,
Operands);
5315 Head =
Name.slice(Start + 1,
Next);
5319 std::string Suggestion;
5322 std::string
Msg =
"invalid condition code";
5323 if (!Suggestion.empty())
5324 Msg +=
", did you mean " + Suggestion +
"?";
5330 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5340 Operands.push_back(AArch64Operand::CreateToken(
5346 bool condCodeFourthOperand =
5347 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5348 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5349 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5357 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5358 bool condCodeThirdOperand =
5359 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5367 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5368 (
N == 3 && condCodeThirdOperand) ||
5369 (
N == 2 && condCodeSecondOperand),
5370 condCodeSecondOperand || condCodeThirdOperand)) {
5390 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5393 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5396 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5409 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5410 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5411 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5412 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5413 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5414 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5415 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5427bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5428 SmallVectorImpl<SMLoc> &Loc) {
5429 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5436 PrefixInfo
Prefix = NextPrefix;
5437 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5448 return Error(IDLoc,
"instruction is unpredictable when following a"
5449 " movprfx, suggest replacing movprfx with mov");
5453 return Error(Loc[0],
"instruction is unpredictable when following a"
5454 " movprfx writing to a different destination");
5461 return Error(Loc[0],
"instruction is unpredictable when following a"
5462 " movprfx and destination also used as non-destructive"
5466 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5467 if (
Prefix.isPredicated()) {
5481 return Error(IDLoc,
"instruction is unpredictable when following a"
5482 " predicated movprfx, suggest using unpredicated movprfx");
5486 return Error(IDLoc,
"instruction is unpredictable when following a"
5487 " predicated movprfx using a different general predicate");
5491 return Error(IDLoc,
"instruction is unpredictable when following a"
5492 " predicated movprfx with a different element size");
5498 if (IsWindowsArm64EC) {
5504 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5505 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5506 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5507 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5508 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5509 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5510 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5511 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5512 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5513 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5515 " is disallowed on ARM64EC.");
5525 case AArch64::LDPSWpre:
5526 case AArch64::LDPWpost:
5527 case AArch64::LDPWpre:
5528 case AArch64::LDPXpost:
5529 case AArch64::LDPXpre: {
5534 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5535 "is also a destination");
5537 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5538 "is also a destination");
5541 case AArch64::LDR_ZA:
5542 case AArch64::STR_ZA: {
5545 return Error(Loc[1],
5546 "unpredictable instruction, immediate and offset mismatch.");
5549 case AArch64::LDPDi:
5550 case AArch64::LDPQi:
5551 case AArch64::LDPSi:
5552 case AArch64::LDPSWi:
5553 case AArch64::LDPWi:
5554 case AArch64::LDPXi: {
5558 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5561 case AArch64::LDPDpost:
5562 case AArch64::LDPDpre:
5563 case AArch64::LDPQpost:
5564 case AArch64::LDPQpre:
5565 case AArch64::LDPSpost:
5566 case AArch64::LDPSpre:
5567 case AArch64::LDPSWpost: {
5571 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5574 case AArch64::STPDpost:
5575 case AArch64::STPDpre:
5576 case AArch64::STPQpost:
5577 case AArch64::STPQpre:
5578 case AArch64::STPSpost:
5579 case AArch64::STPSpre:
5580 case AArch64::STPWpost:
5581 case AArch64::STPWpre:
5582 case AArch64::STPXpost:
5583 case AArch64::STPXpre: {
5588 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5589 "is also a source");
5591 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5592 "is also a source");
5595 case AArch64::LDRBBpre:
5596 case AArch64::LDRBpre:
5597 case AArch64::LDRHHpre:
5598 case AArch64::LDRHpre:
5599 case AArch64::LDRSBWpre:
5600 case AArch64::LDRSBXpre:
5601 case AArch64::LDRSHWpre:
5602 case AArch64::LDRSHXpre:
5603 case AArch64::LDRSWpre:
5604 case AArch64::LDRWpre:
5605 case AArch64::LDRXpre:
5606 case AArch64::LDRBBpost:
5607 case AArch64::LDRBpost:
5608 case AArch64::LDRHHpost:
5609 case AArch64::LDRHpost:
5610 case AArch64::LDRSBWpost:
5611 case AArch64::LDRSBXpost:
5612 case AArch64::LDRSHWpost:
5613 case AArch64::LDRSHXpost:
5614 case AArch64::LDRSWpost:
5615 case AArch64::LDRWpost:
5616 case AArch64::LDRXpost: {
5620 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5621 "is also a source");
5624 case AArch64::STRBBpost:
5625 case AArch64::STRBpost:
5626 case AArch64::STRHHpost:
5627 case AArch64::STRHpost:
5628 case AArch64::STRWpost:
5629 case AArch64::STRXpost:
5630 case AArch64::STRBBpre:
5631 case AArch64::STRBpre:
5632 case AArch64::STRHHpre:
5633 case AArch64::STRHpre:
5634 case AArch64::STRWpre:
5635 case AArch64::STRXpre: {
5639 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5640 "is also a source");
5643 case AArch64::STXRB:
5644 case AArch64::STXRH:
5645 case AArch64::STXRW:
5646 case AArch64::STXRX:
5647 case AArch64::STLXRB:
5648 case AArch64::STLXRH:
5649 case AArch64::STLXRW:
5650 case AArch64::STLXRX: {
5656 return Error(Loc[0],
5657 "unpredictable STXR instruction, status is also a source");
5660 case AArch64::STXPW:
5661 case AArch64::STXPX:
5662 case AArch64::STLXPW:
5663 case AArch64::STLXPX: {
5670 return Error(Loc[0],
5671 "unpredictable STXP instruction, status is also a source");
5674 case AArch64::LDRABwriteback:
5675 case AArch64::LDRAAwriteback: {
5679 return Error(Loc[0],
5680 "unpredictable LDRA instruction, writeback base"
5681 " is also a destination");
5688 case AArch64::CPYFP:
5689 case AArch64::CPYFPWN:
5690 case AArch64::CPYFPRN:
5691 case AArch64::CPYFPN:
5692 case AArch64::CPYFPWT:
5693 case AArch64::CPYFPWTWN:
5694 case AArch64::CPYFPWTRN:
5695 case AArch64::CPYFPWTN:
5696 case AArch64::CPYFPRT:
5697 case AArch64::CPYFPRTWN:
5698 case AArch64::CPYFPRTRN:
5699 case AArch64::CPYFPRTN:
5700 case AArch64::CPYFPT:
5701 case AArch64::CPYFPTWN:
5702 case AArch64::CPYFPTRN:
5703 case AArch64::CPYFPTN:
5704 case AArch64::CPYFM:
5705 case AArch64::CPYFMWN:
5706 case AArch64::CPYFMRN:
5707 case AArch64::CPYFMN:
5708 case AArch64::CPYFMWT:
5709 case AArch64::CPYFMWTWN:
5710 case AArch64::CPYFMWTRN:
5711 case AArch64::CPYFMWTN:
5712 case AArch64::CPYFMRT:
5713 case AArch64::CPYFMRTWN:
5714 case AArch64::CPYFMRTRN:
5715 case AArch64::CPYFMRTN:
5716 case AArch64::CPYFMT:
5717 case AArch64::CPYFMTWN:
5718 case AArch64::CPYFMTRN:
5719 case AArch64::CPYFMTN:
5720 case AArch64::CPYFE:
5721 case AArch64::CPYFEWN:
5722 case AArch64::CPYFERN:
5723 case AArch64::CPYFEN:
5724 case AArch64::CPYFEWT:
5725 case AArch64::CPYFEWTWN:
5726 case AArch64::CPYFEWTRN:
5727 case AArch64::CPYFEWTN:
5728 case AArch64::CPYFERT:
5729 case AArch64::CPYFERTWN:
5730 case AArch64::CPYFERTRN:
5731 case AArch64::CPYFERTN:
5732 case AArch64::CPYFET:
5733 case AArch64::CPYFETWN:
5734 case AArch64::CPYFETRN:
5735 case AArch64::CPYFETN:
5737 case AArch64::CPYPWN:
5738 case AArch64::CPYPRN:
5739 case AArch64::CPYPN:
5740 case AArch64::CPYPWT:
5741 case AArch64::CPYPWTWN:
5742 case AArch64::CPYPWTRN:
5743 case AArch64::CPYPWTN:
5744 case AArch64::CPYPRT:
5745 case AArch64::CPYPRTWN:
5746 case AArch64::CPYPRTRN:
5747 case AArch64::CPYPRTN:
5748 case AArch64::CPYPT:
5749 case AArch64::CPYPTWN:
5750 case AArch64::CPYPTRN:
5751 case AArch64::CPYPTN:
5753 case AArch64::CPYMWN:
5754 case AArch64::CPYMRN:
5755 case AArch64::CPYMN:
5756 case AArch64::CPYMWT:
5757 case AArch64::CPYMWTWN:
5758 case AArch64::CPYMWTRN:
5759 case AArch64::CPYMWTN:
5760 case AArch64::CPYMRT:
5761 case AArch64::CPYMRTWN:
5762 case AArch64::CPYMRTRN:
5763 case AArch64::CPYMRTN:
5764 case AArch64::CPYMT:
5765 case AArch64::CPYMTWN:
5766 case AArch64::CPYMTRN:
5767 case AArch64::CPYMTN:
5769 case AArch64::CPYEWN:
5770 case AArch64::CPYERN:
5771 case AArch64::CPYEN:
5772 case AArch64::CPYEWT:
5773 case AArch64::CPYEWTWN:
5774 case AArch64::CPYEWTRN:
5775 case AArch64::CPYEWTN:
5776 case AArch64::CPYERT:
5777 case AArch64::CPYERTWN:
5778 case AArch64::CPYERTRN:
5779 case AArch64::CPYERTN:
5780 case AArch64::CPYET:
5781 case AArch64::CPYETWN:
5782 case AArch64::CPYETRN:
5783 case AArch64::CPYETN: {
5794 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5795 " registers are the same");
5797 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5798 " registers are the same");
5800 return Error(Loc[0],
"invalid CPY instruction, source and size"
5801 " registers are the same");
5805 case AArch64::SETPT:
5806 case AArch64::SETPN:
5807 case AArch64::SETPTN:
5809 case AArch64::SETMT:
5810 case AArch64::SETMN:
5811 case AArch64::SETMTN:
5813 case AArch64::SETET:
5814 case AArch64::SETEN:
5815 case AArch64::SETETN:
5816 case AArch64::SETGP:
5817 case AArch64::SETGPT:
5818 case AArch64::SETGPN:
5819 case AArch64::SETGPTN:
5820 case AArch64::SETGM:
5821 case AArch64::SETGMT:
5822 case AArch64::SETGMN:
5823 case AArch64::SETGMTN:
5824 case AArch64::MOPSSETGE:
5825 case AArch64::MOPSSETGET:
5826 case AArch64::MOPSSETGEN:
5827 case AArch64::MOPSSETGETN: {
5837 return Error(Loc[0],
"invalid SET instruction, destination and size"
5838 " registers are the same");
5840 return Error(Loc[0],
"invalid SET instruction, destination and source"
5841 " registers are the same");
5843 return Error(Loc[0],
"invalid SET instruction, source and size"
5844 " registers are the same");
5847 case AArch64::SETGOP:
5848 case AArch64::SETGOPT:
5849 case AArch64::SETGOPN:
5850 case AArch64::SETGOPTN:
5851 case AArch64::SETGOM:
5852 case AArch64::SETGOMT:
5853 case AArch64::SETGOMN:
5854 case AArch64::SETGOMTN:
5855 case AArch64::SETGOE:
5856 case AArch64::SETGOET:
5857 case AArch64::SETGOEN:
5858 case AArch64::SETGOETN: {
5867 return Error(Loc[0],
"invalid SET instruction, destination and size"
5868 " registers are the same");
5877 case AArch64::ADDSWri:
5878 case AArch64::ADDSXri:
5879 case AArch64::ADDWri:
5880 case AArch64::ADDXri:
5881 case AArch64::SUBSWri:
5882 case AArch64::SUBSXri:
5883 case AArch64::SUBWri:
5884 case AArch64::SUBXri: {
5892 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5917 return Error(Loc.
back(),
"invalid immediate expression");
5930 unsigned VariantID = 0);
5932bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5936 case Match_InvalidTiedOperand: {
5938 if (
Op.isVectorList())
5939 return Error(
Loc,
"operand must match destination register list");
5941 assert(
Op.isReg() &&
"Unexpected operand type");
5942 switch (
Op.getRegEqualityTy()) {
5943 case RegConstraintEqualityTy::EqualsSubReg:
5944 return Error(
Loc,
"operand must be 64-bit form of destination register");
5945 case RegConstraintEqualityTy::EqualsSuperReg:
5946 return Error(
Loc,
"operand must be 32-bit form of destination register");
5947 case RegConstraintEqualityTy::EqualsReg:
5948 return Error(
Loc,
"operand must match destination register");
5952 case Match_MissingFeature:
5954 "instruction requires a CPU feature not currently enabled");
5955 case Match_InvalidOperand:
5956 return Error(Loc,
"invalid operand for instruction");
5957 case Match_InvalidSuffix:
5958 return Error(Loc,
"invalid type suffix for instruction");
5959 case Match_InvalidCondCode:
5960 return Error(Loc,
"expected AArch64 condition code");
5961 case Match_AddSubRegExtendSmall:
5963 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5964 case Match_AddSubRegExtendLarge:
5966 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5967 case Match_AddSubSecondSource:
5969 "expected compatible register, symbol or integer in range [0, 4095]");
5970 case Match_LogicalSecondSource:
5971 return Error(Loc,
"expected compatible register or logical immediate");
5972 case Match_InvalidMovImm32Shift:
5973 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5974 case Match_InvalidMovImm64Shift:
5975 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5976 case Match_AddSubRegShift32:
5978 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5979 case Match_AddSubRegShift64:
5981 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5982 case Match_InvalidFPImm:
5984 "expected compatible register or floating-point constant");
5985 case Match_InvalidMemoryIndexedSImm6:
5986 return Error(Loc,
"index must be an integer in range [-32, 31].");
5987 case Match_InvalidMemoryIndexedSImm5:
5988 return Error(Loc,
"index must be an integer in range [-16, 15].");
5989 case Match_InvalidMemoryIndexed1SImm4:
5990 return Error(Loc,
"index must be an integer in range [-8, 7].");
5991 case Match_InvalidMemoryIndexed2SImm4:
5992 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5993 case Match_InvalidMemoryIndexed3SImm4:
5994 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5995 case Match_InvalidMemoryIndexed4SImm4:
5996 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5997 case Match_InvalidMemoryIndexed16SImm4:
5998 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5999 case Match_InvalidMemoryIndexed32SImm4:
6000 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6001 case Match_InvalidMemoryIndexed1SImm6:
6002 return Error(Loc,
"index must be an integer in range [-32, 31].");
6003 case Match_InvalidMemoryIndexedSImm8:
6004 return Error(Loc,
"index must be an integer in range [-128, 127].");
6005 case Match_InvalidMemoryIndexedSImm9:
6006 return Error(Loc,
"index must be an integer in range [-256, 255].");
6007 case Match_InvalidMemoryIndexed16SImm9:
6008 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6009 case Match_InvalidMemoryIndexed8SImm10:
6010 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6011 case Match_InvalidMemoryIndexed4SImm7:
6012 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6013 case Match_InvalidMemoryIndexed8SImm7:
6014 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6015 case Match_InvalidMemoryIndexed16SImm7:
6016 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6017 case Match_InvalidMemoryIndexed8UImm5:
6018 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6019 case Match_InvalidMemoryIndexed8UImm3:
6020 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6021 case Match_InvalidMemoryIndexed4UImm5:
6022 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6023 case Match_InvalidMemoryIndexed2UImm5:
6024 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6025 case Match_InvalidMemoryIndexed8UImm6:
6026 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6027 case Match_InvalidMemoryIndexed16UImm6:
6028 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6029 case Match_InvalidMemoryIndexed4UImm6:
6030 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6031 case Match_InvalidMemoryIndexed2UImm6:
6032 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6033 case Match_InvalidMemoryIndexed1UImm6:
6034 return Error(Loc,
"index must be in range [0, 63].");
6035 case Match_InvalidMemoryWExtend8:
6037 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6038 case Match_InvalidMemoryWExtend16:
6040 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6041 case Match_InvalidMemoryWExtend32:
6043 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6044 case Match_InvalidMemoryWExtend64:
6046 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6047 case Match_InvalidMemoryWExtend128:
6049 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6050 case Match_InvalidMemoryXExtend8:
6052 "expected 'lsl' or 'sxtx' with optional shift of #0");
6053 case Match_InvalidMemoryXExtend16:
6055 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6056 case Match_InvalidMemoryXExtend32:
6058 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6059 case Match_InvalidMemoryXExtend64:
6061 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6062 case Match_InvalidMemoryXExtend128:
6064 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6065 case Match_InvalidMemoryIndexed1:
6066 return Error(Loc,
"index must be an integer in range [0, 4095].");
6067 case Match_InvalidMemoryIndexed2:
6068 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6069 case Match_InvalidMemoryIndexed4:
6070 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6071 case Match_InvalidMemoryIndexed8:
6072 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6073 case Match_InvalidMemoryIndexed16:
6074 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6075 case Match_InvalidImm0_0:
6076 return Error(Loc,
"immediate must be 0.");
6077 case Match_InvalidImm0_1:
6078 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6079 case Match_InvalidImm0_3:
6080 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6081 case Match_InvalidImm0_7:
6082 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6083 case Match_InvalidImm0_15:
6084 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6085 case Match_InvalidImm0_31:
6086 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6087 case Match_InvalidImm0_63:
6088 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6089 case Match_InvalidImm0_127:
6090 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6091 case Match_InvalidImm0_255:
6092 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6093 case Match_InvalidImm0_65535:
6094 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6095 case Match_InvalidHinteUImm16:
6097 "immediate must be an integer in range [0, 65535], excluding "
6098 "values in range [12319, 16383] where (value - 12319) is a "
6100 case Match_InvalidImm1_8:
6101 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6102 case Match_InvalidImm1_16:
6103 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6104 case Match_InvalidImm1_32:
6105 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6106 case Match_InvalidImm1_64:
6107 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6108 case Match_InvalidImmM1_62:
6109 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6110 case Match_InvalidMemoryIndexedRange2UImm0:
6111 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6112 case Match_InvalidMemoryIndexedRange2UImm1:
6113 return Error(Loc,
"vector select offset must be an immediate range of the "
6114 "form <immf>:<imml>, where the first "
6115 "immediate is a multiple of 2 in the range [0, 2], and "
6116 "the second immediate is immf + 1.");
6117 case Match_InvalidMemoryIndexedRange2UImm2:
6118 case Match_InvalidMemoryIndexedRange2UImm3:
6121 "vector select offset must be an immediate range of the form "
6123 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6125 "depending on the instruction, and the second immediate is immf + 1.");
6126 case Match_InvalidMemoryIndexedRange4UImm0:
6127 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6128 case Match_InvalidMemoryIndexedRange4UImm1:
6129 case Match_InvalidMemoryIndexedRange4UImm2:
6132 "vector select offset must be an immediate range of the form "
6134 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6136 "depending on the instruction, and the second immediate is immf + 3.");
6137 case Match_InvalidSVEAddSubImm8:
6138 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6139 " with a shift amount of 0");
6140 case Match_InvalidSVEAddSubImm16:
6141 case Match_InvalidSVEAddSubImm32:
6142 case Match_InvalidSVEAddSubImm64:
6143 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6144 "multiple of 256 in range [256, 65280]");
6145 case Match_InvalidSVECpyImm8:
6146 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6147 " with a shift amount of 0");
6148 case Match_InvalidSVECpyImm16:
6149 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6150 "multiple of 256 in range [-32768, 65280]");
6151 case Match_InvalidSVECpyImm32:
6152 case Match_InvalidSVECpyImm64:
6153 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6154 "multiple of 256 in range [-32768, 32512]");
6155 case Match_InvalidIndexRange0_0:
6156 return Error(Loc,
"expected lane specifier '[0]'");
6157 case Match_InvalidIndexRange1_1:
6158 return Error(Loc,
"expected lane specifier '[1]'");
6159 case Match_InvalidIndexRange0_15:
6160 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6161 case Match_InvalidIndexRange0_7:
6162 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6163 case Match_InvalidIndexRange0_3:
6164 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6165 case Match_InvalidIndexRange0_1:
6166 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6167 case Match_InvalidSVEIndexRange0_63:
6168 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6169 case Match_InvalidSVEIndexRange0_31:
6170 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6171 case Match_InvalidSVEIndexRange0_15:
6172 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6173 case Match_InvalidSVEIndexRange0_7:
6174 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6175 case Match_InvalidSVEIndexRange0_3:
6176 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6177 case Match_InvalidLabel:
6178 return Error(Loc,
"expected label or encodable integer pc offset");
6180 return Error(Loc,
"expected readable system register");
6182 case Match_InvalidSVCR:
6183 return Error(Loc,
"expected writable system register or pstate");
6184 case Match_InvalidComplexRotationEven:
6185 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6186 case Match_InvalidComplexRotationOdd:
6187 return Error(Loc,
"complex rotation must be 90 or 270.");
6188 case Match_MnemonicFail: {
6191 ComputeAvailableFeatures(STI->getFeatureBits()));
6192 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6194 case Match_InvalidGPR64shifted8:
6195 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6196 case Match_InvalidGPR64shifted16:
6197 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6198 case Match_InvalidGPR64shifted32:
6199 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6200 case Match_InvalidGPR64shifted64:
6201 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6202 case Match_InvalidGPR64shifted128:
6204 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6205 case Match_InvalidGPR64NoXZRshifted8:
6206 return Error(Loc,
"register must be x0..x30 without shift");
6207 case Match_InvalidGPR64NoXZRshifted16:
6208 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6209 case Match_InvalidGPR64NoXZRshifted32:
6210 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6211 case Match_InvalidGPR64NoXZRshifted64:
6212 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6213 case Match_InvalidGPR64NoXZRshifted128:
6214 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6215 case Match_InvalidZPR32UXTW8:
6216 case Match_InvalidZPR32SXTW8:
6217 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6218 case Match_InvalidZPR32UXTW16:
6219 case Match_InvalidZPR32SXTW16:
6220 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6221 case Match_InvalidZPR32UXTW32:
6222 case Match_InvalidZPR32SXTW32:
6223 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6224 case Match_InvalidZPR32UXTW64:
6225 case Match_InvalidZPR32SXTW64:
6226 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6227 case Match_InvalidZPR64UXTW8:
6228 case Match_InvalidZPR64SXTW8:
6229 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6230 case Match_InvalidZPR64UXTW16:
6231 case Match_InvalidZPR64SXTW16:
6232 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6233 case Match_InvalidZPR64UXTW32:
6234 case Match_InvalidZPR64SXTW32:
6235 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6236 case Match_InvalidZPR64UXTW64:
6237 case Match_InvalidZPR64SXTW64:
6238 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6239 case Match_InvalidZPR32LSL8:
6240 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6241 case Match_InvalidZPR32LSL16:
6242 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6243 case Match_InvalidZPR32LSL32:
6244 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6245 case Match_InvalidZPR32LSL64:
6246 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6247 case Match_InvalidZPR64LSL8:
6248 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6249 case Match_InvalidZPR64LSL16:
6250 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6251 case Match_InvalidZPR64LSL32:
6252 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6253 case Match_InvalidZPR64LSL64:
6254 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6255 case Match_InvalidZPR0:
6256 return Error(Loc,
"expected register without element width suffix");
6257 case Match_InvalidZPR8:
6258 case Match_InvalidZPR16:
6259 case Match_InvalidZPR32:
6260 case Match_InvalidZPR64:
6261 case Match_InvalidZPR128:
6262 return Error(Loc,
"invalid element width");
6263 case Match_InvalidZPR_3b8:
6264 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6265 case Match_InvalidZPR_3b16:
6266 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6267 case Match_InvalidZPR_3b32:
6268 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6269 case Match_InvalidZPR_4b8:
6271 "Invalid restricted vector register, expected z0.b..z15.b");
6272 case Match_InvalidZPR_4b16:
6273 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6274 case Match_InvalidZPR_4b32:
6275 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6276 case Match_InvalidZPR_4b64:
6277 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6278 case Match_InvalidZPRMul2_Lo8:
6279 return Error(Loc,
"Invalid restricted vector register, expected even "
6280 "register in z0.b..z14.b");
6281 case Match_InvalidZPRMul2_Hi8:
6282 return Error(Loc,
"Invalid restricted vector register, expected even "
6283 "register in z16.b..z30.b");
6284 case Match_InvalidZPRMul2_Lo16:
6285 return Error(Loc,
"Invalid restricted vector register, expected even "
6286 "register in z0.h..z14.h");
6287 case Match_InvalidZPRMul2_Hi16:
6288 return Error(Loc,
"Invalid restricted vector register, expected even "
6289 "register in z16.h..z30.h");
6290 case Match_InvalidZPRMul2_Lo32:
6291 return Error(Loc,
"Invalid restricted vector register, expected even "
6292 "register in z0.s..z14.s");
6293 case Match_InvalidZPRMul2_Hi32:
6294 return Error(Loc,
"Invalid restricted vector register, expected even "
6295 "register in z16.s..z30.s");
6296 case Match_InvalidZPRMul2_Lo64:
6297 return Error(Loc,
"Invalid restricted vector register, expected even "
6298 "register in z0.d..z14.d");
6299 case Match_InvalidZPRMul2_Hi64:
6300 return Error(Loc,
"Invalid restricted vector register, expected even "
6301 "register in z16.d..z30.d");
6302 case Match_InvalidZPR_K0:
6303 return Error(Loc,
"invalid restricted vector register, expected register "
6304 "in z20..z23 or z28..z31");
6305 case Match_InvalidSVEPattern:
6306 return Error(Loc,
"invalid predicate pattern");
6307 case Match_InvalidSVEPPRorPNRAnyReg:
6308 case Match_InvalidSVEPPRorPNRBReg:
6309 case Match_InvalidSVEPredicateAnyReg:
6310 case Match_InvalidSVEPredicateBReg:
6311 case Match_InvalidSVEPredicateHReg:
6312 case Match_InvalidSVEPredicateSReg:
6313 case Match_InvalidSVEPredicateDReg:
6314 return Error(Loc,
"invalid predicate register.");
6315 case Match_InvalidSVEPredicate3bAnyReg:
6316 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6317 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6318 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6319 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6320 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6321 return Error(Loc,
"Invalid predicate register, expected PN in range "
6322 "pn8..pn15 with element suffix.");
6323 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6324 return Error(Loc,
"invalid restricted predicate-as-counter register "
6325 "expected pn8..pn15");
6326 case Match_InvalidSVEPNPredicateBReg:
6327 case Match_InvalidSVEPNPredicateHReg:
6328 case Match_InvalidSVEPNPredicateSReg:
6329 case Match_InvalidSVEPNPredicateDReg:
6330 return Error(Loc,
"Invalid predicate register, expected PN in range "
6331 "pn0..pn15 with element suffix.");
6332 case Match_InvalidSVEVecLenSpecifier:
6333 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6334 case Match_InvalidSVEPredicateListMul2x8:
6335 case Match_InvalidSVEPredicateListMul2x16:
6336 case Match_InvalidSVEPredicateListMul2x32:
6337 case Match_InvalidSVEPredicateListMul2x64:
6338 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6339 "predicate registers, where the first vector is a multiple of 2 "
6340 "and with correct element type");
6341 case Match_InvalidSVEExactFPImmOperandHalfOne:
6342 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6343 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6344 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6345 case Match_InvalidSVEExactFPImmOperandZeroOne:
6346 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6347 case Match_InvalidMatrixTileVectorH8:
6348 case Match_InvalidMatrixTileVectorV8:
6349 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6350 case Match_InvalidMatrixTileVectorH16:
6351 case Match_InvalidMatrixTileVectorV16:
6353 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6354 case Match_InvalidMatrixTileVectorH32:
6355 case Match_InvalidMatrixTileVectorV32:
6357 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6358 case Match_InvalidMatrixTileVectorH64:
6359 case Match_InvalidMatrixTileVectorV64:
6361 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6362 case Match_InvalidMatrixTileVectorH128:
6363 case Match_InvalidMatrixTileVectorV128:
6365 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6366 case Match_InvalidMatrixTile16:
6367 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6368 case Match_InvalidMatrixTile32:
6369 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6370 case Match_InvalidMatrixTile64:
6371 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6372 case Match_InvalidMatrix:
6373 return Error(Loc,
"invalid matrix operand, expected za");
6374 case Match_InvalidMatrix8:
6375 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6376 case Match_InvalidMatrix16:
6377 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6378 case Match_InvalidMatrix32:
6379 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6380 case Match_InvalidMatrix64:
6381 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6382 case Match_InvalidMatrixIndexGPR32_12_15:
6383 return Error(Loc,
"operand must be a register in range [w12, w15]");
6384 case Match_InvalidMatrixIndexGPR32_8_11:
6385 return Error(Loc,
"operand must be a register in range [w8, w11]");
6386 case Match_InvalidSVEVectorList2x8Mul2:
6387 case Match_InvalidSVEVectorList2x16Mul2:
6388 case Match_InvalidSVEVectorList2x32Mul2:
6389 case Match_InvalidSVEVectorList2x64Mul2:
6390 case Match_InvalidSVEVectorList2x128Mul2:
6391 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6392 "SVE vectors, where the first vector is a multiple of 2 "
6393 "and with matching element types");
6394 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6395 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6396 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6397 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6398 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6399 "SVE vectors in the range z0-z14, where the first vector "
6400 "is a multiple of 2 "
6401 "and with matching element types");
6402 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6403 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6404 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6405 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6407 "Invalid vector list, expected list with 2 consecutive "
6408 "SVE vectors in the range z16-z30, where the first vector "
6409 "is a multiple of 2 "
6410 "and with matching element types");
6411 case Match_InvalidSVEVectorList4x8Mul4:
6412 case Match_InvalidSVEVectorList4x16Mul4:
6413 case Match_InvalidSVEVectorList4x32Mul4:
6414 case Match_InvalidSVEVectorList4x64Mul4:
6415 case Match_InvalidSVEVectorList4x128Mul4:
6416 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6417 "SVE vectors, where the first vector is a multiple of 4 "
6418 "and with matching element types");
6419 case Match_InvalidSVEVectorList3x0_3b:
6420 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6421 "SVE vectors starting at z0-z7");
6422 case Match_InvalidLookupTable:
6423 return Error(Loc,
"Invalid lookup table, expected zt0");
6424 case Match_InvalidSVEVectorListStrided2x8:
6425 case Match_InvalidSVEVectorListStrided2x16:
6426 case Match_InvalidSVEVectorListStrided2x32:
6427 case Match_InvalidSVEVectorListStrided2x64:
6430 "Invalid vector list, expected list with each SVE vector in the list "
6431 "8 registers apart, and the first register in the range [z0, z7] or "
6432 "[z16, z23] and with correct element type");
6433 case Match_InvalidSVEVectorListStrided4x8:
6434 case Match_InvalidSVEVectorListStrided4x16:
6435 case Match_InvalidSVEVectorListStrided4x32:
6436 case Match_InvalidSVEVectorListStrided4x64:
6439 "Invalid vector list, expected list with each SVE vector in the list "
6440 "4 registers apart, and the first register in the range [z0, z3] or "
6441 "[z16, z19] and with correct element type");
6442 case Match_AddSubLSLImm3ShiftLarge:
6444 "expected 'lsl' with optional integer in range [0, 7]");
6452bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6456 bool MatchingInlineAsm) {
6458 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6459 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6462 unsigned NumOperands =
Operands.size();
6464 if (NumOperands == 4 && Tok ==
"lsl") {
6465 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6466 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6467 if (Op2.isScalarReg() && Op3.isImm()) {
6473 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6475 NewOp3Val = (32 - Op3Val) & 0x1f;
6476 NewOp4Val = 31 - Op3Val;
6478 NewOp3Val = (64 - Op3Val) & 0x3f;
6479 NewOp4Val = 63 - Op3Val;
6486 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6487 Operands.push_back(AArch64Operand::CreateImm(
6488 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6489 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6493 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6495 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6496 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6497 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6499 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6503 if (LSBCE && WidthCE) {
6508 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6514 if (LSB >= RegWidth)
6515 return Error(LSBOp.getStartLoc(),
6516 "expected integer in range [0, 31]");
6517 if (Width < 1 || Width > RegWidth)
6518 return Error(WidthOp.getStartLoc(),
6519 "expected integer in range [1, 32]");
6523 ImmR = (32 - LSB) & 0x1f;
6525 ImmR = (64 - LSB) & 0x3f;
6529 if (ImmR != 0 && ImmS >= ImmR)
6530 return Error(WidthOp.getStartLoc(),
6531 "requested insert overflows register");
6536 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6537 Operands[2] = AArch64Operand::CreateReg(
6538 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6540 Operands[3] = AArch64Operand::CreateImm(
6541 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6543 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6547 }
else if (NumOperands == 5) {
6550 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6551 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6552 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6553 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6555 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6559 if (Op3CE && Op4CE) {
6564 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6570 if (Op3Val >= RegWidth)
6571 return Error(Op3.getStartLoc(),
6572 "expected integer in range [0, 31]");
6573 if (Op4Val < 1 || Op4Val > RegWidth)
6574 return Error(Op4.getStartLoc(),
6575 "expected integer in range [1, 32]");
6579 NewOp3Val = (32 - Op3Val) & 0x1f;
6581 NewOp3Val = (64 - Op3Val) & 0x3f;
6585 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6586 return Error(Op4.getStartLoc(),
6587 "requested insert overflows register");
6589 const MCExpr *NewOp3 =
6591 const MCExpr *NewOp4 =
6593 Operands[3] = AArch64Operand::CreateImm(
6594 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6595 Operands[4] = AArch64Operand::CreateImm(
6596 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6598 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6600 else if (Tok ==
"sbfiz")
6601 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6603 else if (Tok ==
"ubfiz")
6604 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6613 }
else if (NumOperands == 5 &&
6614 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6615 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6616 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6617 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6619 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6623 if (Op3CE && Op4CE) {
6628 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6634 if (Op3Val >= RegWidth)
6635 return Error(Op3.getStartLoc(),
6636 "expected integer in range [0, 31]");
6637 if (Op4Val < 1 || Op4Val > RegWidth)
6638 return Error(Op4.getStartLoc(),
6639 "expected integer in range [1, 32]");
6641 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6643 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6644 return Error(Op4.getStartLoc(),
6645 "requested extract overflows register");
6647 const MCExpr *NewOp4 =
6649 Operands[4] = AArch64Operand::CreateImm(
6650 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6652 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6654 else if (Tok ==
"sbfx")
6655 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6657 else if (Tok ==
"ubfx")
6658 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6671 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6672 NumOperands == 4 && Tok ==
"movi") {
6673 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6674 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6675 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6676 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6677 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6678 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6679 if (Suffix.
lower() ==
".2d" &&
6681 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6682 " correctly on this CPU, converting to equivalent movi.16b");
6684 unsigned Idx = Op1.isToken() ? 1 : 2;
6686 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6694 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6697 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6698 if (
Op.isScalarReg()) {
6700 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6701 Op.getStartLoc(),
Op.getEndLoc(),
6706 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6707 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6708 if (
Op.isScalarReg() &&
6709 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6713 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6714 if (
Op.isScalarReg()) {
6716 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6723 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6724 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6725 if (
Op.isScalarReg() &&
6726 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6730 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6731 if (
Op.isScalarReg()) {
6733 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6741 FeatureBitset MissingFeatures;
6744 unsigned MatchResult =
6745 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6746 MatchingInlineAsm, 1);
6750 if (MatchResult != Match_Success) {
6753 auto ShortFormNEONErrorInfo = ErrorInfo;
6754 auto ShortFormNEONMatchResult = MatchResult;
6755 auto ShortFormNEONMissingFeatures = MissingFeatures;
6758 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6759 MatchingInlineAsm, 0);
6764 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6766 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6767 MatchResult = ShortFormNEONMatchResult;
6768 ErrorInfo = ShortFormNEONErrorInfo;
6769 MissingFeatures = ShortFormNEONMissingFeatures;
6773 switch (MatchResult) {
6774 case Match_Success: {
6778 for (
unsigned i = 1; i < NumOperands; ++i)
6780 if (validateInstruction(Inst, IDLoc, OperandLocs))
6787 case Match_MissingFeature: {
6788 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6791 std::string
Msg =
"instruction requires:";
6792 for (
unsigned Feature : MissingFeatures) {
6798 case Match_MnemonicFail:
6799 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6800 case Match_InvalidOperand: {
6801 SMLoc ErrorLoc = IDLoc;
6803 if (ErrorInfo != ~0ULL) {
6805 return Error(IDLoc,
"too few operands for instruction",
6806 SMRange(IDLoc, getTok().getLoc()));
6808 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6809 if (ErrorLoc == SMLoc())
6814 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6815 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6816 MatchResult = Match_InvalidSuffix;
6818 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6820 case Match_InvalidTiedOperand:
6821 case Match_InvalidMemoryIndexed1:
6822 case Match_InvalidMemoryIndexed2:
6823 case Match_InvalidMemoryIndexed4:
6824 case Match_InvalidMemoryIndexed8:
6825 case Match_InvalidMemoryIndexed16:
6826 case Match_InvalidCondCode:
6827 case Match_AddSubLSLImm3ShiftLarge:
6828 case Match_AddSubRegExtendSmall:
6829 case Match_AddSubRegExtendLarge:
6830 case Match_AddSubSecondSource:
6831 case Match_LogicalSecondSource:
6832 case Match_AddSubRegShift32:
6833 case Match_AddSubRegShift64:
6834 case Match_InvalidMovImm32Shift:
6835 case Match_InvalidMovImm64Shift:
6836 case Match_InvalidFPImm:
6837 case Match_InvalidMemoryWExtend8:
6838 case Match_InvalidMemoryWExtend16:
6839 case Match_InvalidMemoryWExtend32:
6840 case Match_InvalidMemoryWExtend64:
6841 case Match_InvalidMemoryWExtend128:
6842 case Match_InvalidMemoryXExtend8:
6843 case Match_InvalidMemoryXExtend16:
6844 case Match_InvalidMemoryXExtend32:
6845 case Match_InvalidMemoryXExtend64:
6846 case Match_InvalidMemoryXExtend128:
6847 case Match_InvalidMemoryIndexed1SImm4:
6848 case Match_InvalidMemoryIndexed2SImm4:
6849 case Match_InvalidMemoryIndexed3SImm4:
6850 case Match_InvalidMemoryIndexed4SImm4:
6851 case Match_InvalidMemoryIndexed1SImm6:
6852 case Match_InvalidMemoryIndexed16SImm4:
6853 case Match_InvalidMemoryIndexed32SImm4:
6854 case Match_InvalidMemoryIndexed4SImm7:
6855 case Match_InvalidMemoryIndexed8SImm7:
6856 case Match_InvalidMemoryIndexed16SImm7:
6857 case Match_InvalidMemoryIndexed8UImm5:
6858 case Match_InvalidMemoryIndexed8UImm3:
6859 case Match_InvalidMemoryIndexed4UImm5:
6860 case Match_InvalidMemoryIndexed2UImm5:
6861 case Match_InvalidMemoryIndexed1UImm6:
6862 case Match_InvalidMemoryIndexed2UImm6:
6863 case Match_InvalidMemoryIndexed4UImm6:
6864 case Match_InvalidMemoryIndexed8UImm6:
6865 case Match_InvalidMemoryIndexed16UImm6:
6866 case Match_InvalidMemoryIndexedSImm6:
6867 case Match_InvalidMemoryIndexedSImm5:
6868 case Match_InvalidMemoryIndexedSImm8:
6869 case Match_InvalidMemoryIndexedSImm9:
6870 case Match_InvalidMemoryIndexed16SImm9:
6871 case Match_InvalidMemoryIndexed8SImm10:
6872 case Match_InvalidImm0_0:
6873 case Match_InvalidImm0_1:
6874 case Match_InvalidImm0_3:
6875 case Match_InvalidImm0_7:
6876 case Match_InvalidImm0_15:
6877 case Match_InvalidImm0_31:
6878 case Match_InvalidImm0_63:
6879 case Match_InvalidImm0_127:
6880 case Match_InvalidImm0_255:
6881 case Match_InvalidImm0_65535:
6882 case Match_InvalidHinteUImm16:
6883 case Match_InvalidImm1_8:
6884 case Match_InvalidImm1_16:
6885 case Match_InvalidImm1_32:
6886 case Match_InvalidImm1_64:
6887 case Match_InvalidImmM1_62:
6888 case Match_InvalidMemoryIndexedRange2UImm0:
6889 case Match_InvalidMemoryIndexedRange2UImm1:
6890 case Match_InvalidMemoryIndexedRange2UImm2:
6891 case Match_InvalidMemoryIndexedRange2UImm3:
6892 case Match_InvalidMemoryIndexedRange4UImm0:
6893 case Match_InvalidMemoryIndexedRange4UImm1:
6894 case Match_InvalidMemoryIndexedRange4UImm2:
6895 case Match_InvalidSVEAddSubImm8:
6896 case Match_InvalidSVEAddSubImm16:
6897 case Match_InvalidSVEAddSubImm32:
6898 case Match_InvalidSVEAddSubImm64:
6899 case Match_InvalidSVECpyImm8:
6900 case Match_InvalidSVECpyImm16:
6901 case Match_InvalidSVECpyImm32:
6902 case Match_InvalidSVECpyImm64:
6903 case Match_InvalidIndexRange0_0:
6904 case Match_InvalidIndexRange1_1:
6905 case Match_InvalidIndexRange0_15:
6906 case Match_InvalidIndexRange0_7:
6907 case Match_InvalidIndexRange0_3:
6908 case Match_InvalidIndexRange0_1:
6909 case Match_InvalidSVEIndexRange0_63:
6910 case Match_InvalidSVEIndexRange0_31:
6911 case Match_InvalidSVEIndexRange0_15:
6912 case Match_InvalidSVEIndexRange0_7:
6913 case Match_InvalidSVEIndexRange0_3:
6914 case Match_InvalidLabel:
6915 case Match_InvalidComplexRotationEven:
6916 case Match_InvalidComplexRotationOdd:
6917 case Match_InvalidGPR64shifted8:
6918 case Match_InvalidGPR64shifted16:
6919 case Match_InvalidGPR64shifted32:
6920 case Match_InvalidGPR64shifted64:
6921 case Match_InvalidGPR64shifted128:
6922 case Match_InvalidGPR64NoXZRshifted8:
6923 case Match_InvalidGPR64NoXZRshifted16:
6924 case Match_InvalidGPR64NoXZRshifted32:
6925 case Match_InvalidGPR64NoXZRshifted64:
6926 case Match_InvalidGPR64NoXZRshifted128:
6927 case Match_InvalidZPR32UXTW8:
6928 case Match_InvalidZPR32UXTW16:
6929 case Match_InvalidZPR32UXTW32:
6930 case Match_InvalidZPR32UXTW64:
6931 case Match_InvalidZPR32SXTW8:
6932 case Match_InvalidZPR32SXTW16:
6933 case Match_InvalidZPR32SXTW32:
6934 case Match_InvalidZPR32SXTW64:
6935 case Match_InvalidZPR64UXTW8:
6936 case Match_InvalidZPR64SXTW8:
6937 case Match_InvalidZPR64UXTW16:
6938 case Match_InvalidZPR64SXTW16:
6939 case Match_InvalidZPR64UXTW32:
6940 case Match_InvalidZPR64SXTW32:
6941 case Match_InvalidZPR64UXTW64:
6942 case Match_InvalidZPR64SXTW64:
6943 case Match_InvalidZPR32LSL8:
6944 case Match_InvalidZPR32LSL16:
6945 case Match_InvalidZPR32LSL32:
6946 case Match_InvalidZPR32LSL64:
6947 case Match_InvalidZPR64LSL8:
6948 case Match_InvalidZPR64LSL16:
6949 case Match_InvalidZPR64LSL32:
6950 case Match_InvalidZPR64LSL64:
6951 case Match_InvalidZPR0:
6952 case Match_InvalidZPR8:
6953 case Match_InvalidZPR16:
6954 case Match_InvalidZPR32:
6955 case Match_InvalidZPR64:
6956 case Match_InvalidZPR128:
6957 case Match_InvalidZPR_3b8:
6958 case Match_InvalidZPR_3b16:
6959 case Match_InvalidZPR_3b32:
6960 case Match_InvalidZPR_4b8:
6961 case Match_InvalidZPR_4b16:
6962 case Match_InvalidZPR_4b32:
6963 case Match_InvalidZPR_4b64:
6964 case Match_InvalidSVEPPRorPNRAnyReg:
6965 case Match_InvalidSVEPPRorPNRBReg:
6966 case Match_InvalidSVEPredicateAnyReg:
6967 case Match_InvalidSVEPattern:
6968 case Match_InvalidSVEVecLenSpecifier:
6969 case Match_InvalidSVEPredicateBReg:
6970 case Match_InvalidSVEPredicateHReg:
6971 case Match_InvalidSVEPredicateSReg:
6972 case Match_InvalidSVEPredicateDReg:
6973 case Match_InvalidSVEPredicate3bAnyReg:
6974 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6975 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6976 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6977 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6978 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6979 case Match_InvalidSVEPNPredicateBReg:
6980 case Match_InvalidSVEPNPredicateHReg:
6981 case Match_InvalidSVEPNPredicateSReg:
6982 case Match_InvalidSVEPNPredicateDReg:
6983 case Match_InvalidSVEPredicateListMul2x8:
6984 case Match_InvalidSVEPredicateListMul2x16:
6985 case Match_InvalidSVEPredicateListMul2x32:
6986 case Match_InvalidSVEPredicateListMul2x64:
6987 case Match_InvalidSVEExactFPImmOperandHalfOne:
6988 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6989 case Match_InvalidSVEExactFPImmOperandZeroOne:
6990 case Match_InvalidMatrixTile16:
6991 case Match_InvalidMatrixTile32:
6992 case Match_InvalidMatrixTile64:
6993 case Match_InvalidMatrix:
6994 case Match_InvalidMatrix8:
6995 case Match_InvalidMatrix16:
6996 case Match_InvalidMatrix32:
6997 case Match_InvalidMatrix64:
6998 case Match_InvalidMatrixTileVectorH8:
6999 case Match_InvalidMatrixTileVectorH16:
7000 case Match_InvalidMatrixTileVectorH32:
7001 case Match_InvalidMatrixTileVectorH64:
7002 case Match_InvalidMatrixTileVectorH128:
7003 case Match_InvalidMatrixTileVectorV8:
7004 case Match_InvalidMatrixTileVectorV16:
7005 case Match_InvalidMatrixTileVectorV32:
7006 case Match_InvalidMatrixTileVectorV64:
7007 case Match_InvalidMatrixTileVectorV128:
7008 case Match_InvalidSVCR:
7009 case Match_InvalidMatrixIndexGPR32_12_15:
7010 case Match_InvalidMatrixIndexGPR32_8_11:
7011 case Match_InvalidLookupTable:
7012 case Match_InvalidZPRMul2_Lo8:
7013 case Match_InvalidZPRMul2_Hi8:
7014 case Match_InvalidZPRMul2_Lo16:
7015 case Match_InvalidZPRMul2_Hi16:
7016 case Match_InvalidZPRMul2_Lo32:
7017 case Match_InvalidZPRMul2_Hi32:
7018 case Match_InvalidZPRMul2_Lo64:
7019 case Match_InvalidZPRMul2_Hi64:
7020 case Match_InvalidZPR_K0:
7021 case Match_InvalidSVEVectorList2x8Mul2:
7022 case Match_InvalidSVEVectorList2x16Mul2:
7023 case Match_InvalidSVEVectorList2x32Mul2:
7024 case Match_InvalidSVEVectorList2x64Mul2:
7025 case Match_InvalidSVEVectorList2x128Mul2:
7026 case Match_InvalidSVEVectorList4x8Mul4:
7027 case Match_InvalidSVEVectorList4x16Mul4:
7028 case Match_InvalidSVEVectorList4x32Mul4:
7029 case Match_InvalidSVEVectorList4x64Mul4:
7030 case Match_InvalidSVEVectorList4x128Mul4:
7031 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7032 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7033 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7034 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7035 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7036 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7037 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7038 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7039 case Match_InvalidSVEVectorList3x0_3b:
7040 case Match_InvalidSVEVectorListStrided2x8:
7041 case Match_InvalidSVEVectorListStrided2x16:
7042 case Match_InvalidSVEVectorListStrided2x32:
7043 case Match_InvalidSVEVectorListStrided2x64:
7044 case Match_InvalidSVEVectorListStrided4x8:
7045 case Match_InvalidSVEVectorListStrided4x16:
7046 case Match_InvalidSVEVectorListStrided4x32:
7047 case Match_InvalidSVEVectorListStrided4x64:
7051 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
7054 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
7055 if (ErrorLoc == SMLoc())
7057 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7065bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7072 SMLoc Loc = DirectiveID.
getLoc();
7073 if (IDVal ==
".arch")
7074 parseDirectiveArch(Loc);
7075 else if (IDVal ==
".cpu")
7076 parseDirectiveCPU(Loc);
7077 else if (IDVal ==
".tlsdesccall")
7078 parseDirectiveTLSDescCall(Loc);
7079 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7080 parseDirectiveLtorg(Loc);
7081 else if (IDVal ==
".unreq")
7082 parseDirectiveUnreq(Loc);
7083 else if (IDVal ==
".inst")
7084 parseDirectiveInst(Loc);
7085 else if (IDVal ==
".cfi_negate_ra_state")
7086 parseDirectiveCFINegateRAState();
7087 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7088 parseDirectiveCFINegateRAStateWithPC();
7089 else if (IDVal ==
".cfi_set_ra_state")
7090 parseDirectiveCFILLVMSetRAState();
7091 else if (IDVal ==
".cfi_b_key_frame")
7092 parseDirectiveCFIBKeyFrame();
7093 else if (IDVal ==
".cfi_mte_tagged_frame")
7094 parseDirectiveCFIMTETaggedFrame();
7095 else if (IDVal ==
".arch_extension")
7096 parseDirectiveArchExtension(Loc);
7097 else if (IDVal ==
".variant_pcs")
7098 parseDirectiveVariantPCS(Loc);
7101 parseDirectiveLOH(IDVal, Loc);
7104 }
else if (IsCOFF) {
7105 if (IDVal ==
".seh_stackalloc")
7106 parseDirectiveSEHAllocStack(Loc);
7107 else if (IDVal ==
".seh_endprologue")
7108 parseDirectiveSEHPrologEnd(Loc);
7109 else if (IDVal ==
".seh_save_r19r20_x")
7110 parseDirectiveSEHSaveR19R20X(Loc);
7111 else if (IDVal ==
".seh_save_fplr")
7112 parseDirectiveSEHSaveFPLR(Loc);
7113 else if (IDVal ==
".seh_save_fplr_x")
7114 parseDirectiveSEHSaveFPLRX(Loc);
7115 else if (IDVal ==
".seh_save_reg")
7116 parseDirectiveSEHSaveReg(Loc);
7117 else if (IDVal ==
".seh_save_reg_x")
7118 parseDirectiveSEHSaveRegX(Loc);
7119 else if (IDVal ==
".seh_save_regp")
7120 parseDirectiveSEHSaveRegP(Loc);
7121 else if (IDVal ==
".seh_save_regp_x")
7122 parseDirectiveSEHSaveRegPX(Loc);
7123 else if (IDVal ==
".seh_save_lrpair")
7124 parseDirectiveSEHSaveLRPair(Loc);
7125 else if (IDVal ==
".seh_save_freg")
7126 parseDirectiveSEHSaveFReg(Loc);
7127 else if (IDVal ==
".seh_save_freg_x")
7128 parseDirectiveSEHSaveFRegX(Loc);
7129 else if (IDVal ==
".seh_save_fregp")
7130 parseDirectiveSEHSaveFRegP(Loc);
7131 else if (IDVal ==
".seh_save_fregp_x")
7132 parseDirectiveSEHSaveFRegPX(Loc);
7133 else if (IDVal ==
".seh_set_fp")
7134 parseDirectiveSEHSetFP(Loc);
7135 else if (IDVal ==
".seh_add_fp")
7136 parseDirectiveSEHAddFP(Loc);
7137 else if (IDVal ==
".seh_nop")
7138 parseDirectiveSEHNop(Loc);
7139 else if (IDVal ==
".seh_save_next")
7140 parseDirectiveSEHSaveNext(Loc);
7141 else if (IDVal ==
".seh_startepilogue")
7142 parseDirectiveSEHEpilogStart(Loc);
7143 else if (IDVal ==
".seh_endepilogue")
7144 parseDirectiveSEHEpilogEnd(Loc);
7145 else if (IDVal ==
".seh_trap_frame")
7146 parseDirectiveSEHTrapFrame(Loc);
7147 else if (IDVal ==
".seh_pushframe")
7148 parseDirectiveSEHMachineFrame(Loc);
7149 else if (IDVal ==
".seh_context")
7150 parseDirectiveSEHContext(Loc);
7151 else if (IDVal ==
".seh_ec_context")
7152 parseDirectiveSEHECContext(Loc);
7153 else if (IDVal ==
".seh_clear_unwound_to_call")
7154 parseDirectiveSEHClearUnwoundToCall(Loc);
7155 else if (IDVal ==
".seh_pac_sign_lr")
7156 parseDirectiveSEHPACSignLR(Loc);
7157 else if (IDVal ==
".seh_save_any_reg")
7158 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7159 else if (IDVal ==
".seh_save_any_reg_p")
7160 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7161 else if (IDVal ==
".seh_save_any_reg_x")
7162 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7163 else if (IDVal ==
".seh_save_any_reg_px")
7164 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7165 else if (IDVal ==
".seh_allocz")
7166 parseDirectiveSEHAllocZ(Loc);
7167 else if (IDVal ==
".seh_save_zreg")
7168 parseDirectiveSEHSaveZReg(Loc);
7169 else if (IDVal ==
".seh_save_preg")
7170 parseDirectiveSEHSavePReg(Loc);
7174 if (IDVal ==
".aeabi_subsection")
7175 parseDirectiveAeabiSubSectionHeader(Loc);
7176 else if (IDVal ==
".aeabi_attribute")
7177 parseDirectiveAeabiAArch64Attr(Loc);
7190 if (!NoCrypto && Crypto) {
7193 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7194 ArchInfo == AArch64::ARMV8_3A) {
7198 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7199 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7200 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7201 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7202 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7203 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7209 }
else if (NoCrypto) {
7212 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7213 ArchInfo == AArch64::ARMV8_3A) {
7214 RequestedExtensions.
push_back(
"nosha2");
7217 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7218 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7219 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7220 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7221 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7222 ArchInfo == AArch64::ARMV9_4A) {
7224 RequestedExtensions.
push_back(
"nosha3");
7225 RequestedExtensions.
push_back(
"nosha2");
7237bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7238 SMLoc CurLoc = getLoc();
7240 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7241 StringRef Arch, ExtensionString;
7242 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7246 return Error(CurLoc,
"unknown arch name");
7252 std::vector<StringRef> AArch64Features;
7253 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7256 MCSubtargetInfo &STI = copySTI();
7257 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7259 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7262 if (!ExtensionString.
empty())
7263 ExtensionString.
split(RequestedExtensions,
'+');
7268 for (
auto Name : RequestedExtensions) {
7272 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7279 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7287 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7288 setAvailableFeatures(Features);
7290 getTargetStreamer().emitDirectiveArch(Name);
7296bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7297 SMLoc ExtLoc = getLoc();
7299 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7304 bool EnableFeature =
true;
7305 StringRef
Name = FullName;
7306 if (
Name.starts_with_insensitive(
"no")) {
7307 EnableFeature =
false;
7316 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7318 MCSubtargetInfo &STI = copySTI();
7323 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7324 setAvailableFeatures(Features);
7326 getTargetStreamer().emitDirectiveArchExtension(FullName);
7332bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7333 SMLoc CurLoc = getLoc();
7335 StringRef CPU, ExtensionString;
7336 std::tie(CPU, ExtensionString) =
7337 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7343 if (!ExtensionString.
empty())
7344 ExtensionString.
split(RequestedExtensions,
'+');
7348 Error(CurLoc,
"unknown CPU name");
7353 MCSubtargetInfo &STI = copySTI();
7357 for (
auto Name : RequestedExtensions) {
7361 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7368 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7376 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7377 setAvailableFeatures(Features);
7383bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7385 return Error(Loc,
"expected expression following '.inst' directive");
7387 auto parseOp = [&]() ->
bool {
7389 const MCExpr *Expr =
nullptr;
7390 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7393 if (check(!
Value, L,
"expected constant expression"))
7395 getTargetStreamer().emitInst(
Value->getValue());
7399 return parseMany(parseOp);
7404bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7406 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7418 getParser().getStreamer().emitInstruction(Inst, getSTI());
7424bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7428 return TokError(
"expected an identifier or a number in directive");
7431 int64_t
Id = getTok().getIntVal();
7433 return TokError(
"invalid numeric identifier in directive");
7436 StringRef
Name = getTok().getIdentifier();
7442 return TokError(
"invalid identifier in directive");
7450 assert(NbArgs != -1 &&
"Invalid number of arguments");
7453 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7455 if (getParser().parseIdentifier(Name))
7456 return TokError(
"expected identifier in directive");
7459 if (Idx + 1 == NbArgs)
7467 getStreamer().emitLOHDirective(Kind, Args);
7473bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7476 getTargetStreamer().emitCurrentConstantPool();
7482bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7484 SMLoc SRegLoc = getLoc();
7485 RegKind RegisterKind = RegKind::Scalar;
7487 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7491 RegisterKind = RegKind::NeonVector;
7492 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7498 return Error(SRegLoc,
"vector register without type specifier expected");
7503 RegisterKind = RegKind::SVEDataVector;
7505 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7511 return Error(SRegLoc,
7512 "sve vector register without type specifier expected");
7517 RegisterKind = RegKind::SVEPredicateVector;
7518 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7524 return Error(SRegLoc,
7525 "sve predicate register without type specifier expected");
7529 return Error(SRegLoc,
"register name or alias expected");
7535 auto pair = std::make_pair(RegisterKind, RegNum);
7536 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7537 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7544bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7546 return TokError(
"unexpected input in .unreq directive.");
7547 RegisterReqs.
erase(getTok().getIdentifier().lower());
7552bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7555 getStreamer().emitCFINegateRAState();
7559bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7562 getStreamer().emitCFINegateRAStateWithPC();
7569bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7571 if (getParser().parseAbsoluteExpression(State))
7576 SMLoc ExprLoc = getLoc();
7577 if (getParser().parseExpression(Expr))
7582 getStreamer().emitCFILLVMSetRAState(
7583 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7585 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7589 "expected an integer offset or a symbol for .cfi_set_ra_state");
7596bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7599 getStreamer().emitCFIBKeyFrame();
7605bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7608 getStreamer().emitCFIMTETaggedFrame();
7614bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7616 if (getParser().parseIdentifier(Name))
7617 return TokError(
"expected symbol name");
7620 getTargetStreamer().emitDirectiveVariantPCS(
7627bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7629 if (parseImmExpr(
Size))
7631 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7637bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7638 getTargetStreamer().emitARM64WinCFIPrologEnd();
7644bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7646 if (parseImmExpr(
Offset))
7648 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7654bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7656 if (parseImmExpr(
Offset))
7658 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7664bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7666 if (parseImmExpr(
Offset))
7668 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7674bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7677 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7678 parseComma() || parseImmExpr(
Offset))
7680 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7686bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7689 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7690 parseComma() || parseImmExpr(
Offset))
7692 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7698bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7701 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7702 parseComma() || parseImmExpr(
Offset))
7704 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7710bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7713 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7714 parseComma() || parseImmExpr(
Offset))
7716 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7722bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7726 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7727 parseComma() || parseImmExpr(
Offset))
7729 if (check(((
Reg - 19) % 2 != 0), L,
7730 "expected register with even offset from x19"))
7732 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7738bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7741 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7742 parseComma() || parseImmExpr(
Offset))
7744 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7750bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7753 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7754 parseComma() || parseImmExpr(
Offset))
7756 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7762bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7765 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7766 parseComma() || parseImmExpr(
Offset))
7768 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7774bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7777 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7778 parseComma() || parseImmExpr(
Offset))
7780 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7786bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7787 getTargetStreamer().emitARM64WinCFISetFP();
7793bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7795 if (parseImmExpr(
Size))
7797 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7803bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7804 getTargetStreamer().emitARM64WinCFINop();
7810bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7811 getTargetStreamer().emitARM64WinCFISaveNext();
7817bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7818 getTargetStreamer().emitARM64WinCFIEpilogStart();
7824bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7825 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7831bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7832 getTargetStreamer().emitARM64WinCFITrapFrame();
7838bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7839 getTargetStreamer().emitARM64WinCFIMachineFrame();
7845bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7846 getTargetStreamer().emitARM64WinCFIContext();
7852bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7853 getTargetStreamer().emitARM64WinCFIECContext();
7859bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7860 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7866bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7867 getTargetStreamer().emitARM64WinCFIPACSignLR();
7876bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7881 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7882 parseComma() || parseImmExpr(
Offset))
7885 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7886 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7887 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7888 return Error(L,
"invalid save_any_reg offset");
7889 unsigned EncodedReg;
7890 if (
Reg == AArch64::FP)
7892 else if (
Reg == AArch64::LR)
7895 EncodedReg =
Reg - AArch64::X0;
7897 if (
Reg == AArch64::LR)
7898 return Error(Start,
"lr cannot be paired with another register");
7900 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7902 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7905 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7907 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7909 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7910 unsigned EncodedReg =
Reg - AArch64::D0;
7911 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7912 return Error(L,
"invalid save_any_reg offset");
7914 if (
Reg == AArch64::D31)
7915 return Error(Start,
"d31 cannot be paired with another register");
7917 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7919 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7922 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7924 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7926 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7927 unsigned EncodedReg =
Reg - AArch64::Q0;
7929 return Error(L,
"invalid save_any_reg offset");
7931 if (
Reg == AArch64::Q31)
7932 return Error(Start,
"q31 cannot be paired with another register");
7934 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7936 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7939 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7941 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7944 return Error(Start,
"save_any_reg register must be x, q or d register");
7951bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7953 if (parseImmExpr(
Offset))
7955 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7961bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
7966 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7969 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
7970 "expected register in range z8 to z23"))
7972 if (parseComma() || parseImmExpr(
Offset))
7974 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
7980bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
7985 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7988 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
7989 "expected register in range p4 to p15"))
7991 if (parseComma() || parseImmExpr(
Offset))
7993 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
7997bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8003 MCAsmParser &Parser = getParser();
8006 StringRef SubsectionName;
8017 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8018 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8023 if (SubsectionExists) {
8024 getTargetStreamer().emitAttributesSubsection(
8027 SubsectionExists->IsOptional),
8029 SubsectionExists->ParameterType));
8035 "Could not switch to subsection '" + SubsectionName +
8036 "' using subsection name, subsection has not been defined");
8059 if (SubsectionExists) {
8060 if (IsOptional != SubsectionExists->IsOptional) {
8062 "optionality mismatch! subsection '" + SubsectionName +
8063 "' already exists with optionality defined as '" +
8065 SubsectionExists->IsOptional) +
8073 "optionality parameter not found, expected required|optional");
8080 "aeabi_feature_and_bits must be marked as optional");
8087 "aeabi_pauthabi must be marked as required");
8107 if (SubsectionExists) {
8108 if (
Type != SubsectionExists->ParameterType) {
8110 "type mismatch! subsection '" + SubsectionName +
8111 "' already exists with type defined as '" +
8113 SubsectionExists->ParameterType) +
8121 "type parameter not found, expected uleb128|ntbs");
8129 SubsectionName +
" must be marked as ULEB128");
8138 "attributes subsection header directive");
8142 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8147bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8151 MCAsmParser &Parser = getParser();
8153 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8154 getTargetStreamer().getActiveAttributesSubsection();
8155 if (
nullptr == ActiveSubsection) {
8157 "no active subsection, build attribute can not be added");
8160 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8161 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8169 ActiveSubsectionName)
8172 StringRef TagStr =
"";
8175 Tag = getTok().getIntVal();
8178 switch (ActiveSubsectionID) {
8183 "' \nExcept for public subsections, "
8184 "tags have to be an unsigned int.");
8191 TagStr +
"' for subsection '" +
8192 ActiveSubsectionName +
"'");
8200 TagStr +
"' for subsection '" +
8201 ActiveSubsectionName +
"'");
8219 unsigned ValueInt = unsigned(-1);
8220 std::string ValueStr =
"";
8225 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8228 ValueInt = getTok().getIntVal();
8233 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8241 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8252 if (0 != ValueInt && 1 != ValueInt) {
8254 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8255 "' options are 0|1");
8264 "unexpected token for AArch64 build attributes tag and value "
8265 "attribute directive");
8269 if (
unsigned(-1) != ValueInt) {
8270 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8272 if (
"" != ValueStr) {
8273 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8279bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8280 SMLoc Loc = getLoc();
8282 return TokError(
"expected '%' relocation specifier");
8283 StringRef
Identifier = getParser().getTok().getIdentifier();
8286 return TokError(
"invalid relocation specifier");
8292 const MCExpr *SubExpr;
8293 if (getParser().parseParenExpression(SubExpr,
E))
8300bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8303 return parseExprWithSpecifier(Res, EndLoc);
8305 if (getParser().parseExpression(Res))
8307 MCAsmParser &Parser = getParser();
8311 return Error(getLoc(),
"expected relocation specifier");
8314 SMLoc Loc = getLoc();
8316 if (Identifier ==
"auth")
8317 return parseAuthExpr(Res, EndLoc);
8321 if (Identifier ==
"got")
8325 return Error(Loc,
"invalid relocation specifier");
8330 return Error(Loc,
"@ specifier only allowed after a symbol");
8333 std::optional<MCBinaryExpr::Opcode> Opcode;
8341 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8352bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8353 MCAsmParser &Parser = getParser();
8355 AsmToken Tok = Parser.
getTok();
8362 return TokError(
"expected key name");
8367 return TokError(
"invalid key '" + KeyStr +
"'");
8374 return TokError(
"expected integer discriminator");
8378 return TokError(
"integer discriminator " + Twine(Discriminator) +
8379 " out of range [0, 0xFFFF]");
8382 bool UseAddressDiversity =
false;
8387 return TokError(
"expected 'addr'");
8388 UseAddressDiversity =
true;
8397 UseAddressDiversity, Ctx, Res->
getLoc());
8401bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8410 ELFSpec = AE->getSpecifier();
8411 Expr = AE->getSubExpr();
8451#define GET_REGISTER_MATCHER
8452#define GET_SUBTARGET_FEATURE_NAME
8453#define GET_MATCHER_IMPLEMENTATION
8454#define GET_MNEMONIC_SPELL_CHECKER
8455#include "AArch64GenAsmMatcher.inc"
8461 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8463 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8465 return Match_InvalidOperand;
8468 return Match_InvalidOperand;
8469 if (CE->getValue() == ExpectedVal)
8470 return Match_Success;
8471 return Match_InvalidOperand;
8476 return Match_InvalidOperand;
8482 if (
Op.isTokenEqual(
"za"))
8483 return Match_Success;
8484 return Match_InvalidOperand;
8490#define MATCH_HASH(N) \
8491 case MCK__HASH_##N: \
8492 return MatchesOpImmediate(N);
8518#define MATCH_HASH_MINUS(N) \
8519 case MCK__HASH__MINUS_##N: \
8520 return MatchesOpImmediate(-N);
8524#undef MATCH_HASH_MINUS
8533 return Error(S,
"expected register");
8535 MCRegister FirstReg;
8536 ParseStatus Res = tryParseScalarRegister(FirstReg);
8538 return Error(S,
"expected first even register of a consecutive same-size "
8539 "even/odd register pair");
8541 const MCRegisterClass &WRegClass =
8542 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8543 const MCRegisterClass &XRegClass =
8544 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8546 bool isXReg = XRegClass.
contains(FirstReg),
8547 isWReg = WRegClass.
contains(FirstReg);
8548 if (!isXReg && !isWReg)
8549 return Error(S,
"expected first even register of a consecutive same-size "
8550 "even/odd register pair");
8552 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8555 if (FirstEncoding & 0x1)
8556 return Error(S,
"expected first even register of a consecutive same-size "
8557 "even/odd register pair");
8560 return Error(getLoc(),
"expected comma");
8565 MCRegister SecondReg;
8566 Res = tryParseScalarRegister(SecondReg);
8568 return Error(
E,
"expected second odd register of a consecutive same-size "
8569 "even/odd register pair");
8572 (isXReg && !XRegClass.
contains(SecondReg)) ||
8573 (isWReg && !WRegClass.
contains(SecondReg)))
8574 return Error(
E,
"expected second odd register of a consecutive same-size "
8575 "even/odd register pair");
8580 FirstReg, AArch64::sube64,
8581 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8584 FirstReg, AArch64::sube32,
8585 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8588 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8594template <
bool ParseShiftExtend,
bool ParseSuffix>
8596 const SMLoc S = getLoc();
8602 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8607 if (ParseSuffix &&
Kind.empty())
8614 unsigned ElementWidth = KindRes->second;
8618 Operands.push_back(AArch64Operand::CreateVectorReg(
8619 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8621 ParseStatus Res = tryParseVectorIndex(
Operands);
8632 Res = tryParseOptionalShiftExtend(ExtOpnd);
8636 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8637 Operands.push_back(AArch64Operand::CreateVectorReg(
8638 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8639 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8640 Ext->hasShiftExtendAmount()));
8646 MCAsmParser &Parser = getParser();
8648 SMLoc
SS = getLoc();
8649 const AsmToken &TokE = getTok();
8660 const MCExpr *ImmVal;
8667 return TokError(
"invalid operand for instruction");
8672 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8677 Pattern = Pat->Encoding;
8678 assert(Pattern >= 0 && Pattern < 32);
8691 SMLoc
SS = getLoc();
8692 const AsmToken &TokE = getTok();
8694 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8700 Pattern = Pat->Encoding;
8701 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8711 SMLoc
SS = getLoc();
8714 if (!tryParseScalarRegister(XReg).isSuccess())
8720 XReg, AArch64::x8sub_0,
8721 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8724 "expected an even-numbered x-register in the range [x0,x22]");
8727 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8741 if (getParser().parseExpression(ImmF))
8751 SMLoc
E = getTok().getLoc();
8753 if (getParser().parseExpression(ImmL))
8760 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8775 if (getParser().parseExpression(Ex))
8785 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8792 Operands.push_back(AArch64Operand::CreateImm(
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
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.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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)
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
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