72 SVEPredicateAsCounter,
78enum class MatrixKind { Array, Tile, Row, Col };
80enum RegConstraintEqualityTy {
91 StringMap<std::pair<RegKind, MCRegister>> RegisterReqs;
95 static PrefixInfo CreateFromInst(
const MCInst &Inst,
uint64_t TSFlags) {
98 case AArch64::MOVPRFX_ZZ:
102 case AArch64::MOVPRFX_ZPmZ_B:
103 case AArch64::MOVPRFX_ZPmZ_H:
104 case AArch64::MOVPRFX_ZPmZ_S:
105 case AArch64::MOVPRFX_ZPmZ_D:
110 "No destructive element size set for movprfx");
114 case AArch64::MOVPRFX_ZPzZ_B:
115 case AArch64::MOVPRFX_ZPzZ_H:
116 case AArch64::MOVPRFX_ZPzZ_S:
117 case AArch64::MOVPRFX_ZPzZ_D:
122 "No destructive element size set for movprfx");
133 PrefixInfo() =
default;
134 bool isActive()
const {
return Active; }
136 unsigned getElementSize()
const {
140 MCRegister getDstReg()
const {
return Dst; }
141 MCRegister getPgReg()
const {
148 bool Predicated =
false;
149 unsigned ElementSize;
154 AArch64TargetStreamer &getTargetStreamer() {
155 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
156 return static_cast<AArch64TargetStreamer &
>(TS);
159 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
166 std::string &Suggestion);
168 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
170 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
176 bool invertCondCode);
177 bool parseImmExpr(int64_t &Out);
179 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
182 bool showMatchError(SMLoc Loc,
unsigned ErrCode,
uint64_t ErrorInfo,
185 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
186 bool parseDataExpr(
const MCExpr *&Res)
override;
187 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
189 bool parseDirectiveArch(SMLoc L);
190 bool parseDirectiveArchExtension(SMLoc L);
191 bool parseDirectiveCPU(SMLoc L);
192 bool parseDirectiveInst(SMLoc L);
194 bool parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth);
196 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
197 bool parseDirectiveLtorg(SMLoc L);
199 bool parseDirectiveReq(StringRef Name, SMLoc L);
200 bool parseDirectiveUnreq(SMLoc L);
201 bool parseDirectiveCFINegateRAState();
202 bool parseDirectiveCFINegateRAStateWithPC();
203 bool parseDirectiveCFILLVMSetRAState();
204 bool parseDirectiveCFIBKeyFrame();
205 bool parseDirectiveCFIMTETaggedFrame();
207 bool parseDirectiveVariantPCS(SMLoc L);
209 bool parseDirectiveSEHAllocStack(SMLoc L);
210 bool parseDirectiveSEHPrologEnd(SMLoc L);
211 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
212 bool parseDirectiveSEHSaveFPLR(SMLoc L);
213 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
214 bool parseDirectiveSEHSaveReg(SMLoc L);
215 bool parseDirectiveSEHSaveRegX(SMLoc L);
216 bool parseDirectiveSEHSaveRegP(SMLoc L);
217 bool parseDirectiveSEHSaveRegPX(SMLoc L);
218 bool parseDirectiveSEHSaveLRPair(SMLoc L);
219 bool parseDirectiveSEHSaveFReg(SMLoc L);
220 bool parseDirectiveSEHSaveFRegX(SMLoc L);
221 bool parseDirectiveSEHSaveFRegP(SMLoc L);
222 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
223 bool parseDirectiveSEHSetFP(SMLoc L);
224 bool parseDirectiveSEHAddFP(SMLoc L);
225 bool parseDirectiveSEHNop(SMLoc L);
226 bool parseDirectiveSEHSaveNext(SMLoc L);
227 bool parseDirectiveSEHEpilogStart(SMLoc L);
228 bool parseDirectiveSEHEpilogEnd(SMLoc L);
229 bool parseDirectiveSEHTrapFrame(SMLoc L);
230 bool parseDirectiveSEHMachineFrame(SMLoc L);
231 bool parseDirectiveSEHContext(SMLoc L);
232 bool parseDirectiveSEHECContext(SMLoc L);
233 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
234 bool parseDirectiveSEHPACSignLR(SMLoc L);
235 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
236 bool parseDirectiveSEHAllocZ(SMLoc L);
237 bool parseDirectiveSEHSaveZReg(SMLoc L);
238 bool parseDirectiveSEHSavePReg(SMLoc L);
239 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
240 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
242 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
243 SmallVectorImpl<SMLoc> &Loc);
244 unsigned getNumRegsForRegKind(RegKind K);
245 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
248 bool MatchingInlineAsm)
override;
252#define GET_ASSEMBLER_HEADER
253#include "AArch64GenAsmMatcher.inc"
267 template <
bool IsSVEPrefetch = false>
273 template <
bool AddFPZeroAsLiteral>
281 template <
bool ParseShiftExtend,
282 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
285 template <
bool ParseShiftExtend,
bool ParseSuffix>
287 template <RegKind RK>
291 template <RegKind VectorKind>
293 bool ExpectMatch =
false);
301 enum AArch64MatchResultTy {
302 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
303#define GET_OPERAND_DIAGNOSTIC_TYPES
304#include "AArch64GenAsmMatcher.inc"
307 bool IsWindowsArm64EC;
309 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
310 const MCInstrInfo &MII)
311 : MCTargetAsmParser(STI, MII) {
315 MCStreamer &S = getParser().getStreamer();
317 new AArch64TargetStreamer(S);
329 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
332 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
333 const MCParsedAsmOperand &Op2)
const override;
334 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
336 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
337 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
338 SMLoc &EndLoc)
override;
339 bool ParseDirective(AsmToken DirectiveID)
override;
340 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
341 unsigned Kind)
override;
373 SMLoc StartLoc, EndLoc;
382 struct ShiftExtendOp {
385 bool HasExplicitAmount;
395 RegConstraintEqualityTy EqualityTy;
411 ShiftExtendOp ShiftExtend;
416 unsigned ElementWidth;
420 struct MatrixTileListOp {
421 unsigned RegMask = 0;
424 struct VectorListOp {
428 unsigned NumElements;
429 unsigned ElementWidth;
430 RegKind RegisterKind;
433 struct VectorIndexOp {
441 struct ShiftedImmOp {
443 unsigned ShiftAmount;
472 uint32_t PStateField;
485 struct TIndexHintOp {
494 unsigned PStateField;
500 struct MatrixRegOp MatrixReg;
501 struct MatrixTileListOp MatrixTileList;
502 struct VectorListOp VectorList;
503 struct VectorIndexOp VectorIndex;
505 struct ShiftedImmOp ShiftedImm;
506 struct ImmRangeOp ImmRange;
508 struct FPImmOp FPImm;
510 struct SysRegOp SysReg;
511 struct SysCRImmOp SysCRImm;
513 struct TIndexHintOp TIndexHint;
514 struct ShiftExtendOp ShiftExtend;
523 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
525 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
527 StartLoc =
o.StartLoc;
537 ShiftedImm =
o.ShiftedImm;
540 ImmRange =
o.ImmRange;
554 case k_MatrixRegister:
555 MatrixReg =
o.MatrixReg;
557 case k_MatrixTileList:
558 MatrixTileList =
o.MatrixTileList;
561 VectorList =
o.VectorList;
564 VectorIndex =
o.VectorIndex;
570 SysCRImm =
o.SysCRImm;
576 TIndexHint =
o.TIndexHint;
579 ShiftExtend =
o.ShiftExtend;
588 SMLoc getStartLoc()
const override {
return StartLoc; }
590 SMLoc getEndLoc()
const override {
return EndLoc; }
593 assert(Kind == k_Token &&
"Invalid access!");
594 return StringRef(Tok.Data, Tok.Length);
597 bool isTokenSuffix()
const {
598 assert(Kind == k_Token &&
"Invalid access!");
602 const MCExpr *
getImm()
const {
603 assert(Kind == k_Immediate &&
"Invalid access!");
607 const MCExpr *getShiftedImmVal()
const {
608 assert(Kind == k_ShiftedImm &&
"Invalid access!");
609 return ShiftedImm.Val;
612 unsigned getShiftedImmShift()
const {
613 assert(Kind == k_ShiftedImm &&
"Invalid access!");
614 return ShiftedImm.ShiftAmount;
617 unsigned getFirstImmVal()
const {
618 assert(Kind == k_ImmRange &&
"Invalid access!");
619 return ImmRange.First;
622 unsigned getLastImmVal()
const {
623 assert(Kind == k_ImmRange &&
"Invalid access!");
624 return ImmRange.Last;
628 assert(Kind == k_CondCode &&
"Invalid access!");
633 assert (Kind == k_FPImm &&
"Invalid access!");
634 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
637 bool getFPImmIsExact()
const {
638 assert (Kind == k_FPImm &&
"Invalid access!");
639 return FPImm.IsExact;
642 unsigned getBarrier()
const {
643 assert(Kind == k_Barrier &&
"Invalid access!");
647 StringRef getBarrierName()
const {
648 assert(Kind == k_Barrier &&
"Invalid access!");
652 bool getBarriernXSModifier()
const {
653 assert(Kind == k_Barrier &&
"Invalid access!");
657 MCRegister
getReg()
const override {
658 assert(Kind == k_Register &&
"Invalid access!");
662 MCRegister getMatrixReg()
const {
663 assert(Kind == k_MatrixRegister &&
"Invalid access!");
664 return MatrixReg.Reg;
667 unsigned getMatrixElementWidth()
const {
668 assert(Kind == k_MatrixRegister &&
"Invalid access!");
669 return MatrixReg.ElementWidth;
672 MatrixKind getMatrixKind()
const {
673 assert(Kind == k_MatrixRegister &&
"Invalid access!");
674 return MatrixReg.Kind;
677 unsigned getMatrixTileListRegMask()
const {
678 assert(isMatrixTileList() &&
"Invalid access!");
679 return MatrixTileList.RegMask;
682 RegConstraintEqualityTy getRegEqualityTy()
const {
683 assert(Kind == k_Register &&
"Invalid access!");
684 return Reg.EqualityTy;
687 MCRegister getVectorListStart()
const {
688 assert(Kind == k_VectorList &&
"Invalid access!");
689 return VectorList.Reg;
692 unsigned getVectorListCount()
const {
693 assert(Kind == k_VectorList &&
"Invalid access!");
694 return VectorList.Count;
697 unsigned getVectorListStride()
const {
698 assert(Kind == k_VectorList &&
"Invalid access!");
699 return VectorList.Stride;
702 int getVectorIndex()
const {
703 assert(Kind == k_VectorIndex &&
"Invalid access!");
704 return VectorIndex.Val;
707 StringRef getSysReg()
const {
708 assert(Kind == k_SysReg &&
"Invalid access!");
709 return StringRef(SysReg.Data, SysReg.Length);
712 unsigned getSysCR()
const {
713 assert(Kind == k_SysCR &&
"Invalid access!");
717 unsigned getPrefetch()
const {
718 assert(Kind == k_Prefetch &&
"Invalid access!");
722 unsigned getTIndexHint()
const {
723 assert(Kind == k_TIndexHint &&
"Invalid access!");
724 return TIndexHint.Val;
727 StringRef getTIndexHintName()
const {
728 assert(Kind == k_TIndexHint &&
"Invalid access!");
729 return StringRef(TIndexHint.Data, TIndexHint.Length);
732 StringRef getSVCR()
const {
733 assert(Kind == k_SVCR &&
"Invalid access!");
734 return StringRef(SVCR.Data, SVCR.Length);
737 StringRef getPrefetchName()
const {
738 assert(Kind == k_Prefetch &&
"Invalid access!");
743 if (Kind == k_ShiftExtend)
744 return ShiftExtend.Type;
745 if (Kind == k_Register)
746 return Reg.ShiftExtend.Type;
750 unsigned getShiftExtendAmount()
const {
751 if (Kind == k_ShiftExtend)
752 return ShiftExtend.Amount;
753 if (Kind == k_Register)
754 return Reg.ShiftExtend.Amount;
758 bool hasShiftExtendAmount()
const {
759 if (Kind == k_ShiftExtend)
760 return ShiftExtend.HasExplicitAmount;
761 if (Kind == k_Register)
762 return Reg.ShiftExtend.HasExplicitAmount;
766 bool isImm()
const override {
return Kind == k_Immediate; }
767 bool isMem()
const override {
return false; }
769 bool isUImm6()
const {
776 return (Val >= 0 && Val < 64);
779 template <
int W
idth>
bool isSImm()
const {
780 return bool(isSImmScaled<Width, 1>());
783 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
784 return isImmScaled<Bits, Scale>(
true);
787 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
788 DiagnosticPredicate isUImmScaled()
const {
789 if (IsRange && isImmRange() &&
790 (getLastImmVal() != getFirstImmVal() +
Offset))
793 return isImmScaled<Bits, Scale, IsRange>(
false);
796 template <
int Bits,
int Scale,
bool IsRange = false>
797 DiagnosticPredicate isImmScaled(
bool Signed)
const {
798 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
799 (isImmRange() && !IsRange))
804 Val = getFirstImmVal();
812 int64_t MinVal, MaxVal;
814 int64_t Shift =
Bits - 1;
815 MinVal = (int64_t(1) << Shift) * -Scale;
816 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
819 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
822 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
828 DiagnosticPredicate isSVEPattern()
const {
835 if (Val >= 0 && Val < 32)
840 DiagnosticPredicate isSVEVecLenSpecifier()
const {
847 if (Val >= 0 && Val <= 1)
852 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
856 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
885 template <
int Scale>
bool isUImm12Offset()
const {
891 return isSymbolicUImm12Offset(
getImm());
894 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
897 template <
int N,
int M>
898 bool isImmInRange()
const {
905 return (Val >=
N && Val <= M);
908 bool isHinteUImm16()
const {
915 return Val >= 0 && Val <= 65535 &&
916 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
921 template <
typename T>
922 bool isLogicalImm()
const {
939 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
941 bool isImmRange()
const {
return Kind == k_ImmRange; }
946 template <
unsigned W
idth>
947 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
948 if (isShiftedImm() && Width == getShiftedImmShift())
950 return std::make_pair(
CE->getValue(), Width);
954 int64_t Val =
CE->getValue();
956 return std::make_pair(Val >> Width, Width);
958 return std::make_pair(Val, 0u);
964 bool isAddSubImm()
const {
965 if (!isShiftedImm() && !isImm())
971 if (isShiftedImm()) {
972 unsigned Shift = ShiftedImm.ShiftAmount;
973 Expr = ShiftedImm.Val;
974 if (Shift != 0 && Shift != 12)
983 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
999 if (
auto ShiftedVal = getShiftedVal<12>())
1000 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1007 bool isAddSubImmNeg()
const {
1008 if (!isShiftedImm() && !isImm())
1012 if (
auto ShiftedVal = getShiftedVal<12>())
1013 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1023 template <
typename T>
1024 DiagnosticPredicate isSVECpyImm()
const {
1028 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1029 std::is_same<int8_t, T>::value;
1030 if (
auto ShiftedImm = getShiftedVal<8>())
1031 if (!(IsByte && ShiftedImm->second) &&
1033 << ShiftedImm->second))
1042 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1046 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1047 std::is_same<int8_t, T>::value;
1048 if (
auto ShiftedImm = getShiftedVal<8>())
1049 if (!(IsByte && ShiftedImm->second) &&
1051 << ShiftedImm->second))
1057 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1058 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1063 bool isCondCode()
const {
return Kind == k_CondCode; }
1065 bool isSIMDImmType10()
const {
1075 bool isBranchTarget()
const {
1084 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1085 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1095 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1105 bool isMovWSymbolG3()
const {
1109 bool isMovWSymbolG2()
const {
1116 bool isMovWSymbolG1()
const {
1124 bool isMovWSymbolG0()
const {
1132 template<
int RegW
idth,
int Shift>
1133 bool isMOVZMovAlias()
const {
1134 if (!isImm())
return false;
1147 template<
int RegW
idth,
int Shift>
1148 bool isMOVNMovAlias()
const {
1149 if (!isImm())
return false;
1152 if (!CE)
return false;
1158 bool isFPImm()
const {
1159 return Kind == k_FPImm &&
1163 bool isBarrier()
const {
1164 return Kind == k_Barrier && !getBarriernXSModifier();
1166 bool isBarriernXS()
const {
1167 return Kind == k_Barrier && getBarriernXSModifier();
1169 bool isSysReg()
const {
return Kind == k_SysReg; }
1171 bool isMRSSystemRegister()
const {
1172 if (!isSysReg())
return false;
1174 return SysReg.MRSReg != -1U;
1177 bool isMSRSystemRegister()
const {
1178 if (!isSysReg())
return false;
1179 return SysReg.MSRReg != -1U;
1182 bool isSystemPStateFieldWithImm0_1()
const {
1183 if (!isSysReg())
return false;
1184 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1187 bool isSystemPStateFieldWithImm0_15()
const {
1190 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1193 bool isSVCR()
const {
1196 return SVCR.PStateField != -1U;
1199 bool isReg()
const override {
1200 return Kind == k_Register;
1203 bool isVectorList()
const {
return Kind == k_VectorList; }
1205 bool isScalarReg()
const {
1206 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1209 bool isNeonVectorReg()
const {
1210 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1213 bool isNeonVectorRegLo()
const {
1214 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1215 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1216 .contains(
Reg.Reg) ||
1217 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1218 .contains(
Reg.Reg));
1221 bool isNeonVectorReg0to7()
const {
1222 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1223 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1224 .contains(
Reg.Reg));
1227 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1228 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1230 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1233 case AArch64::PPRRegClassID:
1234 case AArch64::PPR_3bRegClassID:
1235 case AArch64::PPR_p8to15RegClassID:
1236 case AArch64::PNRRegClassID:
1237 case AArch64::PNR_p8to15RegClassID:
1238 case AArch64::PPRorPNRRegClassID:
1239 RK = RegKind::SVEPredicateAsCounter;
1245 return (Kind == k_Register &&
Reg.Kind == RK) &&
1246 getAArch64MCRegisterClass(Class).contains(
getReg());
1249 template <
unsigned Class>
bool isSVEVectorReg()
const {
1252 case AArch64::ZPRRegClassID:
1253 case AArch64::ZPR_3bRegClassID:
1254 case AArch64::ZPR_4bRegClassID:
1255 case AArch64::ZPRMul2_LoRegClassID:
1256 case AArch64::ZPRMul2_HiRegClassID:
1257 case AArch64::ZPR_KRegClassID:
1258 RK = RegKind::SVEDataVector;
1260 case AArch64::PPRRegClassID:
1261 case AArch64::PPR_3bRegClassID:
1262 case AArch64::PPR_p8to15RegClassID:
1263 case AArch64::PNRRegClassID:
1264 case AArch64::PNR_p8to15RegClassID:
1265 case AArch64::PPRorPNRRegClassID:
1266 RK = RegKind::SVEPredicateVector;
1272 return (Kind == k_Register &&
Reg.Kind == RK) &&
1273 getAArch64MCRegisterClass(Class).contains(
getReg());
1276 template <
unsigned Class>
bool isFPRasZPR()
const {
1277 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1278 getAArch64MCRegisterClass(Class).contains(
getReg());
1281 template <
int ElementW
idth,
unsigned Class>
1282 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1283 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1286 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1292 template <
int ElementW
idth,
unsigned Class>
1293 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1294 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1295 Reg.Kind != RegKind::SVEPredicateVector))
1298 if ((isSVEPredicateAsCounterReg<Class>() ||
1299 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1300 Reg.ElementWidth == ElementWidth)
1306 template <
int ElementW
idth,
unsigned Class>
1307 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1308 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1311 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1317 template <
int ElementW
idth,
unsigned Class>
1318 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1319 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1322 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1328 template <
int ElementWidth,
unsigned Class,
1330 bool ShiftWidthAlwaysSame>
1331 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1332 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1333 if (!VectorMatch.isMatch())
1339 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1342 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1345 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1351 bool isGPR32as64()
const {
1352 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1353 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1357 bool isGPR64as32()
const {
1358 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1359 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1363 bool isGPR64x8()
const {
1364 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1365 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1369 bool isWSeqPair()
const {
1370 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1371 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1375 bool isXSeqPair()
const {
1376 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1377 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1381 bool isSyspXzrPair()
const {
1385 template<
int64_t Angle,
int64_t Remainder>
1386 DiagnosticPredicate isComplexRotation()
const {
1395 if (
Value % Angle == Remainder &&
Value <= 270)
1400 template <
unsigned RegClassID>
bool isGPR64()
const {
1401 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1402 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1405 template <
unsigned RegClassID,
int ExtW
idth>
1406 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1407 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1411 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1418 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1419 bool isImplicitlyTypedVectorList()
const {
1420 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1421 VectorList.NumElements == 0 &&
1423 (!IsConsecutive || (VectorList.Stride == 1));
1426 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1427 unsigned ElementWidth,
unsigned Stride = 1>
1428 bool isTypedVectorList()
const {
1429 if (Kind != k_VectorList)
1431 if (VectorList.Count != NumRegs)
1433 if (VectorList.RegisterKind != VectorKind)
1435 if (VectorList.ElementWidth != ElementWidth)
1437 if (VectorList.Stride != Stride)
1439 return VectorList.NumElements == NumElements;
1442 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1443 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1445 DiagnosticPredicate isTypedVectorListInRange()
const {
1447 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1450 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1451 (VectorList.Reg - FirstReg) % Multiple != 0)
1456 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned Stride,
1457 unsigned ElementWidth>
1458 DiagnosticPredicate isTypedVectorListStrided()
const {
1459 bool Res = isTypedVectorList<
VectorKind, NumRegs, 0,
1460 ElementWidth, Stride>();
1463 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1464 ((VectorList.Reg >= AArch64::Z16) &&
1465 (VectorList.Reg < (AArch64::Z16 + Stride))))
1470 template <
int Min,
int Max>
1471 DiagnosticPredicate isVectorIndex()
const {
1472 if (Kind != k_VectorIndex)
1474 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1479 bool isToken()
const override {
return Kind == k_Token; }
1481 bool isTokenEqual(StringRef Str)
const {
1482 return Kind == k_Token &&
getToken() == Str;
1484 bool isSysCR()
const {
return Kind == k_SysCR; }
1485 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1486 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1487 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1488 bool isShifter()
const {
1489 if (!isShiftExtend())
1498 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1499 if (Kind != k_FPImm)
1502 if (getFPImmIsExact()) {
1504 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1506 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1509 APFloat RealVal(APFloat::IEEEdouble());
1511 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1512 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1515 if (
getFPImm().bitwiseIsEqual(RealVal))
1522 template <
unsigned ImmA,
unsigned ImmB>
1523 DiagnosticPredicate isExactFPImm()
const {
1525 if ((Res = isExactFPImm<ImmA>()))
1527 if ((Res = isExactFPImm<ImmB>()))
1532 bool isExtend()
const {
1533 if (!isShiftExtend())
1542 getShiftExtendAmount() <= 4;
1545 bool isExtend64()
const {
1555 bool isExtendLSL64()
const {
1561 getShiftExtendAmount() <= 4;
1564 bool isLSLImm3Shift()
const {
1565 if (!isShiftExtend())
1571 template<
int W
idth>
bool isMemXExtend()
const {
1576 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1577 getShiftExtendAmount() == 0);
1580 template<
int W
idth>
bool isMemWExtend()
const {
1585 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1586 getShiftExtendAmount() == 0);
1589 template <
unsigned w
idth>
1590 bool isArithmeticShifter()
const {
1600 template <
unsigned w
idth>
1601 bool isLogicalShifter()
const {
1609 getShiftExtendAmount() < width;
1612 bool isMovImm32Shifter()
const {
1620 uint64_t Val = getShiftExtendAmount();
1621 return (Val == 0 || Val == 16);
1624 bool isMovImm64Shifter()
const {
1632 uint64_t Val = getShiftExtendAmount();
1633 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1636 bool isLogicalVecShifter()
const {
1641 unsigned Shift = getShiftExtendAmount();
1643 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1646 bool isLogicalVecHalfWordShifter()
const {
1647 if (!isLogicalVecShifter())
1651 unsigned Shift = getShiftExtendAmount();
1653 (Shift == 0 || Shift == 8);
1656 bool isMoveVecShifter()
const {
1657 if (!isShiftExtend())
1661 unsigned Shift = getShiftExtendAmount();
1663 (Shift == 8 || Shift == 16);
1672 bool isSImm9OffsetFB()
const {
1673 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1676 bool isAdrpLabel()
const {
1683 int64_t Val =
CE->getValue();
1684 int64_t Min = - (4096 * (1LL << (21 - 1)));
1685 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1686 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1692 bool isAdrLabel()
const {
1699 int64_t Val =
CE->getValue();
1700 int64_t Min = - (1LL << (21 - 1));
1701 int64_t
Max = ((1LL << (21 - 1)) - 1);
1702 return Val >= Min && Val <=
Max;
1708 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1709 DiagnosticPredicate isMatrixRegOperand()
const {
1712 if (getMatrixKind() != Kind ||
1713 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1714 EltSize != getMatrixElementWidth())
1719 bool isPAuthPCRelLabel16Operand()
const {
1731 return (Val <= 0) && (Val > -(1 << 18));
1734 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1744 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1745 assert(
N == 1 &&
"Invalid number of operands!");
1749 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1750 assert(
N == 1 &&
"Invalid number of operands!");
1754 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1755 assert(
N == 1 &&
"Invalid number of operands!");
1757 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1759 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1766 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1767 assert(
N == 1 &&
"Invalid number of operands!");
1769 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1771 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1778 template <
int W
idth>
1779 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1782 case 8:
Base = AArch64::B0;
break;
1783 case 16:
Base = AArch64::H0;
break;
1784 case 32:
Base = AArch64::S0;
break;
1785 case 64:
Base = AArch64::D0;
break;
1786 case 128:
Base = AArch64::Q0;
break;
1793 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1794 assert(
N == 1 &&
"Invalid number of operands!");
1797 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1798 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1802 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1803 assert(
N == 1 &&
"Invalid number of operands!");
1808 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1809 assert(
N == 1 &&
"Invalid number of operands!");
1810 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1815 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1816 assert(
N == 1 &&
"Invalid number of operands!");
1817 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1822 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1823 assert(
N == 1 &&
"Invalid number of operands!");
1827 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1828 assert(
N == 1 &&
"Invalid number of operands!");
1832 enum VecListIndexType {
1833 VecListIdx_DReg = 0,
1834 VecListIdx_QReg = 1,
1835 VecListIdx_ZReg = 2,
1836 VecListIdx_PReg = 3,
1839 template <VecListIndexType RegTy,
unsigned NumRegs,
1840 bool IsConsecutive =
false>
1841 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1842 assert(
N == 1 &&
"Invalid number of operands!");
1843 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1844 "Expected consecutive registers");
1845 static const unsigned FirstRegs[][5] = {
1847 AArch64::D0, AArch64::D0_D1,
1848 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1850 AArch64::Q0, AArch64::Q0_Q1,
1851 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1853 AArch64::Z0, AArch64::Z0_Z1,
1854 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1856 AArch64::P0, AArch64::P0_P1 }
1859 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1860 " NumRegs must be <= 4 for ZRegs");
1862 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1863 " NumRegs must be <= 2 for PRegs");
1865 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1867 FirstRegs[(
unsigned)RegTy][0]));
1870 template <
unsigned NumRegs>
1871 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1872 assert(
N == 1 &&
"Invalid number of operands!");
1873 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1877 if (getVectorListStart() < AArch64::Z16) {
1878 assert((getVectorListStart() < AArch64::Z8) &&
1879 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1881 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1883 assert((getVectorListStart() < AArch64::Z24) &&
1884 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1886 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1890 if (getVectorListStart() < AArch64::Z16) {
1891 assert((getVectorListStart() < AArch64::Z4) &&
1892 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1894 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1896 assert((getVectorListStart() < AArch64::Z20) &&
1897 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1899 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1907 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1908 assert(
N == 1 &&
"Invalid number of operands!");
1909 unsigned RegMask = getMatrixTileListRegMask();
1910 assert(RegMask <= 0xFF &&
"Invalid mask!");
1914 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1915 assert(
N == 1 &&
"Invalid number of operands!");
1919 template <
unsigned ImmIs0,
unsigned ImmIs1>
1920 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1921 assert(
N == 1 &&
"Invalid number of operands!");
1922 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1926 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1927 assert(
N == 1 &&
"Invalid number of operands!");
1934 template <
int Adj>
void addAdjImmOperands(MCInst &Inst,
unsigned N)
const {
1935 assert(
N == 1 &&
"Invalid number of operands!");
1940 template <
int Shift>
1941 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1942 assert(
N == 2 &&
"Invalid number of operands!");
1943 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1946 }
else if (isShiftedImm()) {
1947 addExpr(Inst, getShiftedImmVal());
1955 template <
int Shift>
1956 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1957 assert(
N == 2 &&
"Invalid number of operands!");
1958 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1965 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1966 assert(
N == 1 &&
"Invalid number of operands!");
1970 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1971 assert(
N == 1 &&
"Invalid number of operands!");
1979 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1980 addImmOperands(Inst,
N);
1984 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1985 assert(
N == 1 &&
"Invalid number of operands!");
1995 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1996 assert(
N == 1 &&
"Invalid number of operands!");
2001 template <
int Scale>
2002 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2003 assert(
N == 1 &&
"Invalid number of operands!");
2008 template <
int Scale>
2009 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2010 assert(
N == 1 &&
"Invalid number of operands!");
2014 template <
typename T>
2015 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2016 assert(
N == 1 &&
"Invalid number of operands!");
2018 std::make_unsigned_t<T> Val = MCE->
getValue();
2023 template <
typename T>
2024 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2025 assert(
N == 1 &&
"Invalid number of operands!");
2027 std::make_unsigned_t<T> Val = ~MCE->getValue();
2032 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2033 assert(
N == 1 &&
"Invalid number of operands!");
2039 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2043 assert(
N == 1 &&
"Invalid number of operands!");
2049 assert(MCE &&
"Invalid constant immediate operand!");
2053 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2057 assert(
N == 1 &&
"Invalid number of operands!");
2066 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2070 assert(
N == 1 &&
"Invalid number of operands!");
2076 assert(MCE &&
"Invalid constant immediate operand!");
2080 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2084 assert(
N == 1 &&
"Invalid number of operands!");
2090 assert(MCE &&
"Invalid constant immediate operand!");
2094 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2098 assert(
N == 1 &&
"Invalid number of operands!");
2104 assert(MCE &&
"Invalid constant immediate operand!");
2108 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2109 assert(
N == 1 &&
"Invalid number of operands!");
2114 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2115 assert(
N == 1 &&
"Invalid number of operands!");
2119 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2120 assert(
N == 1 &&
"Invalid number of operands!");
2124 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2125 assert(
N == 1 &&
"Invalid number of operands!");
2130 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2131 assert(
N == 1 &&
"Invalid number of operands!");
2136 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2137 assert(
N == 1 &&
"Invalid number of operands!");
2142 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2143 assert(
N == 1 &&
"Invalid number of operands!");
2148 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2149 assert(
N == 1 &&
"Invalid number of operands!");
2154 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2155 assert(
N == 1 &&
"Invalid number of operands!");
2159 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2160 assert(
N == 1 &&
"Invalid number of operands!");
2164 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2165 assert(
N == 1 &&
"Invalid number of operands!");
2169 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2170 assert(
N == 1 &&
"Invalid number of operands!");
2176 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2177 assert(
N == 1 &&
"Invalid number of operands!");
2178 unsigned Imm = getShiftExtendAmount();
2182 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2183 assert(
N == 1 &&
"Invalid number of operands!");
2188 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2191 if (
Reg != AArch64::XZR)
2197 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2198 assert(
N == 1 &&
"Invalid number of operands!");
2205 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2206 assert(
N == 1 &&
"Invalid number of operands!");
2213 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2214 assert(
N == 2 &&
"Invalid number of operands!");
2225 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2226 assert(
N == 2 &&
"Invalid number of operands!");
2234 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2235 assert(
N == 1 &&
"Invalid number of operands!");
2247 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2248 assert(
N == 1 &&
"Invalid number of operands!");
2255 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2256 assert(
N == 1 &&
"Invalid number of operands!");
2261 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2262 assert(
N == 1 &&
"Invalid number of operands!");
2267 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2269 static std::unique_ptr<AArch64Operand>
2270 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2271 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2272 Op->Tok.Data = Str.data();
2273 Op->Tok.Length = Str.size();
2274 Op->Tok.IsSuffix = IsSuffix;
2280 static std::unique_ptr<AArch64Operand>
2281 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2282 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2284 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2285 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2287 Op->Reg.Kind = Kind;
2288 Op->Reg.ElementWidth = 0;
2289 Op->Reg.EqualityTy = EqTy;
2290 Op->Reg.ShiftExtend.Type = ExtTy;
2291 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2292 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2298 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2299 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2301 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2302 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2303 Kind == RegKind::SVEPredicateVector ||
2304 Kind == RegKind::SVEPredicateAsCounter) &&
2305 "Invalid vector kind");
2306 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2308 Op->Reg.ElementWidth = ElementWidth;
2312 static std::unique_ptr<AArch64Operand>
2313 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2314 unsigned NumElements,
unsigned ElementWidth,
2315 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2316 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2317 Op->VectorList.Reg =
Reg;
2319 Op->VectorList.Stride = Stride;
2320 Op->VectorList.NumElements = NumElements;
2321 Op->VectorList.ElementWidth = ElementWidth;
2322 Op->VectorList.RegisterKind = RegisterKind;
2328 static std::unique_ptr<AArch64Operand>
2329 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2330 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2331 Op->VectorIndex.Val =
Idx;
2337 static std::unique_ptr<AArch64Operand>
2338 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2339 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2340 Op->MatrixTileList.RegMask = RegMask;
2346 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2347 const unsigned ElementWidth) {
2348 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2350 {{0, AArch64::ZAB0},
2351 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2352 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2353 {{8, AArch64::ZAB0},
2354 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2355 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2356 {{16, AArch64::ZAH0},
2357 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2358 {{16, AArch64::ZAH1},
2359 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2360 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2361 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2362 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2363 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2366 if (ElementWidth == 64)
2369 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2370 assert(!Regs.empty() &&
"Invalid tile or element width!");
2375 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2376 SMLoc
E, MCContext &Ctx) {
2377 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2384 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2385 unsigned ShiftAmount,
2388 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2389 Op->ShiftedImm .Val = Val;
2390 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2396 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2397 unsigned Last, SMLoc S,
2400 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2402 Op->ImmRange.Last =
Last;
2407 static std::unique_ptr<AArch64Operand>
2409 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2410 Op->CondCode.Code =
Code;
2416 static std::unique_ptr<AArch64Operand>
2417 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2418 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2420 Op->FPImm.IsExact = IsExact;
2426 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2430 bool HasnXSModifier) {
2431 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2432 Op->Barrier.Val = Val;
2433 Op->Barrier.Data = Str.data();
2434 Op->Barrier.Length = Str.size();
2435 Op->Barrier.HasnXSModifier = HasnXSModifier;
2441 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2444 uint32_t PStateField,
2446 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2447 Op->SysReg.Data = Str.data();
2448 Op->SysReg.Length = Str.size();
2449 Op->SysReg.MRSReg = MRSReg;
2450 Op->SysReg.MSRReg = MSRReg;
2451 Op->SysReg.PStateField = PStateField;
2457 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2458 SMLoc
E, MCContext &Ctx) {
2459 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2460 Op->SysCRImm.Val = Val;
2466 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2470 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2471 Op->Prefetch.Val = Val;
2472 Op->Barrier.Data = Str.data();
2473 Op->Barrier.Length = Str.size();
2479 static std::unique_ptr<AArch64Operand>
2480 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2481 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2482 Op->TIndexHint.Val = Val;
2483 Op->TIndexHint.Data = Str.data();
2484 Op->TIndexHint.Length = Str.size();
2490 static std::unique_ptr<AArch64Operand>
2491 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2492 SMLoc S, SMLoc
E, MCContext &Ctx) {
2493 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2494 Op->MatrixReg.Reg =
Reg;
2495 Op->MatrixReg.ElementWidth = ElementWidth;
2496 Op->MatrixReg.Kind = Kind;
2502 static std::unique_ptr<AArch64Operand>
2503 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2504 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2505 Op->SVCR.PStateField = PStateField;
2506 Op->SVCR.Data = Str.data();
2507 Op->SVCR.Length = Str.size();
2513 static std::unique_ptr<AArch64Operand>
2515 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2516 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2517 Op->ShiftExtend.Type = ShOp;
2518 Op->ShiftExtend.Amount = Val;
2519 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2531 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2532 if (!getFPImmIsExact())
2537 StringRef
Name = getBarrierName();
2539 OS <<
"<barrier " <<
Name <<
">";
2541 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2547 case k_ShiftedImm: {
2548 unsigned Shift = getShiftedImmShift();
2549 OS <<
"<shiftedimm ";
2556 OS << getFirstImmVal();
2557 OS <<
":" << getLastImmVal() <<
">";
2563 case k_VectorList: {
2564 OS <<
"<vectorlist ";
2565 MCRegister
Reg = getVectorListStart();
2566 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2567 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2572 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2575 OS <<
"<sysreg: " << getSysReg() <<
'>';
2581 OS <<
"c" << getSysCR();
2584 StringRef
Name = getPrefetchName();
2586 OS <<
"<prfop " <<
Name <<
">";
2588 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2592 OS << getTIndexHintName();
2594 case k_MatrixRegister:
2595 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2597 case k_MatrixTileList: {
2598 OS <<
"<matrixlist ";
2599 unsigned RegMask = getMatrixTileListRegMask();
2600 unsigned MaxBits = 8;
2601 for (
unsigned I = MaxBits;
I > 0; --
I)
2602 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2611 OS <<
"<register " <<
getReg().
id() <<
">";
2612 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2617 << getShiftExtendAmount();
2618 if (!hasShiftExtendAmount())
2634 .
Case(
"v0", AArch64::Q0)
2635 .
Case(
"v1", AArch64::Q1)
2636 .
Case(
"v2", AArch64::Q2)
2637 .
Case(
"v3", AArch64::Q3)
2638 .
Case(
"v4", AArch64::Q4)
2639 .
Case(
"v5", AArch64::Q5)
2640 .
Case(
"v6", AArch64::Q6)
2641 .
Case(
"v7", AArch64::Q7)
2642 .
Case(
"v8", AArch64::Q8)
2643 .
Case(
"v9", AArch64::Q9)
2644 .
Case(
"v10", AArch64::Q10)
2645 .
Case(
"v11", AArch64::Q11)
2646 .
Case(
"v12", AArch64::Q12)
2647 .
Case(
"v13", AArch64::Q13)
2648 .
Case(
"v14", AArch64::Q14)
2649 .
Case(
"v15", AArch64::Q15)
2650 .
Case(
"v16", AArch64::Q16)
2651 .
Case(
"v17", AArch64::Q17)
2652 .
Case(
"v18", AArch64::Q18)
2653 .
Case(
"v19", AArch64::Q19)
2654 .
Case(
"v20", AArch64::Q20)
2655 .
Case(
"v21", AArch64::Q21)
2656 .
Case(
"v22", AArch64::Q22)
2657 .
Case(
"v23", AArch64::Q23)
2658 .
Case(
"v24", AArch64::Q24)
2659 .
Case(
"v25", AArch64::Q25)
2660 .
Case(
"v26", AArch64::Q26)
2661 .
Case(
"v27", AArch64::Q27)
2662 .
Case(
"v28", AArch64::Q28)
2663 .
Case(
"v29", AArch64::Q29)
2664 .
Case(
"v30", AArch64::Q30)
2665 .
Case(
"v31", AArch64::Q31)
2674 RegKind VectorKind) {
2675 std::pair<int, int> Res = {-1, -1};
2677 switch (VectorKind) {
2678 case RegKind::NeonVector:
2681 .Case(
".1d", {1, 64})
2682 .Case(
".1q", {1, 128})
2684 .Case(
".2h", {2, 16})
2685 .Case(
".2b", {2, 8})
2686 .Case(
".2s", {2, 32})
2687 .Case(
".2d", {2, 64})
2690 .Case(
".4b", {4, 8})
2691 .Case(
".4h", {4, 16})
2692 .Case(
".4s", {4, 32})
2693 .Case(
".8b", {8, 8})
2694 .Case(
".8h", {8, 16})
2695 .Case(
".16b", {16, 8})
2700 .Case(
".h", {0, 16})
2701 .Case(
".s", {0, 32})
2702 .Case(
".d", {0, 64})
2705 case RegKind::SVEPredicateAsCounter:
2706 case RegKind::SVEPredicateVector:
2707 case RegKind::SVEDataVector:
2708 case RegKind::Matrix:
2712 .Case(
".h", {0, 16})
2713 .Case(
".s", {0, 32})
2714 .Case(
".d", {0, 64})
2715 .Case(
".q", {0, 128})
2722 if (Res == std::make_pair(-1, -1))
2723 return std::nullopt;
2725 return std::optional<std::pair<int, int>>(Res);
2734 .
Case(
"z0", AArch64::Z0)
2735 .
Case(
"z1", AArch64::Z1)
2736 .
Case(
"z2", AArch64::Z2)
2737 .
Case(
"z3", AArch64::Z3)
2738 .
Case(
"z4", AArch64::Z4)
2739 .
Case(
"z5", AArch64::Z5)
2740 .
Case(
"z6", AArch64::Z6)
2741 .
Case(
"z7", AArch64::Z7)
2742 .
Case(
"z8", AArch64::Z8)
2743 .
Case(
"z9", AArch64::Z9)
2744 .
Case(
"z10", AArch64::Z10)
2745 .
Case(
"z11", AArch64::Z11)
2746 .
Case(
"z12", AArch64::Z12)
2747 .
Case(
"z13", AArch64::Z13)
2748 .
Case(
"z14", AArch64::Z14)
2749 .
Case(
"z15", AArch64::Z15)
2750 .
Case(
"z16", AArch64::Z16)
2751 .
Case(
"z17", AArch64::Z17)
2752 .
Case(
"z18", AArch64::Z18)
2753 .
Case(
"z19", AArch64::Z19)
2754 .
Case(
"z20", AArch64::Z20)
2755 .
Case(
"z21", AArch64::Z21)
2756 .
Case(
"z22", AArch64::Z22)
2757 .
Case(
"z23", AArch64::Z23)
2758 .
Case(
"z24", AArch64::Z24)
2759 .
Case(
"z25", AArch64::Z25)
2760 .
Case(
"z26", AArch64::Z26)
2761 .
Case(
"z27", AArch64::Z27)
2762 .
Case(
"z28", AArch64::Z28)
2763 .
Case(
"z29", AArch64::Z29)
2764 .
Case(
"z30", AArch64::Z30)
2765 .
Case(
"z31", AArch64::Z31)
2771 .
Case(
"p0", AArch64::P0)
2772 .
Case(
"p1", AArch64::P1)
2773 .
Case(
"p2", AArch64::P2)
2774 .
Case(
"p3", AArch64::P3)
2775 .
Case(
"p4", AArch64::P4)
2776 .
Case(
"p5", AArch64::P5)
2777 .
Case(
"p6", AArch64::P6)
2778 .
Case(
"p7", AArch64::P7)
2779 .
Case(
"p8", AArch64::P8)
2780 .
Case(
"p9", AArch64::P9)
2781 .
Case(
"p10", AArch64::P10)
2782 .
Case(
"p11", AArch64::P11)
2783 .
Case(
"p12", AArch64::P12)
2784 .
Case(
"p13", AArch64::P13)
2785 .
Case(
"p14", AArch64::P14)
2786 .
Case(
"p15", AArch64::P15)
2792 .
Case(
"pn0", AArch64::PN0)
2793 .
Case(
"pn1", AArch64::PN1)
2794 .
Case(
"pn2", AArch64::PN2)
2795 .
Case(
"pn3", AArch64::PN3)
2796 .
Case(
"pn4", AArch64::PN4)
2797 .
Case(
"pn5", AArch64::PN5)
2798 .
Case(
"pn6", AArch64::PN6)
2799 .
Case(
"pn7", AArch64::PN7)
2800 .
Case(
"pn8", AArch64::PN8)
2801 .
Case(
"pn9", AArch64::PN9)
2802 .
Case(
"pn10", AArch64::PN10)
2803 .
Case(
"pn11", AArch64::PN11)
2804 .
Case(
"pn12", AArch64::PN12)
2805 .
Case(
"pn13", AArch64::PN13)
2806 .
Case(
"pn14", AArch64::PN14)
2807 .
Case(
"pn15", AArch64::PN15)
2813 .
Case(
"za0.d", AArch64::ZAD0)
2814 .
Case(
"za1.d", AArch64::ZAD1)
2815 .
Case(
"za2.d", AArch64::ZAD2)
2816 .
Case(
"za3.d", AArch64::ZAD3)
2817 .
Case(
"za4.d", AArch64::ZAD4)
2818 .
Case(
"za5.d", AArch64::ZAD5)
2819 .
Case(
"za6.d", AArch64::ZAD6)
2820 .
Case(
"za7.d", AArch64::ZAD7)
2821 .
Case(
"za0.s", AArch64::ZAS0)
2822 .
Case(
"za1.s", AArch64::ZAS1)
2823 .
Case(
"za2.s", AArch64::ZAS2)
2824 .
Case(
"za3.s", AArch64::ZAS3)
2825 .
Case(
"za0.h", AArch64::ZAH0)
2826 .
Case(
"za1.h", AArch64::ZAH1)
2827 .
Case(
"za0.b", AArch64::ZAB0)
2833 .
Case(
"za", AArch64::ZA)
2834 .
Case(
"za0.q", AArch64::ZAQ0)
2835 .
Case(
"za1.q", AArch64::ZAQ1)
2836 .
Case(
"za2.q", AArch64::ZAQ2)
2837 .
Case(
"za3.q", AArch64::ZAQ3)
2838 .
Case(
"za4.q", AArch64::ZAQ4)
2839 .
Case(
"za5.q", AArch64::ZAQ5)
2840 .
Case(
"za6.q", AArch64::ZAQ6)
2841 .
Case(
"za7.q", AArch64::ZAQ7)
2842 .
Case(
"za8.q", AArch64::ZAQ8)
2843 .
Case(
"za9.q", AArch64::ZAQ9)
2844 .
Case(
"za10.q", AArch64::ZAQ10)
2845 .
Case(
"za11.q", AArch64::ZAQ11)
2846 .
Case(
"za12.q", AArch64::ZAQ12)
2847 .
Case(
"za13.q", AArch64::ZAQ13)
2848 .
Case(
"za14.q", AArch64::ZAQ14)
2849 .
Case(
"za15.q", AArch64::ZAQ15)
2850 .
Case(
"za0.d", AArch64::ZAD0)
2851 .
Case(
"za1.d", AArch64::ZAD1)
2852 .
Case(
"za2.d", AArch64::ZAD2)
2853 .
Case(
"za3.d", AArch64::ZAD3)
2854 .
Case(
"za4.d", AArch64::ZAD4)
2855 .
Case(
"za5.d", AArch64::ZAD5)
2856 .
Case(
"za6.d", AArch64::ZAD6)
2857 .
Case(
"za7.d", AArch64::ZAD7)
2858 .
Case(
"za0.s", AArch64::ZAS0)
2859 .
Case(
"za1.s", AArch64::ZAS1)
2860 .
Case(
"za2.s", AArch64::ZAS2)
2861 .
Case(
"za3.s", AArch64::ZAS3)
2862 .
Case(
"za0.h", AArch64::ZAH0)
2863 .
Case(
"za1.h", AArch64::ZAH1)
2864 .
Case(
"za0.b", AArch64::ZAB0)
2865 .
Case(
"za0h.q", AArch64::ZAQ0)
2866 .
Case(
"za1h.q", AArch64::ZAQ1)
2867 .
Case(
"za2h.q", AArch64::ZAQ2)
2868 .
Case(
"za3h.q", AArch64::ZAQ3)
2869 .
Case(
"za4h.q", AArch64::ZAQ4)
2870 .
Case(
"za5h.q", AArch64::ZAQ5)
2871 .
Case(
"za6h.q", AArch64::ZAQ6)
2872 .
Case(
"za7h.q", AArch64::ZAQ7)
2873 .
Case(
"za8h.q", AArch64::ZAQ8)
2874 .
Case(
"za9h.q", AArch64::ZAQ9)
2875 .
Case(
"za10h.q", AArch64::ZAQ10)
2876 .
Case(
"za11h.q", AArch64::ZAQ11)
2877 .
Case(
"za12h.q", AArch64::ZAQ12)
2878 .
Case(
"za13h.q", AArch64::ZAQ13)
2879 .
Case(
"za14h.q", AArch64::ZAQ14)
2880 .
Case(
"za15h.q", AArch64::ZAQ15)
2881 .
Case(
"za0h.d", AArch64::ZAD0)
2882 .
Case(
"za1h.d", AArch64::ZAD1)
2883 .
Case(
"za2h.d", AArch64::ZAD2)
2884 .
Case(
"za3h.d", AArch64::ZAD3)
2885 .
Case(
"za4h.d", AArch64::ZAD4)
2886 .
Case(
"za5h.d", AArch64::ZAD5)
2887 .
Case(
"za6h.d", AArch64::ZAD6)
2888 .
Case(
"za7h.d", AArch64::ZAD7)
2889 .
Case(
"za0h.s", AArch64::ZAS0)
2890 .
Case(
"za1h.s", AArch64::ZAS1)
2891 .
Case(
"za2h.s", AArch64::ZAS2)
2892 .
Case(
"za3h.s", AArch64::ZAS3)
2893 .
Case(
"za0h.h", AArch64::ZAH0)
2894 .
Case(
"za1h.h", AArch64::ZAH1)
2895 .
Case(
"za0h.b", AArch64::ZAB0)
2896 .
Case(
"za0v.q", AArch64::ZAQ0)
2897 .
Case(
"za1v.q", AArch64::ZAQ1)
2898 .
Case(
"za2v.q", AArch64::ZAQ2)
2899 .
Case(
"za3v.q", AArch64::ZAQ3)
2900 .
Case(
"za4v.q", AArch64::ZAQ4)
2901 .
Case(
"za5v.q", AArch64::ZAQ5)
2902 .
Case(
"za6v.q", AArch64::ZAQ6)
2903 .
Case(
"za7v.q", AArch64::ZAQ7)
2904 .
Case(
"za8v.q", AArch64::ZAQ8)
2905 .
Case(
"za9v.q", AArch64::ZAQ9)
2906 .
Case(
"za10v.q", AArch64::ZAQ10)
2907 .
Case(
"za11v.q", AArch64::ZAQ11)
2908 .
Case(
"za12v.q", AArch64::ZAQ12)
2909 .
Case(
"za13v.q", AArch64::ZAQ13)
2910 .
Case(
"za14v.q", AArch64::ZAQ14)
2911 .
Case(
"za15v.q", AArch64::ZAQ15)
2912 .
Case(
"za0v.d", AArch64::ZAD0)
2913 .
Case(
"za1v.d", AArch64::ZAD1)
2914 .
Case(
"za2v.d", AArch64::ZAD2)
2915 .
Case(
"za3v.d", AArch64::ZAD3)
2916 .
Case(
"za4v.d", AArch64::ZAD4)
2917 .
Case(
"za5v.d", AArch64::ZAD5)
2918 .
Case(
"za6v.d", AArch64::ZAD6)
2919 .
Case(
"za7v.d", AArch64::ZAD7)
2920 .
Case(
"za0v.s", AArch64::ZAS0)
2921 .
Case(
"za1v.s", AArch64::ZAS1)
2922 .
Case(
"za2v.s", AArch64::ZAS2)
2923 .
Case(
"za3v.s", AArch64::ZAS3)
2924 .
Case(
"za0v.h", AArch64::ZAH0)
2925 .
Case(
"za1v.h", AArch64::ZAH1)
2926 .
Case(
"za0v.b", AArch64::ZAB0)
2930bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2932 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2935ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2937 StartLoc = getLoc();
2938 ParseStatus Res = tryParseScalarRegister(
Reg);
2944MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2946 MCRegister
Reg = MCRegister();
2948 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2951 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2954 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2957 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2960 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2962 if (
Name.equals_insensitive(
"zt0"))
2963 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2967 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2971 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2972 .Case(
"fp", AArch64::FP)
2973 .Case(
"lr", AArch64::LR)
2974 .Case(
"x31", AArch64::XZR)
2975 .Case(
"w31", AArch64::WZR)
2977 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2983 if (Entry == RegisterReqs.
end())
2984 return MCRegister();
2987 if (Kind ==
Entry->getValue().first)
2993unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2995 case RegKind::Scalar:
2996 case RegKind::NeonVector:
2997 case RegKind::SVEDataVector:
2999 case RegKind::Matrix:
3000 case RegKind::SVEPredicateVector:
3001 case RegKind::SVEPredicateAsCounter:
3003 case RegKind::LookupTable:
3012ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3013 const AsmToken &Tok = getTok();
3018 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3032 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3035 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3036 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3040 if (BadNum || CRNum > 15)
3041 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3045 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3052 const AsmToken &Tok = getTok();
3054 unsigned MaxVal = 63;
3059 const MCExpr *ImmVal;
3060 if (getParser().parseExpression(ImmVal))
3065 return TokError(
"immediate value expected for prefetch operand");
3068 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3071 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3072 Operands.push_back(AArch64Operand::CreatePrefetch(
3073 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3079 return TokError(
"prefetch hint expected");
3081 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3083 return TokError(
"prefetch hint expected");
3085 Operands.push_back(AArch64Operand::CreatePrefetch(
3092template <
bool IsSVEPrefetch>
3095 const AsmToken &Tok = getTok();
3097 auto LookupByName = [](StringRef
N) {
3098 if (IsSVEPrefetch) {
3099 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3100 return std::optional<unsigned>(Res->Encoding);
3101 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3102 return std::optional<unsigned>(Res->Encoding);
3103 return std::optional<unsigned>();
3106 auto LookupByEncoding = [](
unsigned E) {
3107 if (IsSVEPrefetch) {
3108 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3109 return std::optional<StringRef>(
3110 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3111 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3112 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3113 return std::optional<StringRef>();
3115 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3121 const MCExpr *ImmVal;
3122 if (getParser().parseExpression(ImmVal))
3127 return TokError(
"immediate value expected for prefetch operand");
3130 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3133 auto PRFM = LookupByEncoding(MCE->
getValue());
3134 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3140 return TokError(
"prefetch hint expected");
3142 auto PRFM = LookupByName(Tok.
getString());
3144 return TokError(
"prefetch hint expected");
3146 Operands.push_back(AArch64Operand::CreatePrefetch(
3153 SMLoc StartLoc = getLoc();
3159 auto RegTok = getTok();
3160 if (!tryParseScalarRegister(RegNum).isSuccess())
3163 if (RegNum != AArch64::XZR) {
3164 getLexer().UnLex(RegTok);
3171 if (!tryParseScalarRegister(RegNum).isSuccess())
3172 return TokError(
"expected register operand");
3174 if (RegNum != AArch64::XZR)
3175 return TokError(
"xzr must be followed by xzr");
3179 Operands.push_back(AArch64Operand::CreateReg(
3180 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3188 const AsmToken &Tok = getTok();
3190 return TokError(
"invalid operand for instruction");
3192 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3194 return TokError(
"invalid operand for instruction");
3196 Operands.push_back(AArch64Operand::CreateTIndexHint(
3206 const MCExpr *Expr =
nullptr;
3212 if (parseSymbolicImmVal(Expr))
3218 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3227 return Error(S,
"gotpage label reference not allowed an addend");
3239 return Error(S,
"page or gotpage label reference expected");
3256 const MCExpr *Expr =
nullptr;
3265 if (parseSymbolicImmVal(Expr))
3271 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3283 return Error(S,
"unexpected adr label");
3293template <
bool AddFPZeroAsLiteral>
3302 const AsmToken &Tok = getTok();
3306 return TokError(
"invalid floating point immediate");
3311 if (Tok.
getIntVal() > 255 || isNegative)
3312 return TokError(
"encoded floating point value out of range");
3316 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3319 APFloat RealVal(APFloat::IEEEdouble());
3321 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3323 return TokError(
"invalid floating point representation");
3326 RealVal.changeSign();
3328 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3332 Operands.push_back(AArch64Operand::CreateFPImm(
3333 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3357 const MCExpr *
Imm =
nullptr;
3358 if (parseSymbolicImmVal(
Imm))
3369 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3373 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3379 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3380 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3388 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3390 int64_t ShiftAmount = getTok().getIntVal();
3392 if (ShiftAmount < 0)
3393 return Error(getLoc(),
"positive shift amount required");
3397 if (ShiftAmount == 0 &&
Imm !=
nullptr) {
3403 Operands.push_back(AArch64Operand::CreateShiftedImm(
Imm, ShiftAmount, S,
3411AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3445 Suggestion =
"nfrst";
3452 bool invertCondCode) {
3454 const AsmToken &Tok = getTok();
3458 std::string Suggestion;
3461 std::string
Msg =
"invalid condition code";
3462 if (!Suggestion.empty())
3463 Msg +=
", did you mean " + Suggestion +
"?";
3464 return TokError(
Msg);
3468 if (invertCondCode) {
3470 return TokError(
"condition codes AL and NV are invalid for this instruction");
3475 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3480 const AsmToken &Tok = getTok();
3484 return TokError(
"invalid operand for instruction");
3486 unsigned PStateImm = -1;
3487 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3490 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3491 PStateImm = SVCR->Encoding;
3500 const AsmToken &Tok = getTok();
3505 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3507 unsigned ElementWidth = 0;
3508 auto DotPosition =
Name.find(
'.');
3510 const auto &KindRes =
3514 "Expected the register to be followed by element width suffix");
3515 ElementWidth = KindRes->second;
3517 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3518 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3523 if (parseOperand(
Operands,
false,
false))
3530 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3534 size_t DotPosition =
Name.find(
'.');
3537 StringRef Head =
Name.take_front(DotPosition);
3538 StringRef
Tail =
Name.drop_front(DotPosition);
3539 StringRef RowOrColumn = Head.
take_back();
3541 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3542 .Case(
"h", MatrixKind::Row)
3543 .Case(
"v", MatrixKind::Col)
3544 .Default(MatrixKind::Tile);
3550 "Expected the register to be followed by element width suffix");
3551 unsigned ElementWidth = KindRes->second;
3555 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3561 if (parseOperand(
Operands,
false,
false))
3571 const AsmToken &Tok = getTok();
3574 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3603 return TokError(
"expected #imm after shift specifier");
3609 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3618 return Error(
E,
"expected integer shift amount");
3620 const MCExpr *ImmVal;
3621 if (getParser().parseExpression(ImmVal))
3626 return Error(
E,
"expected constant '#imm' after shift specifier");
3629 Operands.push_back(AArch64Operand::CreateShiftExtend(
3635 {{
"crc"}, {AArch64::FeatureCRC}},
3636 {{
"sm4"}, {AArch64::FeatureSM4}},
3637 {{
"sha3"}, {AArch64::FeatureSHA3}},
3638 {{
"sha2"}, {AArch64::FeatureSHA2}},
3639 {{
"aes"}, {AArch64::FeatureAES}},
3640 {{
"crypto"}, {AArch64::FeatureCrypto}},
3641 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3642 {{
"simd"}, {AArch64::FeatureNEON}},
3643 {{
"ras"}, {AArch64::FeatureRAS}},
3644 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3645 {{
"lse"}, {AArch64::FeatureLSE}},
3646 {{
"predres"}, {AArch64::FeaturePredRes}},
3647 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3648 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3649 {{
"mte"}, {AArch64::FeatureMTE}},
3650 {{
"memtag"}, {AArch64::FeatureMTE}},
3651 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3652 {{
"pan"}, {AArch64::FeaturePAN}},
3653 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3654 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3655 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3656 {{
"rng"}, {AArch64::FeatureRandGen}},
3657 {{
"sve"}, {AArch64::FeatureSVE}},
3658 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3659 {{
"sve2"}, {AArch64::FeatureSVE2}},
3660 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3661 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3662 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3663 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3664 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3665 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3666 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3668 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3669 AArch64::FeatureSVE2}},
3670 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3671 {{
"ls64"}, {AArch64::FeatureLS64}},
3672 {{
"xs"}, {AArch64::FeatureXS}},
3673 {{
"pauth"}, {AArch64::FeaturePAuth}},
3674 {{
"flagm"}, {AArch64::FeatureFlagM}},
3675 {{
"rme"}, {AArch64::FeatureRME}},
3676 {{
"sme"}, {AArch64::FeatureSME}},
3677 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3678 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3679 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3680 {{
"sme2"}, {AArch64::FeatureSME2}},
3681 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3682 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3683 {{
"hbc"}, {AArch64::FeatureHBC}},
3684 {{
"mops"}, {AArch64::FeatureMOPS}},
3685 {{
"mec"}, {AArch64::FeatureMEC}},
3686 {{
"the"}, {AArch64::FeatureTHE}},
3687 {{
"d128"}, {AArch64::FeatureD128}},
3688 {{
"lse128"}, {AArch64::FeatureLSE128}},
3689 {{
"ite"}, {AArch64::FeatureITE}},
3690 {{
"cssc"}, {AArch64::FeatureCSSC}},
3691 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3692 {{
"gcs"}, {AArch64::FeatureGCS}},
3693 {{
"bf16"}, {AArch64::FeatureBF16}},
3694 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3695 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3696 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3697 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3698 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3699 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3700 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3701 {{
"lor"}, {AArch64::FeatureLOR}},
3702 {{
"profile"}, {AArch64::FeatureSPE}},
3706 {{
"rdm"}, {AArch64::FeatureRDM}},
3707 {{
"rdma"}, {AArch64::FeatureRDM}},
3708 {{
"sb"}, {AArch64::FeatureSB}},
3709 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3710 {{
"fp8"}, {AArch64::FeatureFP8}},
3711 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3712 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3713 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3714 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3715 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3716 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3717 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3718 {{
"lut"}, {AArch64::FeatureLUT}},
3719 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3720 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3721 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3722 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3723 {{
"cpa"}, {AArch64::FeatureCPA}},
3724 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3725 {{
"pops"}, {AArch64::FeaturePoPS}},
3726 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3727 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3728 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3729 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3730 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3731 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3732 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3733 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3734 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3735 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3736 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3737 {{
"lsui"}, {AArch64::FeatureLSUI}},
3738 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3739 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3740 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3741 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3742 {{
"lscp"}, {AArch64::FeatureLSCP}},
3743 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3744 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3745 {{
"gcie"}, {AArch64::FeatureGCIE}},
3746 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3747 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3748 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3749 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3750 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3751 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3752 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3753 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3754 {{
"tev"}, {AArch64::FeatureTEV}},
3755 {{
"btie"}, {AArch64::FeatureBTIE}},
3756 {{
"hinte"}, {AArch64::FeatureHINTE}},
3757 {{
"dit"}, {AArch64::FeatureDIT}},
3758 {{
"brbe"}, {AArch64::FeatureBRBE}},
3759 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3760 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3761 {{
"jscvt"}, {AArch64::FeatureJS}},
3762 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3763 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3764 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3765 {{
"cflt"}, {AArch64::FeatureCFLT}},
3766 {{
"lsc64b"}, {AArch64::FeatureLSC64B}},
3771 if (FBS[AArch64::HasV8_0aOps])
3773 if (FBS[AArch64::HasV8_1aOps])
3775 else if (FBS[AArch64::HasV8_2aOps])
3777 else if (FBS[AArch64::HasV8_3aOps])
3779 else if (FBS[AArch64::HasV8_4aOps])
3781 else if (FBS[AArch64::HasV8_5aOps])
3783 else if (FBS[AArch64::HasV8_6aOps])
3785 else if (FBS[AArch64::HasV8_7aOps])
3787 else if (FBS[AArch64::HasV8_8aOps])
3789 else if (FBS[AArch64::HasV8_9aOps])
3791 else if (FBS[AArch64::HasV9_0aOps])
3793 else if (FBS[AArch64::HasV9_1aOps])
3795 else if (FBS[AArch64::HasV9_2aOps])
3797 else if (FBS[AArch64::HasV9_3aOps])
3799 else if (FBS[AArch64::HasV9_4aOps])
3801 else if (FBS[AArch64::HasV9_5aOps])
3803 else if (FBS[AArch64::HasV9_6aOps])
3805 else if (FBS[AArch64::HasV9_7aOps])
3807 else if (FBS[AArch64::HasV9_8aOps])
3809 else if (FBS[AArch64::HasV8_0rOps])
3818 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3824 const uint16_t Op2 = Encoding & 7;
3825 const uint16_t Cm = (Encoding & 0x78) >> 3;
3826 const uint16_t Cn = (Encoding & 0x780) >> 7;
3827 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3832 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3834 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3836 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3839 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3845bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3847 if (
Name.contains(
'.'))
3848 return TokError(
"invalid operand");
3853 const AsmToken &Tok = getTok();
3856 bool ExpectRegister =
true;
3857 bool OptionalRegister =
false;
3858 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3859 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3861 if (Mnemonic ==
"ic") {
3862 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3864 return TokError(
"invalid operand for IC instruction");
3865 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3866 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3869 return TokError(Str);
3873 }
else if (Mnemonic ==
"dc") {
3874 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3876 return TokError(
"invalid operand for DC instruction");
3877 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3878 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3881 return TokError(Str);
3884 }
else if (Mnemonic ==
"at") {
3885 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3887 return TokError(
"invalid operand for AT instruction");
3888 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3889 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3892 return TokError(Str);
3895 }
else if (Mnemonic ==
"tlbi") {
3896 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3898 return TokError(
"invalid operand for TLBI instruction");
3899 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3900 std::string Str(
"TLBI " +
3901 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3904 return TokError(Str);
3906 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3907 if (hasAll || hasTLBID)
3908 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3910 }
else if (Mnemonic ==
"gic") {
3911 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3913 return TokError(
"invalid operand for GIC instruction");
3914 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3915 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3918 return TokError(Str);
3922 }
else if (Mnemonic ==
"gsb") {
3923 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3925 return TokError(
"invalid operand for GSB instruction");
3926 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3927 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3930 return TokError(Str);
3932 ExpectRegister =
false;
3934 }
else if (Mnemonic ==
"plbi") {
3935 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3937 return TokError(
"invalid operand for PLBI instruction");
3938 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3939 std::string Str(
"PLBI " +
3940 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3943 return TokError(Str);
3945 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3946 if (hasAll || hasTLBID)
3947 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3949 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3950 Mnemonic ==
"cosp") {
3952 if (
Op.lower() !=
"rctx")
3953 return TokError(
"invalid operand for prediction restriction instruction");
3955 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3956 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3958 if (Mnemonic ==
"cosp" && !hasSpecres2)
3959 return TokError(
"COSP requires: predres2");
3961 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3963 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3964 : Mnemonic ==
"dvp" ? 0b101
3965 : Mnemonic ==
"cosp" ? 0b110
3966 : Mnemonic ==
"cpp" ? 0b111
3969 "Invalid mnemonic for prediction restriction instruction");
3970 const auto SYS_3_7_3 = 0b01101110011;
3971 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3973 createSysAlias(Encoding,
Operands, S);
3978 bool HasRegister =
false;
3983 return TokError(
"expected register operand");
3987 if (!OptionalRegister) {
3988 if (ExpectRegister && !HasRegister)
3989 return TokError(
"specified " + Mnemonic +
" op requires a register");
3990 else if (!ExpectRegister && HasRegister)
3991 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4003bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4008 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4011 SMLoc startLoc = getLoc();
4012 const AsmToken ®Tok = getTok();
4014 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4016 return TokError(
"expected register operand");
4018 Operands.push_back(AArch64Operand::CreateReg(
4019 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4026 const AsmToken &operandTok = getTok();
4028 SMLoc S2 = operandTok.
getLoc();
4031 if (Mnemonic ==
"gicr") {
4032 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4034 return Error(S2,
"invalid operand for GICR instruction");
4035 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4036 std::string Str(
"GICR " +
4037 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4040 return Error(S2, Str);
4053bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4055 if (
Name.contains(
'.'))
4056 return TokError(
"invalid operand");
4060 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4062 const AsmToken &Tok = getTok();
4066 if (Mnemonic ==
"tlbip") {
4067 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4069 return TokError(
"invalid operand for TLBIP instruction");
4072 std::string Str(
"instruction requires: ");
4074 return TokError(Str);
4085 return TokError(
"expected register identifier");
4090 return TokError(
"specified " + Mnemonic +
4091 " op requires a pair of registers");
4100 MCAsmParser &Parser = getParser();
4101 const AsmToken &Tok = getTok();
4105 const MCExpr *ImmVal;
4106 SMLoc ExprLoc = getLoc();
4107 AsmToken IntTok = Tok;
4108 if (getParser().parseExpression(ImmVal))
4112 return Error(ExprLoc,
"immediate value expected for barrier operand");
4114 if (Mnemonic ==
"dsb" &&
Value > 15) {
4122 return Error(ExprLoc,
"barrier operand out of range");
4123 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4124 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4125 Operands.push_back(AArch64Operand::CreateBarrier(
4131 return TokError(
"invalid operand for instruction");
4134 auto DB = AArch64DB::lookupDBByName(Operand);
4136 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4137 return TokError(
"'sy' or #imm operand expected");
4139 if (Mnemonic ==
"dsb") {
4144 return TokError(
"invalid barrier option name");
4148 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4157 const AsmToken &Tok = getTok();
4159 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4160 if (Mnemonic !=
"dsb")
4165 const MCExpr *ImmVal;
4166 SMLoc ExprLoc = getLoc();
4167 if (getParser().parseExpression(ImmVal))
4171 return Error(ExprLoc,
"immediate value expected for barrier operand");
4176 return Error(ExprLoc,
"barrier operand out of range");
4177 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4178 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4179 Operands.push_back(AArch64Operand::CreateBarrier(
4185 return TokError(
"invalid operand for instruction");
4188 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4191 return TokError(
"invalid barrier option name");
4194 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4202 const AsmToken &Tok = getTok();
4207 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4211 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4212 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4213 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4214 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4218 unsigned PStateImm = -1;
4219 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4220 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4221 PStateImm = PState15->Encoding;
4223 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4224 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4225 PStateImm = PState1->Encoding;
4229 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4245 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4253 unsigned ElementWidth = KindRes->second;
4255 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4263 return tryParseVectorIndex(
Operands).isFailure();
4267 SMLoc SIdx = getLoc();
4269 const MCExpr *ImmVal;
4270 if (getParser().parseExpression(ImmVal))
4274 return TokError(
"immediate value expected for vector index");
4281 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4292ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4294 RegKind MatchKind) {
4295 const AsmToken &Tok = getTok();
4304 StringRef Head =
Name.slice(Start,
Next);
4305 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4311 return TokError(
"invalid vector kind qualifier");
4322ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4324 ParseStatus Status =
4325 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4327 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4332template <RegKind RK>
4336 const SMLoc S = getLoc();
4339 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4347 unsigned ElementWidth = KindRes->second;
4348 Operands.push_back(AArch64Operand::CreateVectorReg(
4349 RegNum, RK, ElementWidth, S,
4353 if (RK == RegKind::SVEPredicateAsCounter) {
4354 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4360 if (parseOperand(
Operands,
false,
false))
4371 return Error(S,
"not expecting size suffix");
4379 auto Pred = getTok().getString().lower();
4380 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4381 return Error(getLoc(),
"expecting 'z' predication");
4383 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4384 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4387 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4397 if (!tryParseNeonVectorRegister(
Operands))
4400 if (tryParseZTOperand(
Operands).isSuccess())
4404 if (tryParseGPROperand<false>(
Operands).isSuccess())
4410bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4411 bool HasELFModifier =
false;
4413 SMLoc Loc = getLexer().getLoc();
4415 HasELFModifier =
true;
4418 return TokError(
"expect relocation specifier in operand after ':'");
4420 std::string LowerCase = getTok().getIdentifier().lower();
4421 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4476 return TokError(
"expect relocation specifier in operand after ':'");
4480 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4484 if (getParser().parseExpression(ImmVal))
4492 if (!HasELFModifier &&
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4493 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4503 if (getParser().parsePrimaryExpr(Term, EndLoc))
4515 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4516 unsigned &ElementWidth) -> ParseStatus {
4517 StringRef
Name = getTok().getString();
4518 size_t DotPosition =
Name.find(
'.');
4526 StringRef
Tail =
Name.drop_front(DotPosition);
4527 const std::optional<std::pair<int, int>> &KindRes =
4531 "Expected the register to be followed by element width suffix");
4532 ElementWidth = KindRes->second;
4539 auto LCurly = getTok();
4544 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4550 if (getTok().getString().equals_insensitive(
"za")) {
4556 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4561 SMLoc TileLoc = getLoc();
4563 unsigned FirstReg, ElementWidth;
4564 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4565 if (!ParseRes.isSuccess()) {
4566 getLexer().UnLex(LCurly);
4570 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4572 unsigned PrevReg = FirstReg;
4574 SmallSet<unsigned, 8> DRegs;
4575 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4577 SmallSet<unsigned, 8> SeenRegs;
4578 SeenRegs.
insert(FirstReg);
4582 unsigned Reg, NextElementWidth;
4583 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4584 if (!ParseRes.isSuccess())
4588 if (ElementWidth != NextElementWidth)
4589 return Error(TileLoc,
"mismatched register size suffix");
4592 Warning(TileLoc,
"tile list not in ascending order");
4595 Warning(TileLoc,
"duplicate tile in list");
4598 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4607 unsigned RegMask = 0;
4608 for (
auto Reg : DRegs)
4612 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4617template <RegKind VectorKind>
4620 MCAsmParser &Parser = getParser();
4625 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4626 bool NoMatchIsError) -> ParseStatus {
4627 auto RegTok = getTok();
4628 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4629 if (ParseRes.isSuccess()) {
4636 RegTok.getString().equals_insensitive(
"zt0"))
4640 (ParseRes.isNoMatch() && NoMatchIsError &&
4641 !RegTok.getString().starts_with_insensitive(
"za")))
4642 return Error(Loc,
"vector register expected");
4647 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4649 auto LCurly = getTok();
4653 MCRegister FirstReg;
4654 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4658 if (ParseRes.isNoMatch())
4661 if (!ParseRes.isSuccess())
4664 MCRegister PrevReg = FirstReg;
4667 unsigned Stride = 1;
4669 SMLoc Loc = getLoc();
4673 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4674 if (!ParseRes.isSuccess())
4678 if (Kind != NextKind)
4679 return Error(Loc,
"mismatched register size suffix");
4682 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4684 if (Space == 0 || Space > 3)
4685 return Error(Loc,
"invalid number of vectors");
4690 bool HasCalculatedStride =
false;
4692 SMLoc Loc = getLoc();
4695 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4696 if (!ParseRes.isSuccess())
4700 if (Kind != NextKind)
4701 return Error(Loc,
"mismatched register size suffix");
4703 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4704 unsigned PrevRegVal =
4705 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4706 if (!HasCalculatedStride) {
4707 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4708 : (NumRegs - (PrevRegVal - RegVal));
4709 HasCalculatedStride =
true;
4713 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4714 return Error(Loc,
"registers must have the same sequential stride");
4725 return Error(S,
"invalid number of vectors");
4727 unsigned NumElements = 0;
4728 unsigned ElementWidth = 0;
4729 if (!
Kind.empty()) {
4731 std::tie(NumElements, ElementWidth) = *VK;
4734 Operands.push_back(AArch64Operand::CreateVectorList(
4735 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4739 ParseStatus Res = tryParseVectorIndex(
Operands);
4750 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4751 if (!ParseRes.isSuccess())
4754 return tryParseVectorIndex(
Operands).isFailure();
4758 SMLoc StartLoc = getLoc();
4761 ParseStatus Res = tryParseScalarRegister(RegNum);
4766 Operands.push_back(AArch64Operand::CreateReg(
4767 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4774 return Error(getLoc(),
"index must be absent or #0");
4776 const MCExpr *ImmVal;
4779 return Error(getLoc(),
"index must be absent or #0");
4781 Operands.push_back(AArch64Operand::CreateReg(
4782 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4787 SMLoc StartLoc = getLoc();
4788 const AsmToken &Tok = getTok();
4791 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4796 Operands.push_back(AArch64Operand::CreateReg(
4797 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4803 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4804 const MCExpr *ImmVal;
4805 if (getParser().parseExpression(ImmVal))
4809 return TokError(
"immediate value expected for vector index");
4810 Operands.push_back(AArch64Operand::CreateImm(
4814 if (parseOptionalMulOperand(
Operands))
4819 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4824template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4826 SMLoc StartLoc = getLoc();
4829 ParseStatus Res = tryParseScalarRegister(RegNum);
4835 Operands.push_back(AArch64Operand::CreateReg(
4836 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4845 Res = tryParseOptionalShiftExtend(ExtOpnd);
4849 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4850 Operands.push_back(AArch64Operand::CreateReg(
4851 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4852 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4853 Ext->hasShiftExtendAmount()));
4859 MCAsmParser &Parser = getParser();
4867 if (!getTok().getString().equals_insensitive(
"mul") ||
4868 !(NextIsVL || NextIsHash))
4872 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4877 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4887 const MCExpr *ImmVal;
4890 Operands.push_back(AArch64Operand::CreateImm(
4897 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4901 StringRef &VecGroup) {
4902 MCAsmParser &Parser = getParser();
4903 auto Tok = Parser.
getTok();
4908 .Case(
"vgx2",
"vgx2")
4909 .Case(
"vgx4",
"vgx4")
4921 auto Tok = getTok();
4928 .Case(
"csync",
"csync")
4931 .Case(
"keep",
"keep")
4935 .Case(
"stshstrm",
"stshstrm")
4936 .Case(
"strm",
"strm")
4949 bool invertCondCode) {
4950 MCAsmParser &Parser = getParser();
4953 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4967 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4969 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4972 getLexer().UnLex(SavedTok);
4976 switch (getLexer().getKind()) {
4980 if (parseSymbolicImmVal(Expr))
4981 return Error(S,
"invalid operand");
4985 return parseOptionalShiftExtend(getTok());
4989 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4994 return parseOperand(
Operands,
false,
false);
4997 if (!parseNeonVectorList(
Operands))
5001 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5006 return parseOperand(
Operands,
false,
false);
5011 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
5013 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5023 AsmToken SavedTok = getTok();
5028 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5032 Res = tryParseOptionalShiftExtend(
Operands);
5035 getLexer().UnLex(SavedTok);
5042 if (!parseOptionalMulOperand(
Operands))
5047 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5048 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5049 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh" ||
5051 return parseKeywordOperand(
Operands);
5055 const MCExpr *IdVal, *
Term;
5057 if (getParser().parseExpression(IdVal))
5059 if (getParser().parseAtSpecifier(IdVal,
E))
5061 std::optional<MCBinaryExpr::Opcode> Opcode;
5067 if (getParser().parsePrimaryExpr(Term,
E))
5074 return parseOptionalShiftExtend(getTok());
5085 bool isNegative =
false;
5097 const AsmToken &Tok = getTok();
5101 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5102 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5103 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5104 return TokError(
"unexpected floating point literal");
5105 else if (IntVal != 0 || isNegative)
5106 return TokError(
"expected floating-point constant #0.0");
5114 const MCExpr *ImmVal;
5115 if (parseSymbolicImmVal(ImmVal))
5122 return parseOptionalShiftExtend(Tok);
5125 SMLoc Loc = getLoc();
5126 if (Mnemonic !=
"ldr")
5127 return TokError(
"unexpected token in operand");
5129 const MCExpr *SubExprVal;
5130 if (getParser().parseExpression(SubExprVal))
5134 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5135 return Error(Loc,
"Only valid when first operand is register");
5137 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5145 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5150 if (ShiftAmt <= MaxShiftAmt &&
Imm <= 0xFFFF) {
5151 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5152 Operands.push_back(AArch64Operand::CreateImm(
5156 ShiftAmt,
true, S,
E, Ctx));
5159 APInt Simm = APInt(64,
Imm << ShiftAmt);
5162 return Error(Loc,
"Immediate too large for register");
5165 const MCExpr *CPLoc =
5166 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5167 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5173bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5174 const MCExpr *Expr =
nullptr;
5176 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5179 if (check(!
Value, L,
"expected constant expression"))
5185bool AArch64AsmParser::parseComma() {
5193bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5197 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5202 unsigned RangeEnd =
Last;
5203 if (
Base == AArch64::X0) {
5204 if (
Last == AArch64::FP) {
5205 RangeEnd = AArch64::X28;
5206 if (
Reg == AArch64::FP) {
5211 if (
Last == AArch64::LR) {
5212 RangeEnd = AArch64::X28;
5213 if (
Reg == AArch64::FP) {
5216 }
else if (
Reg == AArch64::LR) {
5224 Twine(
"expected register in range ") +
5232bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5233 const MCParsedAsmOperand &Op2)
const {
5234 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5235 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5237 if (AOp1.isVectorList() && AOp2.isVectorList())
5238 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5239 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5240 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5242 if (!AOp1.isReg() || !AOp2.isReg())
5245 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5246 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5249 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5250 "Testing equality of non-scalar registers not supported");
5253 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5255 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5257 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5259 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5266bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5267 StringRef Name, SMLoc NameLoc,
5269 Name = StringSwitch<StringRef>(
Name.lower())
5270 .Case(
"beq",
"b.eq")
5271 .Case(
"bne",
"b.ne")
5272 .Case(
"bhs",
"b.hs")
5273 .Case(
"bcs",
"b.cs")
5274 .Case(
"blo",
"b.lo")
5275 .Case(
"bcc",
"b.cc")
5276 .Case(
"bmi",
"b.mi")
5277 .Case(
"bpl",
"b.pl")
5278 .Case(
"bvs",
"b.vs")
5279 .Case(
"bvc",
"b.vc")
5280 .Case(
"bhi",
"b.hi")
5281 .Case(
"bls",
"b.ls")
5282 .Case(
"bge",
"b.ge")
5283 .Case(
"blt",
"b.lt")
5284 .Case(
"bgt",
"b.gt")
5285 .Case(
"ble",
"b.le")
5286 .Case(
"bal",
"b.al")
5287 .Case(
"bnv",
"b.nv")
5292 getTok().getIdentifier().lower() ==
".req") {
5293 parseDirectiveReq(Name, NameLoc);
5301 StringRef Head =
Name.slice(Start,
Next);
5305 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5306 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5307 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5308 return parseSysAlias(Head, NameLoc,
Operands);
5312 return parseSyslAlias(Head, NameLoc,
Operands);
5315 if (Head ==
"tlbip")
5316 return parseSyspAlias(Head, NameLoc,
Operands);
5322 if ((Head ==
"b" || Head ==
"bc" || Head ==
"flt") &&
5326 Head =
Name.slice(Start + 1,
Next);
5330 std::string Suggestion;
5333 std::string
Msg =
"invalid condition code";
5334 if (!Suggestion.empty())
5335 Msg +=
", did you mean " + Suggestion +
"?";
5341 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5351 Operands.push_back(AArch64Operand::CreateToken(
5357 bool condCodeFourthOperand =
5358 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5359 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5360 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5368 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5369 bool condCodeThirdOperand =
5370 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5378 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5379 (
N == 3 && condCodeThirdOperand) ||
5380 (
N == 2 && condCodeSecondOperand),
5381 condCodeSecondOperand || condCodeThirdOperand)) {
5401 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5404 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5407 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5420 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5421 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5422 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5423 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5424 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5425 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5426 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5438bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5439 SmallVectorImpl<SMLoc> &Loc) {
5440 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5447 PrefixInfo
Prefix = NextPrefix;
5448 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5459 return Error(IDLoc,
"instruction is unpredictable when following a"
5460 " movprfx, suggest replacing movprfx with mov");
5464 return Error(Loc[0],
"instruction is unpredictable when following a"
5465 " movprfx writing to a different destination");
5472 return Error(Loc[0],
"instruction is unpredictable when following a"
5473 " movprfx and destination also used as non-destructive"
5477 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5478 if (
Prefix.isPredicated()) {
5492 return Error(IDLoc,
"instruction is unpredictable when following a"
5493 " predicated movprfx, suggest using unpredicated movprfx");
5497 return Error(IDLoc,
"instruction is unpredictable when following a"
5498 " predicated movprfx using a different general predicate");
5502 return Error(IDLoc,
"instruction is unpredictable when following a"
5503 " predicated movprfx with a different element size");
5509 if (IsWindowsArm64EC) {
5515 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5516 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5517 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5518 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5519 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5520 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5521 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5522 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5523 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5524 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5526 " is disallowed on ARM64EC.");
5536 case AArch64::LDPSWpre:
5537 case AArch64::LDPWpost:
5538 case AArch64::LDPWpre:
5539 case AArch64::LDPXpost:
5540 case AArch64::LDPXpre: {
5545 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5546 "is also a destination");
5548 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5549 "is also a destination");
5552 case AArch64::LDR_ZA:
5553 case AArch64::STR_ZA: {
5556 return Error(Loc[1],
5557 "unpredictable instruction, immediate and offset mismatch.");
5560 case AArch64::LDPDi:
5561 case AArch64::LDPQi:
5562 case AArch64::LDPSi:
5563 case AArch64::LDPSWi:
5564 case AArch64::LDPWi:
5565 case AArch64::LDPXi: {
5569 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5572 case AArch64::LDPDpost:
5573 case AArch64::LDPDpre:
5574 case AArch64::LDPQpost:
5575 case AArch64::LDPQpre:
5576 case AArch64::LDPSpost:
5577 case AArch64::LDPSpre:
5578 case AArch64::LDPSWpost: {
5582 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5585 case AArch64::STPDpost:
5586 case AArch64::STPDpre:
5587 case AArch64::STPQpost:
5588 case AArch64::STPQpre:
5589 case AArch64::STPSpost:
5590 case AArch64::STPSpre:
5591 case AArch64::STPWpost:
5592 case AArch64::STPWpre:
5593 case AArch64::STPXpost:
5594 case AArch64::STPXpre: {
5599 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5600 "is also a source");
5602 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5603 "is also a source");
5606 case AArch64::LDRBBpre:
5607 case AArch64::LDRBpre:
5608 case AArch64::LDRHHpre:
5609 case AArch64::LDRHpre:
5610 case AArch64::LDRSBWpre:
5611 case AArch64::LDRSBXpre:
5612 case AArch64::LDRSHWpre:
5613 case AArch64::LDRSHXpre:
5614 case AArch64::LDRSWpre:
5615 case AArch64::LDRWpre:
5616 case AArch64::LDRXpre:
5617 case AArch64::LDRBBpost:
5618 case AArch64::LDRBpost:
5619 case AArch64::LDRHHpost:
5620 case AArch64::LDRHpost:
5621 case AArch64::LDRSBWpost:
5622 case AArch64::LDRSBXpost:
5623 case AArch64::LDRSHWpost:
5624 case AArch64::LDRSHXpost:
5625 case AArch64::LDRSWpost:
5626 case AArch64::LDRWpost:
5627 case AArch64::LDRXpost: {
5631 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5632 "is also a source");
5635 case AArch64::STRBBpost:
5636 case AArch64::STRBpost:
5637 case AArch64::STRHHpost:
5638 case AArch64::STRHpost:
5639 case AArch64::STRWpost:
5640 case AArch64::STRXpost:
5641 case AArch64::STRBBpre:
5642 case AArch64::STRBpre:
5643 case AArch64::STRHHpre:
5644 case AArch64::STRHpre:
5645 case AArch64::STRWpre:
5646 case AArch64::STRXpre: {
5650 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5651 "is also a source");
5654 case AArch64::STXRB:
5655 case AArch64::STXRH:
5656 case AArch64::STXRW:
5657 case AArch64::STXRX:
5658 case AArch64::STLXRB:
5659 case AArch64::STLXRH:
5660 case AArch64::STLXRW:
5661 case AArch64::STLXRX: {
5667 return Error(Loc[0],
5668 "unpredictable STXR instruction, status is also a source");
5671 case AArch64::STXPW:
5672 case AArch64::STXPX:
5673 case AArch64::STLXPW:
5674 case AArch64::STLXPX: {
5681 return Error(Loc[0],
5682 "unpredictable STXP instruction, status is also a source");
5685 case AArch64::LDRABwriteback:
5686 case AArch64::LDRAAwriteback: {
5690 return Error(Loc[0],
5691 "unpredictable LDRA instruction, writeback base"
5692 " is also a destination");
5699 case AArch64::CPYFP:
5700 case AArch64::CPYFPWN:
5701 case AArch64::CPYFPRN:
5702 case AArch64::CPYFPN:
5703 case AArch64::CPYFPWT:
5704 case AArch64::CPYFPWTWN:
5705 case AArch64::CPYFPWTRN:
5706 case AArch64::CPYFPWTN:
5707 case AArch64::CPYFPRT:
5708 case AArch64::CPYFPRTWN:
5709 case AArch64::CPYFPRTRN:
5710 case AArch64::CPYFPRTN:
5711 case AArch64::CPYFPT:
5712 case AArch64::CPYFPTWN:
5713 case AArch64::CPYFPTRN:
5714 case AArch64::CPYFPTN:
5715 case AArch64::CPYFM:
5716 case AArch64::CPYFMWN:
5717 case AArch64::CPYFMRN:
5718 case AArch64::CPYFMN:
5719 case AArch64::CPYFMWT:
5720 case AArch64::CPYFMWTWN:
5721 case AArch64::CPYFMWTRN:
5722 case AArch64::CPYFMWTN:
5723 case AArch64::CPYFMRT:
5724 case AArch64::CPYFMRTWN:
5725 case AArch64::CPYFMRTRN:
5726 case AArch64::CPYFMRTN:
5727 case AArch64::CPYFMT:
5728 case AArch64::CPYFMTWN:
5729 case AArch64::CPYFMTRN:
5730 case AArch64::CPYFMTN:
5731 case AArch64::CPYFE:
5732 case AArch64::CPYFEWN:
5733 case AArch64::CPYFERN:
5734 case AArch64::CPYFEN:
5735 case AArch64::CPYFEWT:
5736 case AArch64::CPYFEWTWN:
5737 case AArch64::CPYFEWTRN:
5738 case AArch64::CPYFEWTN:
5739 case AArch64::CPYFERT:
5740 case AArch64::CPYFERTWN:
5741 case AArch64::CPYFERTRN:
5742 case AArch64::CPYFERTN:
5743 case AArch64::CPYFET:
5744 case AArch64::CPYFETWN:
5745 case AArch64::CPYFETRN:
5746 case AArch64::CPYFETN:
5748 case AArch64::CPYPWN:
5749 case AArch64::CPYPRN:
5750 case AArch64::CPYPN:
5751 case AArch64::CPYPWT:
5752 case AArch64::CPYPWTWN:
5753 case AArch64::CPYPWTRN:
5754 case AArch64::CPYPWTN:
5755 case AArch64::CPYPRT:
5756 case AArch64::CPYPRTWN:
5757 case AArch64::CPYPRTRN:
5758 case AArch64::CPYPRTN:
5759 case AArch64::CPYPT:
5760 case AArch64::CPYPTWN:
5761 case AArch64::CPYPTRN:
5762 case AArch64::CPYPTN:
5764 case AArch64::CPYMWN:
5765 case AArch64::CPYMRN:
5766 case AArch64::CPYMN:
5767 case AArch64::CPYMWT:
5768 case AArch64::CPYMWTWN:
5769 case AArch64::CPYMWTRN:
5770 case AArch64::CPYMWTN:
5771 case AArch64::CPYMRT:
5772 case AArch64::CPYMRTWN:
5773 case AArch64::CPYMRTRN:
5774 case AArch64::CPYMRTN:
5775 case AArch64::CPYMT:
5776 case AArch64::CPYMTWN:
5777 case AArch64::CPYMTRN:
5778 case AArch64::CPYMTN:
5780 case AArch64::CPYEWN:
5781 case AArch64::CPYERN:
5782 case AArch64::CPYEN:
5783 case AArch64::CPYEWT:
5784 case AArch64::CPYEWTWN:
5785 case AArch64::CPYEWTRN:
5786 case AArch64::CPYEWTN:
5787 case AArch64::CPYERT:
5788 case AArch64::CPYERTWN:
5789 case AArch64::CPYERTRN:
5790 case AArch64::CPYERTN:
5791 case AArch64::CPYET:
5792 case AArch64::CPYETWN:
5793 case AArch64::CPYETRN:
5794 case AArch64::CPYETN: {
5805 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5806 " registers are the same");
5808 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5809 " registers are the same");
5811 return Error(Loc[0],
"invalid CPY instruction, source and size"
5812 " registers are the same");
5816 case AArch64::SETPT:
5817 case AArch64::SETPN:
5818 case AArch64::SETPTN:
5820 case AArch64::SETMT:
5821 case AArch64::SETMN:
5822 case AArch64::SETMTN:
5824 case AArch64::SETET:
5825 case AArch64::SETEN:
5826 case AArch64::SETETN:
5827 case AArch64::SETGP:
5828 case AArch64::SETGPT:
5829 case AArch64::SETGPN:
5830 case AArch64::SETGPTN:
5831 case AArch64::SETGM:
5832 case AArch64::SETGMT:
5833 case AArch64::SETGMN:
5834 case AArch64::SETGMTN:
5835 case AArch64::MOPSSETGE:
5836 case AArch64::MOPSSETGET:
5837 case AArch64::MOPSSETGEN:
5838 case AArch64::MOPSSETGETN: {
5848 return Error(Loc[0],
"invalid SET instruction, destination and size"
5849 " registers are the same");
5851 return Error(Loc[0],
"invalid SET instruction, destination and source"
5852 " registers are the same");
5854 return Error(Loc[0],
"invalid SET instruction, source and size"
5855 " registers are the same");
5858 case AArch64::SETGOP:
5859 case AArch64::SETGOPT:
5860 case AArch64::SETGOPN:
5861 case AArch64::SETGOPTN:
5862 case AArch64::SETGOM:
5863 case AArch64::SETGOMT:
5864 case AArch64::SETGOMN:
5865 case AArch64::SETGOMTN:
5866 case AArch64::SETGOE:
5867 case AArch64::SETGOET:
5868 case AArch64::SETGOEN:
5869 case AArch64::SETGOETN: {
5878 return Error(Loc[0],
"invalid SET instruction, destination and size"
5879 " registers are the same");
5888 case AArch64::ADDSWri:
5889 case AArch64::ADDSXri:
5890 case AArch64::ADDWri:
5891 case AArch64::ADDXri:
5892 case AArch64::SUBSWri:
5893 case AArch64::SUBSXri:
5894 case AArch64::SUBWri:
5895 case AArch64::SUBXri: {
5903 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5928 return Error(Loc.
back(),
"invalid immediate expression");
5941 unsigned VariantID = 0);
5943bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5947 case Match_InvalidTiedOperand: {
5949 if (
Op.isVectorList())
5950 return Error(
Loc,
"operand must match destination register list");
5952 assert(
Op.isReg() &&
"Unexpected operand type");
5953 switch (
Op.getRegEqualityTy()) {
5954 case RegConstraintEqualityTy::EqualsSubReg:
5955 return Error(
Loc,
"operand must be 64-bit form of destination register");
5956 case RegConstraintEqualityTy::EqualsSuperReg:
5957 return Error(
Loc,
"operand must be 32-bit form of destination register");
5958 case RegConstraintEqualityTy::EqualsReg:
5959 return Error(
Loc,
"operand must match destination register");
5963 case Match_MissingFeature:
5965 "instruction requires a CPU feature not currently enabled");
5966 case Match_InvalidOperand:
5967 return Error(Loc,
"invalid operand for instruction");
5968 case Match_InvalidSuffix:
5969 return Error(Loc,
"invalid type suffix for instruction");
5970 case Match_InvalidCondCode:
5971 return Error(Loc,
"expected AArch64 condition code");
5972 case Match_AddSubRegExtendSmall:
5974 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5975 case Match_AddSubRegExtendLarge:
5977 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5978 case Match_AddSubSecondSource:
5980 "expected compatible register, symbol or integer in range [0, 4095]");
5981 case Match_LogicalSecondSource:
5982 return Error(Loc,
"expected compatible register or logical immediate");
5983 case Match_InvalidMovImm32Shift:
5984 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5985 case Match_InvalidMovImm64Shift:
5986 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5987 case Match_AddSubRegShift32:
5989 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5990 case Match_AddSubRegShift64:
5992 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5993 case Match_InvalidFPImm:
5995 "expected compatible register or floating-point constant");
5996 case Match_InvalidMemoryIndexedSImm6:
5997 return Error(Loc,
"index must be an integer in range [-32, 31].");
5998 case Match_InvalidMemoryIndexedSImm5:
5999 return Error(Loc,
"index must be an integer in range [-16, 15].");
6000 case Match_InvalidMemoryIndexed1SImm4:
6001 return Error(Loc,
"index must be an integer in range [-8, 7].");
6002 case Match_InvalidMemoryIndexed2SImm4:
6003 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6004 case Match_InvalidMemoryIndexed3SImm4:
6005 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6006 case Match_InvalidMemoryIndexed4SImm4:
6007 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6008 case Match_InvalidMemoryIndexed16SImm4:
6009 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6010 case Match_InvalidMemoryIndexed32SImm4:
6011 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6012 case Match_InvalidMemoryIndexed1SImm6:
6013 return Error(Loc,
"index must be an integer in range [-32, 31].");
6014 case Match_InvalidMemoryIndexedSImm8:
6015 return Error(Loc,
"index must be an integer in range [-128, 127].");
6016 case Match_InvalidMemoryIndexedSImm9:
6017 return Error(Loc,
"index must be an integer in range [-256, 255].");
6018 case Match_InvalidMemoryIndexed16SImm9:
6019 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6020 case Match_InvalidMemoryIndexed8SImm10:
6021 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6022 case Match_InvalidMemoryIndexed4SImm7:
6023 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6024 case Match_InvalidMemoryIndexed8SImm7:
6025 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6026 case Match_InvalidMemoryIndexed16SImm7:
6027 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6028 case Match_InvalidMemoryIndexed8UImm5:
6029 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6030 case Match_InvalidMemoryIndexed8UImm3:
6031 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6032 case Match_InvalidMemoryIndexed4UImm5:
6033 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6034 case Match_InvalidMemoryIndexed2UImm5:
6035 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6036 case Match_InvalidMemoryIndexed8UImm6:
6037 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6038 case Match_InvalidMemoryIndexed16UImm6:
6039 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6040 case Match_InvalidMemoryIndexed4UImm6:
6041 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6042 case Match_InvalidMemoryIndexed2UImm6:
6043 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6044 case Match_InvalidMemoryIndexed1UImm6:
6045 return Error(Loc,
"index must be in range [0, 63].");
6046 case Match_InvalidMemoryWExtend8:
6048 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6049 case Match_InvalidMemoryWExtend16:
6051 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6052 case Match_InvalidMemoryWExtend32:
6054 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6055 case Match_InvalidMemoryWExtend64:
6057 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6058 case Match_InvalidMemoryWExtend128:
6060 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6061 case Match_InvalidMemoryXExtend8:
6063 "expected 'lsl' or 'sxtx' with optional shift of #0");
6064 case Match_InvalidMemoryXExtend16:
6066 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6067 case Match_InvalidMemoryXExtend32:
6069 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6070 case Match_InvalidMemoryXExtend64:
6072 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6073 case Match_InvalidMemoryXExtend128:
6075 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6076 case Match_InvalidMemoryIndexed1:
6077 return Error(Loc,
"index must be an integer in range [0, 4095].");
6078 case Match_InvalidMemoryIndexed2:
6079 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6080 case Match_InvalidMemoryIndexed4:
6081 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6082 case Match_InvalidMemoryIndexed8:
6083 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6084 case Match_InvalidMemoryIndexed16:
6085 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6086 case Match_InvalidImm0_0:
6087 return Error(Loc,
"immediate must be 0.");
6088 case Match_InvalidImm0_1:
6089 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6090 case Match_InvalidImm0_3:
6091 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6092 case Match_InvalidImm0_7:
6093 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6094 case Match_InvalidImm0_15:
6095 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6096 case Match_InvalidImm0_31:
6097 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6098 case Match_InvalidImm0_63:
6099 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6100 case Match_InvalidImm0_127:
6101 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6102 case Match_InvalidImm0_255:
6103 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6104 case Match_InvalidImm0_511:
6105 return Error(Loc,
"immediate must be an integer in range [0, 511].");
6106 case Match_InvalidImm0_65535:
6107 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6108 case Match_InvalidHinteUImm16:
6110 "immediate must be an integer in range [0, 65535], excluding "
6111 "values in range [12319, 16383] where (value - 12319) is a "
6113 case Match_InvalidImm1_8:
6114 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6115 case Match_InvalidImm1_16:
6116 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6117 case Match_InvalidImm1_32:
6118 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6119 case Match_InvalidImm1_64:
6120 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6121 case Match_InvalidImm1_512:
6122 return Error(Loc,
"immediate must be an integer in range [1, 512].");
6123 case Match_InvalidImmM1_62:
6124 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6125 case Match_InvalidImmM1_510:
6126 return Error(Loc,
"immediate must be an integer in range [-1, 510].");
6127 case Match_InvalidImmM255_256:
6128 return Error(Loc,
"immediate must be an integer in range [-255, 256].");
6129 case Match_InvalidImmM257_254:
6130 return Error(Loc,
"immediate must be an integer in range [-257, 254].");
6131 case Match_InvalidMemoryIndexedRange2UImm0:
6132 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6133 case Match_InvalidMemoryIndexedRange2UImm1:
6134 return Error(Loc,
"vector select offset must be an immediate range of the "
6135 "form <immf>:<imml>, where the first "
6136 "immediate is a multiple of 2 in the range [0, 2], and "
6137 "the second immediate is immf + 1.");
6138 case Match_InvalidMemoryIndexedRange2UImm2:
6139 case Match_InvalidMemoryIndexedRange2UImm3:
6142 "vector select offset must be an immediate range of the form "
6144 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6146 "depending on the instruction, and the second immediate is immf + 1.");
6147 case Match_InvalidMemoryIndexedRange4UImm0:
6148 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6149 case Match_InvalidMemoryIndexedRange4UImm1:
6150 case Match_InvalidMemoryIndexedRange4UImm2:
6153 "vector select offset must be an immediate range of the form "
6155 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6157 "depending on the instruction, and the second immediate is immf + 3.");
6158 case Match_InvalidSVEAddSubImm8:
6159 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6160 " with a shift amount of 0");
6161 case Match_InvalidSVEAddSubImm16:
6162 case Match_InvalidSVEAddSubImm32:
6163 case Match_InvalidSVEAddSubImm64:
6164 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6165 "multiple of 256 in range [256, 65280]");
6166 case Match_InvalidSVECpyImm8:
6167 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6168 " with a shift amount of 0");
6169 case Match_InvalidSVECpyImm16:
6170 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6171 "multiple of 256 in range [-32768, 65280]");
6172 case Match_InvalidSVECpyImm32:
6173 case Match_InvalidSVECpyImm64:
6174 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6175 "multiple of 256 in range [-32768, 32512]");
6176 case Match_InvalidIndexRange0_0:
6177 return Error(Loc,
"expected lane specifier '[0]'");
6178 case Match_InvalidIndexRange1_1:
6179 return Error(Loc,
"expected lane specifier '[1]'");
6180 case Match_InvalidIndexRange0_15:
6181 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6182 case Match_InvalidIndexRange0_7:
6183 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6184 case Match_InvalidIndexRange0_3:
6185 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6186 case Match_InvalidIndexRange0_1:
6187 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6188 case Match_InvalidSVEIndexRange0_63:
6189 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6190 case Match_InvalidSVEIndexRange0_31:
6191 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6192 case Match_InvalidSVEIndexRange0_15:
6193 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6194 case Match_InvalidSVEIndexRange0_7:
6195 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6196 case Match_InvalidSVEIndexRange0_3:
6197 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6198 case Match_InvalidLabel:
6199 return Error(Loc,
"expected label or encodable integer pc offset");
6201 return Error(Loc,
"expected readable system register");
6203 case Match_InvalidSVCR:
6204 return Error(Loc,
"expected writable system register or pstate");
6205 case Match_InvalidComplexRotationEven:
6206 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6207 case Match_InvalidComplexRotationOdd:
6208 return Error(Loc,
"complex rotation must be 90 or 270.");
6209 case Match_MnemonicFail: {
6212 ComputeAvailableFeatures(STI->getFeatureBits()));
6213 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6215 case Match_InvalidGPR64shifted8:
6216 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6217 case Match_InvalidGPR64shifted16:
6218 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6219 case Match_InvalidGPR64shifted32:
6220 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6221 case Match_InvalidGPR64shifted64:
6222 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6223 case Match_InvalidGPR64shifted128:
6225 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6226 case Match_InvalidGPR64NoXZRshifted8:
6227 return Error(Loc,
"register must be x0..x30 without shift");
6228 case Match_InvalidGPR64NoXZRshifted16:
6229 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6230 case Match_InvalidGPR64NoXZRshifted32:
6231 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6232 case Match_InvalidGPR64NoXZRshifted64:
6233 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6234 case Match_InvalidGPR64NoXZRshifted128:
6235 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6236 case Match_InvalidZPR32UXTW8:
6237 case Match_InvalidZPR32SXTW8:
6238 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6239 case Match_InvalidZPR32UXTW16:
6240 case Match_InvalidZPR32SXTW16:
6241 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6242 case Match_InvalidZPR32UXTW32:
6243 case Match_InvalidZPR32SXTW32:
6244 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6245 case Match_InvalidZPR32UXTW64:
6246 case Match_InvalidZPR32SXTW64:
6247 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6248 case Match_InvalidZPR64UXTW8:
6249 case Match_InvalidZPR64SXTW8:
6250 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6251 case Match_InvalidZPR64UXTW16:
6252 case Match_InvalidZPR64SXTW16:
6253 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6254 case Match_InvalidZPR64UXTW32:
6255 case Match_InvalidZPR64SXTW32:
6256 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6257 case Match_InvalidZPR64UXTW64:
6258 case Match_InvalidZPR64SXTW64:
6259 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6260 case Match_InvalidZPR32LSL8:
6261 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6262 case Match_InvalidZPR32LSL16:
6263 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6264 case Match_InvalidZPR32LSL32:
6265 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6266 case Match_InvalidZPR32LSL64:
6267 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6268 case Match_InvalidZPR64LSL8:
6269 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6270 case Match_InvalidZPR64LSL16:
6271 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6272 case Match_InvalidZPR64LSL32:
6273 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6274 case Match_InvalidZPR64LSL64:
6275 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6276 case Match_InvalidZPR0:
6277 return Error(Loc,
"expected register without element width suffix");
6278 case Match_InvalidZPR8:
6279 case Match_InvalidZPR16:
6280 case Match_InvalidZPR32:
6281 case Match_InvalidZPR64:
6282 case Match_InvalidZPR128:
6283 return Error(Loc,
"invalid element width");
6284 case Match_InvalidZPR_3b8:
6285 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6286 case Match_InvalidZPR_3b16:
6287 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6288 case Match_InvalidZPR_3b32:
6289 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6290 case Match_InvalidZPR_4b8:
6292 "Invalid restricted vector register, expected z0.b..z15.b");
6293 case Match_InvalidZPR_4b16:
6294 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6295 case Match_InvalidZPR_4b32:
6296 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6297 case Match_InvalidZPR_4b64:
6298 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6299 case Match_InvalidZPRMul2_Lo8:
6300 return Error(Loc,
"Invalid restricted vector register, expected even "
6301 "register in z0.b..z14.b");
6302 case Match_InvalidZPRMul2_Hi8:
6303 return Error(Loc,
"Invalid restricted vector register, expected even "
6304 "register in z16.b..z30.b");
6305 case Match_InvalidZPRMul2_Lo16:
6306 return Error(Loc,
"Invalid restricted vector register, expected even "
6307 "register in z0.h..z14.h");
6308 case Match_InvalidZPRMul2_Hi16:
6309 return Error(Loc,
"Invalid restricted vector register, expected even "
6310 "register in z16.h..z30.h");
6311 case Match_InvalidZPRMul2_Lo32:
6312 return Error(Loc,
"Invalid restricted vector register, expected even "
6313 "register in z0.s..z14.s");
6314 case Match_InvalidZPRMul2_Hi32:
6315 return Error(Loc,
"Invalid restricted vector register, expected even "
6316 "register in z16.s..z30.s");
6317 case Match_InvalidZPRMul2_Lo64:
6318 return Error(Loc,
"Invalid restricted vector register, expected even "
6319 "register in z0.d..z14.d");
6320 case Match_InvalidZPRMul2_Hi64:
6321 return Error(Loc,
"Invalid restricted vector register, expected even "
6322 "register in z16.d..z30.d");
6323 case Match_InvalidZPR_K0:
6324 return Error(Loc,
"invalid restricted vector register, expected register "
6325 "in z20..z23 or z28..z31");
6326 case Match_InvalidSVEPattern:
6327 return Error(Loc,
"invalid predicate pattern");
6328 case Match_InvalidSVEPPRorPNRAnyReg:
6329 case Match_InvalidSVEPPRorPNRBReg:
6330 case Match_InvalidSVEPredicateAnyReg:
6331 case Match_InvalidSVEPredicateBReg:
6332 case Match_InvalidSVEPredicateHReg:
6333 case Match_InvalidSVEPredicateSReg:
6334 case Match_InvalidSVEPredicateDReg:
6335 return Error(Loc,
"invalid predicate register.");
6336 case Match_InvalidSVEPredicate3bAnyReg:
6337 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6338 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6339 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6340 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6341 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6342 return Error(Loc,
"Invalid predicate register, expected PN in range "
6343 "pn8..pn15 with element suffix.");
6344 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6345 return Error(Loc,
"invalid restricted predicate-as-counter register "
6346 "expected pn8..pn15");
6347 case Match_InvalidSVEPNPredicateBReg:
6348 case Match_InvalidSVEPNPredicateHReg:
6349 case Match_InvalidSVEPNPredicateSReg:
6350 case Match_InvalidSVEPNPredicateDReg:
6351 return Error(Loc,
"Invalid predicate register, expected PN in range "
6352 "pn0..pn15 with element suffix.");
6353 case Match_InvalidSVEVecLenSpecifier:
6354 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6355 case Match_InvalidSVEPredicateListMul2x8:
6356 case Match_InvalidSVEPredicateListMul2x16:
6357 case Match_InvalidSVEPredicateListMul2x32:
6358 case Match_InvalidSVEPredicateListMul2x64:
6359 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6360 "predicate registers, where the first vector is a multiple of 2 "
6361 "and with correct element type");
6362 case Match_InvalidSVEExactFPImmOperandHalfOne:
6363 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6364 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6365 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6366 case Match_InvalidSVEExactFPImmOperandZeroOne:
6367 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6368 case Match_InvalidMatrixTileVectorH8:
6369 case Match_InvalidMatrixTileVectorV8:
6370 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6371 case Match_InvalidMatrixTileVectorH16:
6372 case Match_InvalidMatrixTileVectorV16:
6374 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6375 case Match_InvalidMatrixTileVectorH32:
6376 case Match_InvalidMatrixTileVectorV32:
6378 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6379 case Match_InvalidMatrixTileVectorH64:
6380 case Match_InvalidMatrixTileVectorV64:
6382 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6383 case Match_InvalidMatrixTileVectorH128:
6384 case Match_InvalidMatrixTileVectorV128:
6386 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6387 case Match_InvalidMatrixTile16:
6388 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6389 case Match_InvalidMatrixTile32:
6390 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6391 case Match_InvalidMatrixTile64:
6392 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6393 case Match_InvalidMatrix:
6394 return Error(Loc,
"invalid matrix operand, expected za");
6395 case Match_InvalidMatrix8:
6396 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6397 case Match_InvalidMatrix16:
6398 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6399 case Match_InvalidMatrix32:
6400 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6401 case Match_InvalidMatrix64:
6402 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6403 case Match_InvalidMatrixIndexGPR32_12_15:
6404 return Error(Loc,
"operand must be a register in range [w12, w15]");
6405 case Match_InvalidMatrixIndexGPR32_8_11:
6406 return Error(Loc,
"operand must be a register in range [w8, w11]");
6407 case Match_InvalidSVEVectorList2x8Mul2:
6408 case Match_InvalidSVEVectorList2x16Mul2:
6409 case Match_InvalidSVEVectorList2x32Mul2:
6410 case Match_InvalidSVEVectorList2x64Mul2:
6411 case Match_InvalidSVEVectorList2x128Mul2:
6412 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6413 "SVE vectors, where the first vector is a multiple of 2 "
6414 "and with matching element types");
6415 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6416 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6417 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6418 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6419 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6420 "SVE vectors in the range z0-z14, where the first vector "
6421 "is a multiple of 2 "
6422 "and with matching element types");
6423 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6424 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6425 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6426 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6428 "Invalid vector list, expected list with 2 consecutive "
6429 "SVE vectors in the range z16-z30, where the first vector "
6430 "is a multiple of 2 "
6431 "and with matching element types");
6432 case Match_InvalidSVEVectorList4x8Mul4:
6433 case Match_InvalidSVEVectorList4x16Mul4:
6434 case Match_InvalidSVEVectorList4x32Mul4:
6435 case Match_InvalidSVEVectorList4x64Mul4:
6436 case Match_InvalidSVEVectorList4x128Mul4:
6437 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6438 "SVE vectors, where the first vector is a multiple of 4 "
6439 "and with matching element types");
6440 case Match_InvalidSVEVectorList3x0_3b:
6441 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6442 "SVE vectors starting at z0-z7");
6443 case Match_InvalidLookupTable:
6444 return Error(Loc,
"Invalid lookup table, expected zt0");
6445 case Match_InvalidSVEVectorListStrided2x8:
6446 case Match_InvalidSVEVectorListStrided2x16:
6447 case Match_InvalidSVEVectorListStrided2x32:
6448 case Match_InvalidSVEVectorListStrided2x64:
6451 "Invalid vector list, expected list with each SVE vector in the list "
6452 "8 registers apart, and the first register in the range [z0, z7] or "
6453 "[z16, z23] and with correct element type");
6454 case Match_InvalidSVEVectorListStrided4x8:
6455 case Match_InvalidSVEVectorListStrided4x16:
6456 case Match_InvalidSVEVectorListStrided4x32:
6457 case Match_InvalidSVEVectorListStrided4x64:
6460 "Invalid vector list, expected list with each SVE vector in the list "
6461 "4 registers apart, and the first register in the range [z0, z3] or "
6462 "[z16, z19] and with correct element type");
6463 case Match_AddSubLSLImm3ShiftLarge:
6465 "expected 'lsl' with optional integer in range [0, 7]");
6473bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6477 bool MatchingInlineAsm) {
6479 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6480 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6483 unsigned NumOperands =
Operands.size();
6485 if (NumOperands == 4 && Tok ==
"lsl") {
6486 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6487 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6488 if (Op2.isScalarReg() && Op3.isImm()) {
6494 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6496 NewOp3Val = (32 - Op3Val) & 0x1f;
6497 NewOp4Val = 31 - Op3Val;
6499 NewOp3Val = (64 - Op3Val) & 0x3f;
6500 NewOp4Val = 63 - Op3Val;
6507 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6508 Operands.push_back(AArch64Operand::CreateImm(
6509 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6510 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6514 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6516 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6517 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6518 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6520 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6524 if (LSBCE && WidthCE) {
6529 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6535 if (LSB >= RegWidth)
6536 return Error(LSBOp.getStartLoc(),
6537 "expected integer in range [0, 31]");
6538 if (Width < 1 || Width > RegWidth)
6539 return Error(WidthOp.getStartLoc(),
6540 "expected integer in range [1, 32]");
6544 ImmR = (32 - LSB) & 0x1f;
6546 ImmR = (64 - LSB) & 0x3f;
6550 if (ImmR != 0 && ImmS >= ImmR)
6551 return Error(WidthOp.getStartLoc(),
6552 "requested insert overflows register");
6557 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6558 Operands[2] = AArch64Operand::CreateReg(
6559 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6561 Operands[3] = AArch64Operand::CreateImm(
6562 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6564 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6568 }
else if (NumOperands == 5) {
6571 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6572 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6573 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6574 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6576 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6580 if (Op3CE && Op4CE) {
6585 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6591 if (Op3Val >= RegWidth)
6592 return Error(Op3.getStartLoc(),
6593 "expected integer in range [0, 31]");
6594 if (Op4Val < 1 || Op4Val > RegWidth)
6595 return Error(Op4.getStartLoc(),
6596 "expected integer in range [1, 32]");
6600 NewOp3Val = (32 - Op3Val) & 0x1f;
6602 NewOp3Val = (64 - Op3Val) & 0x3f;
6606 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6607 return Error(Op4.getStartLoc(),
6608 "requested insert overflows register");
6610 const MCExpr *NewOp3 =
6612 const MCExpr *NewOp4 =
6614 Operands[3] = AArch64Operand::CreateImm(
6615 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6616 Operands[4] = AArch64Operand::CreateImm(
6617 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6619 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6621 else if (Tok ==
"sbfiz")
6622 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6624 else if (Tok ==
"ubfiz")
6625 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6634 }
else if (NumOperands == 5 &&
6635 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6636 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6637 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6638 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6640 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6644 if (Op3CE && Op4CE) {
6649 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6655 if (Op3Val >= RegWidth)
6656 return Error(Op3.getStartLoc(),
6657 "expected integer in range [0, 31]");
6658 if (Op4Val < 1 || Op4Val > RegWidth)
6659 return Error(Op4.getStartLoc(),
6660 "expected integer in range [1, 32]");
6662 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6664 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6665 return Error(Op4.getStartLoc(),
6666 "requested extract overflows register");
6668 const MCExpr *NewOp4 =
6670 Operands[4] = AArch64Operand::CreateImm(
6671 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6673 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6675 else if (Tok ==
"sbfx")
6676 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6678 else if (Tok ==
"ubfx")
6679 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6692 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6693 NumOperands == 4 && Tok ==
"movi") {
6694 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6695 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6696 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6697 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6698 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6699 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6700 if (Suffix.
lower() ==
".2d" &&
6702 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6703 " correctly on this CPU, converting to equivalent movi.16b");
6705 unsigned Idx = Op1.isToken() ? 1 : 2;
6707 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6715 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6718 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6719 if (
Op.isScalarReg()) {
6721 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6722 Op.getStartLoc(),
Op.getEndLoc(),
6727 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6728 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6729 if (
Op.isScalarReg() &&
6730 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6734 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6735 if (
Op.isScalarReg()) {
6737 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6744 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6745 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6746 if (
Op.isScalarReg() &&
6747 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6751 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6752 if (
Op.isScalarReg()) {
6754 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6762 FeatureBitset MissingFeatures;
6765 unsigned MatchResult =
6766 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6767 MatchingInlineAsm, 1);
6771 if (MatchResult != Match_Success) {
6774 auto ShortFormNEONErrorInfo = ErrorInfo;
6775 auto ShortFormNEONMatchResult = MatchResult;
6776 auto ShortFormNEONMissingFeatures = MissingFeatures;
6779 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6780 MatchingInlineAsm, 0);
6785 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6787 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6788 MatchResult = ShortFormNEONMatchResult;
6789 ErrorInfo = ShortFormNEONErrorInfo;
6790 MissingFeatures = ShortFormNEONMissingFeatures;
6794 switch (MatchResult) {
6795 case Match_Success: {
6799 for (
unsigned i = 1; i < NumOperands; ++i)
6801 if (validateInstruction(Inst, IDLoc, OperandLocs))
6805 Out.emitInstruction(Inst, getSTI());
6808 case Match_MissingFeature: {
6809 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6812 std::string
Msg =
"instruction requires:";
6813 for (
unsigned Feature : MissingFeatures) {
6819 case Match_MnemonicFail:
6820 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6821 case Match_InvalidOperand: {
6822 SMLoc ErrorLoc = IDLoc;
6824 if (ErrorInfo != ~0ULL) {
6826 return Error(IDLoc,
"too few operands for instruction",
6827 SMRange(IDLoc, getTok().getLoc()));
6829 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6830 if (ErrorLoc == SMLoc())
6835 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6836 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6837 MatchResult = Match_InvalidSuffix;
6839 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6841 case Match_InvalidTiedOperand:
6842 case Match_InvalidMemoryIndexed1:
6843 case Match_InvalidMemoryIndexed2:
6844 case Match_InvalidMemoryIndexed4:
6845 case Match_InvalidMemoryIndexed8:
6846 case Match_InvalidMemoryIndexed16:
6847 case Match_InvalidCondCode:
6848 case Match_AddSubLSLImm3ShiftLarge:
6849 case Match_AddSubRegExtendSmall:
6850 case Match_AddSubRegExtendLarge:
6851 case Match_AddSubSecondSource:
6852 case Match_LogicalSecondSource:
6853 case Match_AddSubRegShift32:
6854 case Match_AddSubRegShift64:
6855 case Match_InvalidMovImm32Shift:
6856 case Match_InvalidMovImm64Shift:
6857 case Match_InvalidFPImm:
6858 case Match_InvalidMemoryWExtend8:
6859 case Match_InvalidMemoryWExtend16:
6860 case Match_InvalidMemoryWExtend32:
6861 case Match_InvalidMemoryWExtend64:
6862 case Match_InvalidMemoryWExtend128:
6863 case Match_InvalidMemoryXExtend8:
6864 case Match_InvalidMemoryXExtend16:
6865 case Match_InvalidMemoryXExtend32:
6866 case Match_InvalidMemoryXExtend64:
6867 case Match_InvalidMemoryXExtend128:
6868 case Match_InvalidMemoryIndexed1SImm4:
6869 case Match_InvalidMemoryIndexed2SImm4:
6870 case Match_InvalidMemoryIndexed3SImm4:
6871 case Match_InvalidMemoryIndexed4SImm4:
6872 case Match_InvalidMemoryIndexed1SImm6:
6873 case Match_InvalidMemoryIndexed16SImm4:
6874 case Match_InvalidMemoryIndexed32SImm4:
6875 case Match_InvalidMemoryIndexed4SImm7:
6876 case Match_InvalidMemoryIndexed8SImm7:
6877 case Match_InvalidMemoryIndexed16SImm7:
6878 case Match_InvalidMemoryIndexed8UImm5:
6879 case Match_InvalidMemoryIndexed8UImm3:
6880 case Match_InvalidMemoryIndexed4UImm5:
6881 case Match_InvalidMemoryIndexed2UImm5:
6882 case Match_InvalidMemoryIndexed1UImm6:
6883 case Match_InvalidMemoryIndexed2UImm6:
6884 case Match_InvalidMemoryIndexed4UImm6:
6885 case Match_InvalidMemoryIndexed8UImm6:
6886 case Match_InvalidMemoryIndexed16UImm6:
6887 case Match_InvalidMemoryIndexedSImm6:
6888 case Match_InvalidMemoryIndexedSImm5:
6889 case Match_InvalidMemoryIndexedSImm8:
6890 case Match_InvalidMemoryIndexedSImm9:
6891 case Match_InvalidMemoryIndexed16SImm9:
6892 case Match_InvalidMemoryIndexed8SImm10:
6893 case Match_InvalidImm0_0:
6894 case Match_InvalidImm0_1:
6895 case Match_InvalidImm0_3:
6896 case Match_InvalidImm0_7:
6897 case Match_InvalidImm0_15:
6898 case Match_InvalidImm0_31:
6899 case Match_InvalidImm0_63:
6900 case Match_InvalidImm0_127:
6901 case Match_InvalidImm0_255:
6902 case Match_InvalidImm0_511:
6903 case Match_InvalidImm0_65535:
6904 case Match_InvalidHinteUImm16:
6905 case Match_InvalidImm1_8:
6906 case Match_InvalidImm1_16:
6907 case Match_InvalidImm1_32:
6908 case Match_InvalidImm1_64:
6909 case Match_InvalidImm1_512:
6910 case Match_InvalidImmM1_62:
6911 case Match_InvalidImmM1_510:
6912 case Match_InvalidImmM255_256:
6913 case Match_InvalidImmM257_254:
6914 case Match_InvalidMemoryIndexedRange2UImm0:
6915 case Match_InvalidMemoryIndexedRange2UImm1:
6916 case Match_InvalidMemoryIndexedRange2UImm2:
6917 case Match_InvalidMemoryIndexedRange2UImm3:
6918 case Match_InvalidMemoryIndexedRange4UImm0:
6919 case Match_InvalidMemoryIndexedRange4UImm1:
6920 case Match_InvalidMemoryIndexedRange4UImm2:
6921 case Match_InvalidSVEAddSubImm8:
6922 case Match_InvalidSVEAddSubImm16:
6923 case Match_InvalidSVEAddSubImm32:
6924 case Match_InvalidSVEAddSubImm64:
6925 case Match_InvalidSVECpyImm8:
6926 case Match_InvalidSVECpyImm16:
6927 case Match_InvalidSVECpyImm32:
6928 case Match_InvalidSVECpyImm64:
6929 case Match_InvalidIndexRange0_0:
6930 case Match_InvalidIndexRange1_1:
6931 case Match_InvalidIndexRange0_15:
6932 case Match_InvalidIndexRange0_7:
6933 case Match_InvalidIndexRange0_3:
6934 case Match_InvalidIndexRange0_1:
6935 case Match_InvalidSVEIndexRange0_63:
6936 case Match_InvalidSVEIndexRange0_31:
6937 case Match_InvalidSVEIndexRange0_15:
6938 case Match_InvalidSVEIndexRange0_7:
6939 case Match_InvalidSVEIndexRange0_3:
6940 case Match_InvalidLabel:
6941 case Match_InvalidComplexRotationEven:
6942 case Match_InvalidComplexRotationOdd:
6943 case Match_InvalidGPR64shifted8:
6944 case Match_InvalidGPR64shifted16:
6945 case Match_InvalidGPR64shifted32:
6946 case Match_InvalidGPR64shifted64:
6947 case Match_InvalidGPR64shifted128:
6948 case Match_InvalidGPR64NoXZRshifted8:
6949 case Match_InvalidGPR64NoXZRshifted16:
6950 case Match_InvalidGPR64NoXZRshifted32:
6951 case Match_InvalidGPR64NoXZRshifted64:
6952 case Match_InvalidGPR64NoXZRshifted128:
6953 case Match_InvalidZPR32UXTW8:
6954 case Match_InvalidZPR32UXTW16:
6955 case Match_InvalidZPR32UXTW32:
6956 case Match_InvalidZPR32UXTW64:
6957 case Match_InvalidZPR32SXTW8:
6958 case Match_InvalidZPR32SXTW16:
6959 case Match_InvalidZPR32SXTW32:
6960 case Match_InvalidZPR32SXTW64:
6961 case Match_InvalidZPR64UXTW8:
6962 case Match_InvalidZPR64SXTW8:
6963 case Match_InvalidZPR64UXTW16:
6964 case Match_InvalidZPR64SXTW16:
6965 case Match_InvalidZPR64UXTW32:
6966 case Match_InvalidZPR64SXTW32:
6967 case Match_InvalidZPR64UXTW64:
6968 case Match_InvalidZPR64SXTW64:
6969 case Match_InvalidZPR32LSL8:
6970 case Match_InvalidZPR32LSL16:
6971 case Match_InvalidZPR32LSL32:
6972 case Match_InvalidZPR32LSL64:
6973 case Match_InvalidZPR64LSL8:
6974 case Match_InvalidZPR64LSL16:
6975 case Match_InvalidZPR64LSL32:
6976 case Match_InvalidZPR64LSL64:
6977 case Match_InvalidZPR0:
6978 case Match_InvalidZPR8:
6979 case Match_InvalidZPR16:
6980 case Match_InvalidZPR32:
6981 case Match_InvalidZPR64:
6982 case Match_InvalidZPR128:
6983 case Match_InvalidZPR_3b8:
6984 case Match_InvalidZPR_3b16:
6985 case Match_InvalidZPR_3b32:
6986 case Match_InvalidZPR_4b8:
6987 case Match_InvalidZPR_4b16:
6988 case Match_InvalidZPR_4b32:
6989 case Match_InvalidZPR_4b64:
6990 case Match_InvalidSVEPPRorPNRAnyReg:
6991 case Match_InvalidSVEPPRorPNRBReg:
6992 case Match_InvalidSVEPredicateAnyReg:
6993 case Match_InvalidSVEPattern:
6994 case Match_InvalidSVEVecLenSpecifier:
6995 case Match_InvalidSVEPredicateBReg:
6996 case Match_InvalidSVEPredicateHReg:
6997 case Match_InvalidSVEPredicateSReg:
6998 case Match_InvalidSVEPredicateDReg:
6999 case Match_InvalidSVEPredicate3bAnyReg:
7000 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7001 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7002 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7003 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7004 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7005 case Match_InvalidSVEPNPredicateBReg:
7006 case Match_InvalidSVEPNPredicateHReg:
7007 case Match_InvalidSVEPNPredicateSReg:
7008 case Match_InvalidSVEPNPredicateDReg:
7009 case Match_InvalidSVEPredicateListMul2x8:
7010 case Match_InvalidSVEPredicateListMul2x16:
7011 case Match_InvalidSVEPredicateListMul2x32:
7012 case Match_InvalidSVEPredicateListMul2x64:
7013 case Match_InvalidSVEExactFPImmOperandHalfOne:
7014 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7015 case Match_InvalidSVEExactFPImmOperandZeroOne:
7016 case Match_InvalidMatrixTile16:
7017 case Match_InvalidMatrixTile32:
7018 case Match_InvalidMatrixTile64:
7019 case Match_InvalidMatrix:
7020 case Match_InvalidMatrix8:
7021 case Match_InvalidMatrix16:
7022 case Match_InvalidMatrix32:
7023 case Match_InvalidMatrix64:
7024 case Match_InvalidMatrixTileVectorH8:
7025 case Match_InvalidMatrixTileVectorH16:
7026 case Match_InvalidMatrixTileVectorH32:
7027 case Match_InvalidMatrixTileVectorH64:
7028 case Match_InvalidMatrixTileVectorH128:
7029 case Match_InvalidMatrixTileVectorV8:
7030 case Match_InvalidMatrixTileVectorV16:
7031 case Match_InvalidMatrixTileVectorV32:
7032 case Match_InvalidMatrixTileVectorV64:
7033 case Match_InvalidMatrixTileVectorV128:
7034 case Match_InvalidSVCR:
7035 case Match_InvalidMatrixIndexGPR32_12_15:
7036 case Match_InvalidMatrixIndexGPR32_8_11:
7037 case Match_InvalidLookupTable:
7038 case Match_InvalidZPRMul2_Lo8:
7039 case Match_InvalidZPRMul2_Hi8:
7040 case Match_InvalidZPRMul2_Lo16:
7041 case Match_InvalidZPRMul2_Hi16:
7042 case Match_InvalidZPRMul2_Lo32:
7043 case Match_InvalidZPRMul2_Hi32:
7044 case Match_InvalidZPRMul2_Lo64:
7045 case Match_InvalidZPRMul2_Hi64:
7046 case Match_InvalidZPR_K0:
7047 case Match_InvalidSVEVectorList2x8Mul2:
7048 case Match_InvalidSVEVectorList2x16Mul2:
7049 case Match_InvalidSVEVectorList2x32Mul2:
7050 case Match_InvalidSVEVectorList2x64Mul2:
7051 case Match_InvalidSVEVectorList2x128Mul2:
7052 case Match_InvalidSVEVectorList4x8Mul4:
7053 case Match_InvalidSVEVectorList4x16Mul4:
7054 case Match_InvalidSVEVectorList4x32Mul4:
7055 case Match_InvalidSVEVectorList4x64Mul4:
7056 case Match_InvalidSVEVectorList4x128Mul4:
7057 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7058 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7059 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7060 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7061 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7062 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7063 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7064 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7065 case Match_InvalidSVEVectorList3x0_3b:
7066 case Match_InvalidSVEVectorListStrided2x8:
7067 case Match_InvalidSVEVectorListStrided2x16:
7068 case Match_InvalidSVEVectorListStrided2x32:
7069 case Match_InvalidSVEVectorListStrided2x64:
7070 case Match_InvalidSVEVectorListStrided4x8:
7071 case Match_InvalidSVEVectorListStrided4x16:
7072 case Match_InvalidSVEVectorListStrided4x32:
7073 case Match_InvalidSVEVectorListStrided4x64:
7077 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
7081 static_cast<AArch64Operand &
>(*
Operands[ErrorInfo]).isScalarReg())
7082 MatchResult = Match_InvalidOperand;
7085 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
7086 if (ErrorLoc == SMLoc())
7088 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7096bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7103 SMLoc Loc = DirectiveID.
getLoc();
7104 if (IDVal ==
".arch")
7105 parseDirectiveArch(Loc);
7106 else if (IDVal ==
".cpu")
7107 parseDirectiveCPU(Loc);
7108 else if (IDVal ==
".tlsdesccall")
7109 parseDirectiveTLSDescCall(Loc,
false);
7110 else if (IDVal ==
".tlsauthdesccall")
7111 parseDirectiveTLSDescCall(Loc,
true);
7112 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7113 parseDirectiveLtorg(Loc);
7114 else if (IDVal ==
".unreq")
7115 parseDirectiveUnreq(Loc);
7116 else if (IDVal ==
".inst")
7117 parseDirectiveInst(Loc);
7118 else if (IDVal ==
".cfi_negate_ra_state")
7119 parseDirectiveCFINegateRAState();
7120 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7121 parseDirectiveCFINegateRAStateWithPC();
7122 else if (IDVal ==
".cfi_set_ra_state")
7123 parseDirectiveCFILLVMSetRAState();
7124 else if (IDVal ==
".cfi_b_key_frame")
7125 parseDirectiveCFIBKeyFrame();
7126 else if (IDVal ==
".cfi_mte_tagged_frame")
7127 parseDirectiveCFIMTETaggedFrame();
7128 else if (IDVal ==
".arch_extension")
7129 parseDirectiveArchExtension(Loc);
7130 else if (IDVal ==
".variant_pcs")
7131 parseDirectiveVariantPCS(Loc);
7134 parseDirectiveLOH(IDVal, Loc);
7137 }
else if (IsCOFF) {
7138 if (IDVal ==
".seh_stackalloc")
7139 parseDirectiveSEHAllocStack(Loc);
7140 else if (IDVal ==
".seh_endprologue")
7141 parseDirectiveSEHPrologEnd(Loc);
7142 else if (IDVal ==
".seh_save_r19r20_x")
7143 parseDirectiveSEHSaveR19R20X(Loc);
7144 else if (IDVal ==
".seh_save_fplr")
7145 parseDirectiveSEHSaveFPLR(Loc);
7146 else if (IDVal ==
".seh_save_fplr_x")
7147 parseDirectiveSEHSaveFPLRX(Loc);
7148 else if (IDVal ==
".seh_save_reg")
7149 parseDirectiveSEHSaveReg(Loc);
7150 else if (IDVal ==
".seh_save_reg_x")
7151 parseDirectiveSEHSaveRegX(Loc);
7152 else if (IDVal ==
".seh_save_regp")
7153 parseDirectiveSEHSaveRegP(Loc);
7154 else if (IDVal ==
".seh_save_regp_x")
7155 parseDirectiveSEHSaveRegPX(Loc);
7156 else if (IDVal ==
".seh_save_lrpair")
7157 parseDirectiveSEHSaveLRPair(Loc);
7158 else if (IDVal ==
".seh_save_freg")
7159 parseDirectiveSEHSaveFReg(Loc);
7160 else if (IDVal ==
".seh_save_freg_x")
7161 parseDirectiveSEHSaveFRegX(Loc);
7162 else if (IDVal ==
".seh_save_fregp")
7163 parseDirectiveSEHSaveFRegP(Loc);
7164 else if (IDVal ==
".seh_save_fregp_x")
7165 parseDirectiveSEHSaveFRegPX(Loc);
7166 else if (IDVal ==
".seh_set_fp")
7167 parseDirectiveSEHSetFP(Loc);
7168 else if (IDVal ==
".seh_add_fp")
7169 parseDirectiveSEHAddFP(Loc);
7170 else if (IDVal ==
".seh_nop")
7171 parseDirectiveSEHNop(Loc);
7172 else if (IDVal ==
".seh_save_next")
7173 parseDirectiveSEHSaveNext(Loc);
7174 else if (IDVal ==
".seh_startepilogue")
7175 parseDirectiveSEHEpilogStart(Loc);
7176 else if (IDVal ==
".seh_endepilogue")
7177 parseDirectiveSEHEpilogEnd(Loc);
7178 else if (IDVal ==
".seh_trap_frame")
7179 parseDirectiveSEHTrapFrame(Loc);
7180 else if (IDVal ==
".seh_pushframe")
7181 parseDirectiveSEHMachineFrame(Loc);
7182 else if (IDVal ==
".seh_context")
7183 parseDirectiveSEHContext(Loc);
7184 else if (IDVal ==
".seh_ec_context")
7185 parseDirectiveSEHECContext(Loc);
7186 else if (IDVal ==
".seh_clear_unwound_to_call")
7187 parseDirectiveSEHClearUnwoundToCall(Loc);
7188 else if (IDVal ==
".seh_pac_sign_lr")
7189 parseDirectiveSEHPACSignLR(Loc);
7190 else if (IDVal ==
".seh_save_any_reg")
7191 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7192 else if (IDVal ==
".seh_save_any_reg_p")
7193 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7194 else if (IDVal ==
".seh_save_any_reg_x")
7195 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7196 else if (IDVal ==
".seh_save_any_reg_px")
7197 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7198 else if (IDVal ==
".seh_allocz")
7199 parseDirectiveSEHAllocZ(Loc);
7200 else if (IDVal ==
".seh_save_zreg")
7201 parseDirectiveSEHSaveZReg(Loc);
7202 else if (IDVal ==
".seh_save_preg")
7203 parseDirectiveSEHSavePReg(Loc);
7207 if (IDVal ==
".aeabi_subsection")
7208 parseDirectiveAeabiSubSectionHeader(Loc);
7209 else if (IDVal ==
".aeabi_attribute")
7210 parseDirectiveAeabiAArch64Attr(Loc);
7223 if (!NoCrypto && Crypto) {
7226 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7227 ArchInfo == AArch64::ARMV8_3A) {
7231 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7232 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7233 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7234 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7235 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7236 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7242 }
else if (NoCrypto) {
7245 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7246 ArchInfo == AArch64::ARMV8_3A) {
7247 RequestedExtensions.
push_back(
"nosha2");
7250 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7251 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7252 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7253 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7254 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7255 ArchInfo == AArch64::ARMV9_4A) {
7257 RequestedExtensions.
push_back(
"nosha3");
7258 RequestedExtensions.
push_back(
"nosha2");
7270bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7271 SMLoc CurLoc = getLoc();
7273 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7274 StringRef Arch, ExtensionString;
7275 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7279 return Error(CurLoc,
"unknown arch name");
7285 std::vector<StringRef> AArch64Features;
7286 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7289 MCSubtargetInfo &STI = copySTI();
7290 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7292 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7295 if (!ExtensionString.
empty())
7296 ExtensionString.
split(RequestedExtensions,
'+');
7301 for (
auto Name : RequestedExtensions) {
7305 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7312 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7320 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7321 setAvailableFeatures(Features);
7323 getTargetStreamer().emitDirectiveArch(Name);
7329bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7330 SMLoc ExtLoc = getLoc();
7332 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7337 bool EnableFeature =
true;
7338 StringRef
Name = FullName;
7339 if (
Name.starts_with_insensitive(
"no")) {
7340 EnableFeature =
false;
7349 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7351 MCSubtargetInfo &STI = copySTI();
7356 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7357 setAvailableFeatures(Features);
7359 getTargetStreamer().emitDirectiveArchExtension(FullName);
7365bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7366 SMLoc CurLoc = getLoc();
7368 StringRef CPU, ExtensionString;
7369 std::tie(CPU, ExtensionString) =
7370 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7376 if (!ExtensionString.
empty())
7377 ExtensionString.
split(RequestedExtensions,
'+');
7381 Error(CurLoc,
"unknown CPU name");
7386 MCSubtargetInfo &STI = copySTI();
7390 for (
auto Name : RequestedExtensions) {
7394 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7401 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7409 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7410 setAvailableFeatures(Features);
7416bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7418 return Error(Loc,
"expected expression following '.inst' directive");
7420 auto parseOp = [&]() ->
bool {
7422 const MCExpr *Expr =
nullptr;
7423 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7426 if (check(!
Value, L,
"expected constant expression"))
7428 getTargetStreamer().emitInst(
Value->getValue());
7432 return parseMany(parseOp);
7438bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth) {
7440 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7451 Inst.
setOpcode(IsAuth ? AArch64::TLSAUTHDESCCALL : AArch64::TLSDESCCALL);
7454 getParser().getStreamer().emitInstruction(Inst, getSTI());
7460bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7464 return TokError(
"expected an identifier or a number in directive");
7467 int64_t
Id = getTok().getIntVal();
7469 return TokError(
"invalid numeric identifier in directive");
7472 StringRef
Name = getTok().getIdentifier();
7478 return TokError(
"invalid identifier in directive");
7486 assert(NbArgs != -1 &&
"Invalid number of arguments");
7489 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7491 if (getParser().parseIdentifier(Name))
7492 return TokError(
"expected identifier in directive");
7495 if (Idx + 1 == NbArgs)
7503 getStreamer().emitLOHDirective(Kind, Args);
7509bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7512 getTargetStreamer().emitCurrentConstantPool();
7518bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7520 SMLoc SRegLoc = getLoc();
7521 RegKind RegisterKind = RegKind::Scalar;
7523 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7527 RegisterKind = RegKind::NeonVector;
7528 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7534 return Error(SRegLoc,
"vector register without type specifier expected");
7539 RegisterKind = RegKind::SVEDataVector;
7541 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7547 return Error(SRegLoc,
7548 "sve vector register without type specifier expected");
7553 RegisterKind = RegKind::SVEPredicateVector;
7554 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7560 return Error(SRegLoc,
7561 "sve predicate register without type specifier expected");
7565 return Error(SRegLoc,
"register name or alias expected");
7571 auto pair = std::make_pair(RegisterKind, RegNum);
7572 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7573 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7580bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7582 return TokError(
"unexpected input in .unreq directive.");
7583 RegisterReqs.
erase(getTok().getIdentifier().lower());
7588bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7591 getStreamer().emitCFINegateRAState();
7595bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7598 getStreamer().emitCFINegateRAStateWithPC();
7605bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7607 if (getParser().parseAbsoluteExpression(State))
7612 SMLoc ExprLoc = getLoc();
7613 if (getParser().parseExpression(Expr))
7618 getStreamer().emitCFILLVMSetRAState(
7619 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7621 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7625 "expected an integer offset or a symbol for .cfi_set_ra_state");
7632bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7635 getStreamer().emitCFIBKeyFrame();
7641bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7644 getStreamer().emitCFIMTETaggedFrame();
7650bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7652 if (getParser().parseIdentifier(Name))
7653 return TokError(
"expected symbol name");
7656 getTargetStreamer().emitDirectiveVariantPCS(
7663bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7665 if (parseImmExpr(
Size))
7667 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7673bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7674 getTargetStreamer().emitARM64WinCFIPrologEnd();
7680bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7682 if (parseImmExpr(
Offset))
7684 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7690bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7692 if (parseImmExpr(
Offset))
7694 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7700bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7702 if (parseImmExpr(
Offset))
7704 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7710bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7713 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7714 parseComma() || parseImmExpr(
Offset))
7716 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7722bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7725 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7726 parseComma() || parseImmExpr(
Offset))
7728 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7734bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7737 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7738 parseComma() || parseImmExpr(
Offset))
7740 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7746bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7749 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7750 parseComma() || parseImmExpr(
Offset))
7752 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7758bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7762 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7763 parseComma() || parseImmExpr(
Offset))
7765 if (check(((
Reg - 19) % 2 != 0), L,
7766 "expected register with even offset from x19"))
7768 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7774bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7777 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7778 parseComma() || parseImmExpr(
Offset))
7780 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7786bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7789 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7790 parseComma() || parseImmExpr(
Offset))
7792 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7798bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7801 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7802 parseComma() || parseImmExpr(
Offset))
7804 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7810bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7813 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7814 parseComma() || parseImmExpr(
Offset))
7816 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7822bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7823 getTargetStreamer().emitARM64WinCFISetFP();
7829bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7831 if (parseImmExpr(
Size))
7833 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7839bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7840 getTargetStreamer().emitARM64WinCFINop();
7846bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7847 getTargetStreamer().emitARM64WinCFISaveNext();
7853bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7854 getTargetStreamer().emitARM64WinCFIEpilogStart();
7860bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7861 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7867bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7868 getTargetStreamer().emitARM64WinCFITrapFrame();
7874bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7875 getTargetStreamer().emitARM64WinCFIMachineFrame();
7881bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7882 getTargetStreamer().emitARM64WinCFIContext();
7888bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7889 getTargetStreamer().emitARM64WinCFIECContext();
7895bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7896 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7902bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7903 getTargetStreamer().emitARM64WinCFIPACSignLR();
7912bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7917 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7918 parseComma() || parseImmExpr(
Offset))
7921 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7922 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7923 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7924 return Error(L,
"invalid save_any_reg offset");
7925 unsigned EncodedReg;
7926 if (
Reg == AArch64::FP)
7928 else if (
Reg == AArch64::LR)
7931 EncodedReg =
Reg - AArch64::X0;
7933 if (
Reg == AArch64::LR)
7934 return Error(Start,
"lr cannot be paired with another register");
7936 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7938 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7941 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7943 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7945 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7946 unsigned EncodedReg =
Reg - AArch64::D0;
7947 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7948 return Error(L,
"invalid save_any_reg offset");
7950 if (
Reg == AArch64::D31)
7951 return Error(Start,
"d31 cannot be paired with another register");
7953 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7955 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7958 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7960 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7962 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7963 unsigned EncodedReg =
Reg - AArch64::Q0;
7965 return Error(L,
"invalid save_any_reg offset");
7967 if (
Reg == AArch64::Q31)
7968 return Error(Start,
"q31 cannot be paired with another register");
7970 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7972 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7975 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7977 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7980 return Error(Start,
"save_any_reg register must be x, q or d register");
7987bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7989 if (parseImmExpr(
Offset))
7991 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7997bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8002 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8005 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8006 "expected register in range z8 to z23"))
8008 if (parseComma() || parseImmExpr(
Offset))
8010 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8016bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8021 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8024 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8025 "expected register in range p4 to p15"))
8027 if (parseComma() || parseImmExpr(
Offset))
8029 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8033bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8039 MCAsmParser &Parser = getParser();
8042 StringRef SubsectionName;
8053 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8054 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8059 if (SubsectionExists) {
8060 getTargetStreamer().emitAttributesSubsection(
8063 SubsectionExists->IsOptional),
8065 SubsectionExists->ParameterType));
8071 "Could not switch to subsection '" + SubsectionName +
8072 "' using subsection name, subsection has not been defined");
8095 if (SubsectionExists) {
8096 if (IsOptional != SubsectionExists->IsOptional) {
8098 "optionality mismatch! subsection '" + SubsectionName +
8099 "' already exists with optionality defined as '" +
8101 SubsectionExists->IsOptional) +
8109 "optionality parameter not found, expected required|optional");
8116 "aeabi_feature_and_bits must be marked as optional");
8123 "aeabi_pauthabi must be marked as required");
8143 if (SubsectionExists) {
8144 if (
Type != SubsectionExists->ParameterType) {
8146 "type mismatch! subsection '" + SubsectionName +
8147 "' already exists with type defined as '" +
8149 SubsectionExists->ParameterType) +
8157 "type parameter not found, expected uleb128|ntbs");
8165 SubsectionName +
" must be marked as ULEB128");
8174 "attributes subsection header directive");
8178 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8183bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8187 MCAsmParser &Parser = getParser();
8189 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8190 getTargetStreamer().getActiveAttributesSubsection();
8191 if (
nullptr == ActiveSubsection) {
8193 "no active subsection, build attribute can not be added");
8196 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8197 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8205 ActiveSubsectionName)
8208 StringRef TagStr =
"";
8211 Tag = getTok().getIntVal();
8214 switch (ActiveSubsectionID) {
8219 "' \nExcept for public subsections, "
8220 "tags have to be an unsigned int.");
8227 TagStr +
"' for subsection '" +
8228 ActiveSubsectionName +
"'");
8236 TagStr +
"' for subsection '" +
8237 ActiveSubsectionName +
"'");
8255 unsigned ValueInt = unsigned(-1);
8256 std::string ValueStr =
"";
8261 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8264 ValueInt = getTok().getIntVal();
8269 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8277 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8288 if (0 != ValueInt && 1 != ValueInt) {
8290 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8291 "' options are 0|1");
8300 "unexpected token for AArch64 build attributes tag and value "
8301 "attribute directive");
8305 if (
unsigned(-1) != ValueInt) {
8306 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8308 if (
"" != ValueStr) {
8309 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8315bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8316 SMLoc Loc = getLoc();
8318 return TokError(
"expected '%' relocation specifier");
8319 StringRef
Identifier = getParser().getTok().getIdentifier();
8322 return TokError(
"invalid relocation specifier");
8328 const MCExpr *SubExpr;
8329 if (getParser().parseParenExpression(SubExpr,
E))
8336bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8339 return parseExprWithSpecifier(Res, EndLoc);
8341 if (getParser().parseExpression(Res))
8343 MCAsmParser &Parser = getParser();
8347 return Error(getLoc(),
"expected relocation specifier");
8350 SMLoc Loc = getLoc();
8352 if (Identifier ==
"auth")
8353 return parseAuthExpr(Res, EndLoc);
8357 if (Identifier ==
"got")
8361 return Error(Loc,
"invalid relocation specifier");
8366 return Error(Loc,
"@ specifier only allowed after a symbol");
8369 std::optional<MCBinaryExpr::Opcode> Opcode;
8377 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8388bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8389 MCAsmParser &Parser = getParser();
8391 AsmToken Tok = Parser.
getTok();
8398 return TokError(
"expected key name");
8403 return TokError(
"invalid key '" + KeyStr +
"'");
8410 return TokError(
"expected integer discriminator");
8414 return TokError(
"integer discriminator " + Twine(Discriminator) +
8415 " out of range [0, 0xFFFF]");
8418 bool UseAddressDiversity =
false;
8423 return TokError(
"expected 'addr'");
8424 UseAddressDiversity =
true;
8433 UseAddressDiversity, Ctx, Res->
getLoc());
8437bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8446 ELFSpec = AE->getSpecifier();
8447 Expr = AE->getSubExpr();
8487#define GET_REGISTER_MATCHER
8488#define GET_SUBTARGET_FEATURE_NAME
8489#define GET_MATCHER_IMPLEMENTATION
8490#define GET_MNEMONIC_SPELL_CHECKER
8491#include "AArch64GenAsmMatcher.inc"
8497 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8499 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8501 return Match_InvalidOperand;
8504 return Match_InvalidOperand;
8505 if (CE->getValue() == ExpectedVal)
8506 return Match_Success;
8507 return Match_InvalidOperand;
8512 return Match_InvalidOperand;
8518 if (
Op.isTokenEqual(
"za"))
8519 return Match_Success;
8520 return Match_InvalidOperand;
8526#define MATCH_HASH(N) \
8527 case MCK__HASH_##N: \
8528 return MatchesOpImmediate(N);
8554#define MATCH_HASH_MINUS(N) \
8555 case MCK__HASH__MINUS_##N: \
8556 return MatchesOpImmediate(-N);
8560#undef MATCH_HASH_MINUS
8569 return Error(S,
"expected register");
8571 MCRegister FirstReg;
8572 ParseStatus Res = tryParseScalarRegister(FirstReg);
8574 return Error(S,
"expected first even register of a consecutive same-size "
8575 "even/odd register pair");
8577 const MCRegisterClass &WRegClass =
8578 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8579 const MCRegisterClass &XRegClass =
8580 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8582 bool isXReg = XRegClass.
contains(FirstReg),
8583 isWReg = WRegClass.
contains(FirstReg);
8584 if (!isXReg && !isWReg)
8585 return Error(S,
"expected first even register of a consecutive same-size "
8586 "even/odd register pair");
8588 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8591 if (FirstEncoding & 0x1)
8592 return Error(S,
"expected first even register of a consecutive same-size "
8593 "even/odd register pair");
8596 return Error(getLoc(),
"expected comma");
8601 MCRegister SecondReg;
8602 Res = tryParseScalarRegister(SecondReg);
8604 return Error(
E,
"expected second odd register of a consecutive same-size "
8605 "even/odd register pair");
8608 (isXReg && !XRegClass.
contains(SecondReg)) ||
8609 (isWReg && !WRegClass.
contains(SecondReg)))
8610 return Error(
E,
"expected second odd register of a consecutive same-size "
8611 "even/odd register pair");
8616 FirstReg, AArch64::sube64,
8617 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8620 FirstReg, AArch64::sube32,
8621 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8624 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8630template <
bool ParseShiftExtend,
bool ParseSuffix>
8632 const SMLoc S = getLoc();
8638 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8643 if (ParseSuffix &&
Kind.empty())
8650 unsigned ElementWidth = KindRes->second;
8654 Operands.push_back(AArch64Operand::CreateVectorReg(
8655 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8657 ParseStatus Res = tryParseVectorIndex(
Operands);
8668 Res = tryParseOptionalShiftExtend(ExtOpnd);
8672 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8673 Operands.push_back(AArch64Operand::CreateVectorReg(
8674 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8675 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8676 Ext->hasShiftExtendAmount()));
8682 SMLoc
SS = getLoc();
8683 const AsmToken &TokE = getTok();
8688 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8693 int64_t Pattern = Pat->Encoding;
8694 assert(Pattern >= 0 && Pattern < 32);
8706 SMLoc
SS = getLoc();
8707 const AsmToken &TokE = getTok();
8709 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8715 Pattern = Pat->Encoding;
8716 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8726 SMLoc
SS = getLoc();
8729 if (!tryParseScalarRegister(XReg).isSuccess())
8735 XReg, AArch64::x8sub_0,
8736 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8739 "expected an even-numbered x-register in the range [x0,x22]");
8742 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8756 if (getParser().parseExpression(ImmF))
8766 SMLoc
E = getTok().getLoc();
8768 if (getParser().parseExpression(ImmL))
8775 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
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.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
LLVM_ABI std::string lower() const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI SubsectionType getTypeID(StringRef Type)
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
LLVM_ABI StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
LLVM_ABI StringRef getSubsectionTypeUnknownError()
LLVM_ABI SubsectionOptional getOptionalID(StringRef Optional)
LLVM_ABI StringRef getSubsectionOptionalUnknownError()
LLVM_ABI FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
LLVM_ABI VendorID getVendorID(StringRef const Vendor)
LLVM_ABI PauthABITags getPauthABITagsID(StringRef PauthABITag)
LLVM_ABI StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
uint32_t parseGenericRegister(StringRef Name)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool isSVEAddSubImm(int64_t Imm)
Returns true if Imm is valid for ADD/SUB.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static bool isSVECpyImm(int64_t Imm)
Returns true if Imm is valid for CPY/DUP.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
VectorKind
Distinguishes the vector flavors that ABIs have to treat differently.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static int MCLOHNameToId(StringRef Name)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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