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> DiagnosticPredicate isSImm()
const {
780 return 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> DiagnosticPredicate isUImm12Offset()
const {
891 return DiagnosticPredicate(isSymbolicUImm12Offset(
getImm()));
894 if ((Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000)
899 template <
int N,
int M> DiagnosticPredicate isImmInRange()
const {
906 if (Val >=
N && Val <= M)
911 bool isHinteUImm16()
const {
918 return Val >= 0 && Val <= 65535 &&
919 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
924 template <
typename T>
925 bool isLogicalImm()
const {
942 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
944 bool isImmRange()
const {
return Kind == k_ImmRange; }
949 template <
unsigned W
idth>
950 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
951 if (isShiftedImm() && Width == getShiftedImmShift())
953 return std::make_pair(
CE->getValue(), Width);
957 int64_t Val =
CE->getValue();
959 return std::make_pair(Val >> Width, Width);
961 return std::make_pair(Val, 0u);
967 bool isAddSubImm()
const {
968 if (!isShiftedImm() && !isImm())
974 if (isShiftedImm()) {
975 unsigned Shift = ShiftedImm.ShiftAmount;
976 Expr = ShiftedImm.Val;
977 if (Shift != 0 && Shift != 12)
986 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1002 if (
auto ShiftedVal = getShiftedVal<12>())
1003 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1010 bool isAddSubImmNeg()
const {
1011 if (!isShiftedImm() && !isImm())
1015 if (
auto ShiftedVal = getShiftedVal<12>())
1016 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1026 template <
typename T>
1027 DiagnosticPredicate isSVECpyImm()
const {
1031 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1032 std::is_same<int8_t, T>::value;
1033 if (
auto ShiftedImm = getShiftedVal<8>())
1034 if (!(IsByte && ShiftedImm->second) &&
1036 << ShiftedImm->second))
1045 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1049 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1050 std::is_same<int8_t, T>::value;
1051 if (
auto ShiftedImm = getShiftedVal<8>())
1052 if (!(IsByte && ShiftedImm->second) &&
1054 << ShiftedImm->second))
1060 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1061 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1066 bool isCondCode()
const {
return Kind == k_CondCode; }
1068 bool isSIMDImmType10()
const {
1078 bool isBranchTarget()
const {
1087 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1088 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1098 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1108 bool isMovWSymbolG3()
const {
1112 bool isMovWSymbolG2()
const {
1119 bool isMovWSymbolG1()
const {
1127 bool isMovWSymbolG0()
const {
1135 template<
int RegW
idth,
int Shift>
1136 bool isMOVZMovAlias()
const {
1137 if (!isImm())
return false;
1150 template<
int RegW
idth,
int Shift>
1151 bool isMOVNMovAlias()
const {
1152 if (!isImm())
return false;
1155 if (!CE)
return false;
1161 bool isFPImm()
const {
1162 return Kind == k_FPImm &&
1166 bool isBarrier()
const {
1167 return Kind == k_Barrier && !getBarriernXSModifier();
1169 bool isBarriernXS()
const {
1170 return Kind == k_Barrier && getBarriernXSModifier();
1172 bool isSysReg()
const {
return Kind == k_SysReg; }
1174 bool isMRSSystemRegister()
const {
1175 if (!isSysReg())
return false;
1177 return SysReg.MRSReg != -1U;
1180 bool isMSRSystemRegister()
const {
1181 if (!isSysReg())
return false;
1182 return SysReg.MSRReg != -1U;
1185 bool isSystemPStateFieldWithImm0_1()
const {
1186 if (!isSysReg())
return false;
1187 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1190 bool isSystemPStateFieldWithImm0_15()
const {
1193 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1196 bool isSVCR()
const {
1199 return SVCR.PStateField != -1U;
1202 bool isReg()
const override {
1203 return Kind == k_Register;
1206 bool isVectorList()
const {
return Kind == k_VectorList; }
1208 bool isScalarReg()
const {
1209 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1212 bool isNeonVectorReg()
const {
1213 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1216 bool isNeonVectorRegLo()
const {
1217 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1218 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1219 .contains(
Reg.Reg) ||
1220 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1221 .contains(
Reg.Reg));
1224 bool isNeonVectorReg0to7()
const {
1225 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1226 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1227 .contains(
Reg.Reg));
1230 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1231 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1233 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1236 case AArch64::PPRRegClassID:
1237 case AArch64::PPR_3bRegClassID:
1238 case AArch64::PPR_p8to15RegClassID:
1239 case AArch64::PNRRegClassID:
1240 case AArch64::PNR_p8to15RegClassID:
1241 case AArch64::PPRorPNRRegClassID:
1242 RK = RegKind::SVEPredicateAsCounter;
1248 return (Kind == k_Register &&
Reg.Kind == RK) &&
1249 getAArch64MCRegisterClass(Class).contains(
getReg());
1252 template <
unsigned Class>
bool isSVEVectorReg()
const {
1255 case AArch64::ZPRRegClassID:
1256 case AArch64::ZPR_3bRegClassID:
1257 case AArch64::ZPR_4bRegClassID:
1258 case AArch64::ZPRMul2_LoRegClassID:
1259 case AArch64::ZPRMul2_HiRegClassID:
1260 case AArch64::ZPR_KRegClassID:
1261 RK = RegKind::SVEDataVector;
1263 case AArch64::PPRRegClassID:
1264 case AArch64::PPR_3bRegClassID:
1265 case AArch64::PPR_p8to15RegClassID:
1266 case AArch64::PNRRegClassID:
1267 case AArch64::PNR_p8to15RegClassID:
1268 case AArch64::PPRorPNRRegClassID:
1269 RK = RegKind::SVEPredicateVector;
1275 return (Kind == k_Register &&
Reg.Kind == RK) &&
1276 getAArch64MCRegisterClass(Class).contains(
getReg());
1279 template <
unsigned Class>
bool isFPRasZPR()
const {
1280 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1281 getAArch64MCRegisterClass(Class).contains(
getReg());
1284 template <
int ElementW
idth,
unsigned Class>
1285 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1286 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1289 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1295 template <
int ElementW
idth,
unsigned Class>
1296 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1297 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1298 Reg.Kind != RegKind::SVEPredicateVector))
1301 if ((isSVEPredicateAsCounterReg<Class>() ||
1302 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1303 Reg.ElementWidth == ElementWidth)
1309 template <
int ElementW
idth,
unsigned Class>
1310 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1311 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1314 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1320 template <
int ElementW
idth,
unsigned Class>
1321 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1322 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1325 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1331 template <
int ElementWidth,
unsigned Class,
1333 bool ShiftWidthAlwaysSame>
1334 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1335 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1336 if (!VectorMatch.isMatch())
1342 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1345 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1348 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1354 bool isGPR32as64()
const {
1355 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1356 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1360 bool isGPR64as32()
const {
1361 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1362 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1366 bool isGPR64x8()
const {
1367 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1368 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1372 bool isWSeqPair()
const {
1373 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1374 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1378 bool isXSeqPair()
const {
1379 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1380 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1384 bool isSyspXzrPair()
const {
1388 template<
int64_t Angle,
int64_t Remainder>
1389 DiagnosticPredicate isComplexRotation()
const {
1398 if (
Value % Angle == Remainder &&
Value <= 270)
1403 template <
unsigned RegClassID>
bool isGPR64()
const {
1404 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1405 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1408 template <
unsigned RegClassID,
int ExtW
idth>
1409 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1410 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1414 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1421 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1422 bool isImplicitlyTypedVectorList()
const {
1423 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1424 VectorList.NumElements == 0 &&
1426 (!IsConsecutive || (VectorList.Stride == 1));
1429 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1430 unsigned ElementWidth,
unsigned Stride = 1>
1431 bool isTypedVectorList()
const {
1432 if (Kind != k_VectorList)
1434 if (VectorList.Count != NumRegs)
1436 if (VectorList.RegisterKind != VectorKind)
1438 if (VectorList.ElementWidth != ElementWidth)
1440 if (VectorList.Stride != Stride)
1442 return VectorList.NumElements == NumElements;
1445 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1446 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1448 DiagnosticPredicate isTypedVectorListInRange()
const {
1450 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1453 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1454 (VectorList.Reg - FirstReg) % Multiple != 0)
1459 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned Stride,
1460 unsigned ElementWidth>
1461 DiagnosticPredicate isTypedVectorListStrided()
const {
1462 bool Res = isTypedVectorList<
VectorKind, NumRegs, 0,
1463 ElementWidth, Stride>();
1466 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1467 ((VectorList.Reg >= AArch64::Z16) &&
1468 (VectorList.Reg < (AArch64::Z16 + Stride))))
1473 template <
int Min,
int Max>
1474 DiagnosticPredicate isVectorIndex()
const {
1475 if (Kind != k_VectorIndex)
1477 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1482 bool isToken()
const override {
return Kind == k_Token; }
1484 bool isTokenEqual(StringRef Str)
const {
1485 return Kind == k_Token &&
getToken() == Str;
1487 bool isSysCR()
const {
return Kind == k_SysCR; }
1488 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1489 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1490 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1491 bool isShifter()
const {
1492 if (!isShiftExtend())
1501 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1502 if (Kind != k_FPImm)
1505 if (getFPImmIsExact()) {
1507 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1509 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1512 APFloat RealVal(APFloat::IEEEdouble());
1514 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1515 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1518 if (
getFPImm().bitwiseIsEqual(RealVal))
1525 template <
unsigned ImmA,
unsigned ImmB>
1526 DiagnosticPredicate isExactFPImm()
const {
1528 if ((Res = isExactFPImm<ImmA>()))
1530 if ((Res = isExactFPImm<ImmB>()))
1535 bool isExtend()
const {
1536 if (!isShiftExtend())
1545 getShiftExtendAmount() <= 4;
1548 bool isExtend64()
const {
1558 bool isExtendLSL64()
const {
1564 getShiftExtendAmount() <= 4;
1567 bool isLSLImm3Shift()
const {
1568 if (!isShiftExtend())
1574 template<
int W
idth>
bool isMemXExtend()
const {
1579 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1580 getShiftExtendAmount() == 0);
1583 template<
int W
idth>
bool isMemWExtend()
const {
1588 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1589 getShiftExtendAmount() == 0);
1592 template <
unsigned w
idth>
1593 bool isArithmeticShifter()
const {
1603 template <
unsigned w
idth>
1604 bool isLogicalShifter()
const {
1612 getShiftExtendAmount() < width;
1615 bool isMovImm32Shifter()
const {
1623 uint64_t Val = getShiftExtendAmount();
1624 return (Val == 0 || Val == 16);
1627 bool isMovImm64Shifter()
const {
1635 uint64_t Val = getShiftExtendAmount();
1636 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1639 bool isLogicalVecShifter()
const {
1644 unsigned Shift = getShiftExtendAmount();
1646 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1649 bool isLogicalVecHalfWordShifter()
const {
1650 if (!isLogicalVecShifter())
1654 unsigned Shift = getShiftExtendAmount();
1656 (Shift == 0 || Shift == 8);
1659 bool isMoveVecShifter()
const {
1660 if (!isShiftExtend())
1664 unsigned Shift = getShiftExtendAmount();
1666 (Shift == 8 || Shift == 16);
1675 bool isSImm9OffsetFB()
const {
1676 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1679 bool isAdrpLabel()
const {
1686 int64_t Val =
CE->getValue();
1687 int64_t Min = - (4096 * (1LL << (21 - 1)));
1688 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1689 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1695 bool isAdrLabel()
const {
1702 int64_t Val =
CE->getValue();
1703 int64_t Min = - (1LL << (21 - 1));
1704 int64_t
Max = ((1LL << (21 - 1)) - 1);
1705 return Val >= Min && Val <=
Max;
1711 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1712 DiagnosticPredicate isMatrixRegOperand()
const {
1715 if (getMatrixKind() != Kind ||
1716 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1717 EltSize != getMatrixElementWidth())
1722 bool isPAuthPCRelLabel16Operand()
const {
1734 return (Val <= 0) && (Val > -(1 << 18));
1737 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1747 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1748 assert(
N == 1 &&
"Invalid number of operands!");
1752 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1753 assert(
N == 1 &&
"Invalid number of operands!");
1757 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1758 assert(
N == 1 &&
"Invalid number of operands!");
1760 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1762 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1769 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1770 assert(
N == 1 &&
"Invalid number of operands!");
1772 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1774 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1781 template <
int W
idth>
1782 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1785 case 8:
Base = AArch64::B0;
break;
1786 case 16:
Base = AArch64::H0;
break;
1787 case 32:
Base = AArch64::S0;
break;
1788 case 64:
Base = AArch64::D0;
break;
1789 case 128:
Base = AArch64::Q0;
break;
1796 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1797 assert(
N == 1 &&
"Invalid number of operands!");
1800 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1801 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1805 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1806 assert(
N == 1 &&
"Invalid number of operands!");
1811 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1812 assert(
N == 1 &&
"Invalid number of operands!");
1813 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1818 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1819 assert(
N == 1 &&
"Invalid number of operands!");
1820 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1825 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1826 assert(
N == 1 &&
"Invalid number of operands!");
1830 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1831 assert(
N == 1 &&
"Invalid number of operands!");
1835 enum VecListIndexType {
1836 VecListIdx_DReg = 0,
1837 VecListIdx_QReg = 1,
1838 VecListIdx_ZReg = 2,
1839 VecListIdx_PReg = 3,
1842 template <VecListIndexType RegTy,
unsigned NumRegs,
1843 bool IsConsecutive =
false>
1844 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1845 assert(
N == 1 &&
"Invalid number of operands!");
1846 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1847 "Expected consecutive registers");
1848 static const unsigned FirstRegs[][5] = {
1850 AArch64::D0, AArch64::D0_D1,
1851 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1853 AArch64::Q0, AArch64::Q0_Q1,
1854 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1856 AArch64::Z0, AArch64::Z0_Z1,
1857 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1859 AArch64::P0, AArch64::P0_P1 }
1862 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1863 " NumRegs must be <= 4 for ZRegs");
1865 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1866 " NumRegs must be <= 2 for PRegs");
1868 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1870 FirstRegs[(
unsigned)RegTy][0]));
1873 template <
unsigned NumRegs>
1874 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1875 assert(
N == 1 &&
"Invalid number of operands!");
1876 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1880 if (getVectorListStart() < AArch64::Z16) {
1881 assert((getVectorListStart() < AArch64::Z8) &&
1882 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1884 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1886 assert((getVectorListStart() < AArch64::Z24) &&
1887 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1889 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1893 if (getVectorListStart() < AArch64::Z16) {
1894 assert((getVectorListStart() < AArch64::Z4) &&
1895 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1897 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1899 assert((getVectorListStart() < AArch64::Z20) &&
1900 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1902 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1910 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1911 assert(
N == 1 &&
"Invalid number of operands!");
1912 unsigned RegMask = getMatrixTileListRegMask();
1913 assert(RegMask <= 0xFF &&
"Invalid mask!");
1917 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1918 assert(
N == 1 &&
"Invalid number of operands!");
1922 template <
unsigned ImmIs0,
unsigned ImmIs1>
1923 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1924 assert(
N == 1 &&
"Invalid number of operands!");
1925 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1929 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1930 assert(
N == 1 &&
"Invalid number of operands!");
1937 template <
int Adj>
void addAdjImmOperands(MCInst &Inst,
unsigned N)
const {
1938 assert(
N == 1 &&
"Invalid number of operands!");
1943 template <
int Shift>
1944 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1945 assert(
N == 2 &&
"Invalid number of operands!");
1946 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1949 }
else if (isShiftedImm()) {
1950 addExpr(Inst, getShiftedImmVal());
1958 template <
int Shift>
1959 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1960 assert(
N == 2 &&
"Invalid number of operands!");
1961 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1968 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1969 assert(
N == 1 &&
"Invalid number of operands!");
1973 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1974 assert(
N == 1 &&
"Invalid number of operands!");
1982 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1983 addImmOperands(Inst,
N);
1987 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1988 assert(
N == 1 &&
"Invalid number of operands!");
1998 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1999 assert(
N == 1 &&
"Invalid number of operands!");
2004 template <
int Scale>
2005 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2006 assert(
N == 1 &&
"Invalid number of operands!");
2011 template <
int Scale>
2012 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2013 assert(
N == 1 &&
"Invalid number of operands!");
2017 template <
typename T>
2018 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2019 assert(
N == 1 &&
"Invalid number of operands!");
2021 std::make_unsigned_t<T> Val = MCE->
getValue();
2026 template <
typename T>
2027 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2028 assert(
N == 1 &&
"Invalid number of operands!");
2030 std::make_unsigned_t<T> Val = ~MCE->getValue();
2035 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2036 assert(
N == 1 &&
"Invalid number of operands!");
2042 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2046 assert(
N == 1 &&
"Invalid number of operands!");
2052 assert(MCE &&
"Invalid constant immediate operand!");
2056 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2060 assert(
N == 1 &&
"Invalid number of operands!");
2069 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2073 assert(
N == 1 &&
"Invalid number of operands!");
2079 assert(MCE &&
"Invalid constant immediate operand!");
2083 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2087 assert(
N == 1 &&
"Invalid number of operands!");
2093 assert(MCE &&
"Invalid constant immediate operand!");
2097 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2101 assert(
N == 1 &&
"Invalid number of operands!");
2107 assert(MCE &&
"Invalid constant immediate operand!");
2111 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2112 assert(
N == 1 &&
"Invalid number of operands!");
2117 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2118 assert(
N == 1 &&
"Invalid number of operands!");
2122 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2123 assert(
N == 1 &&
"Invalid number of operands!");
2127 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2128 assert(
N == 1 &&
"Invalid number of operands!");
2133 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2134 assert(
N == 1 &&
"Invalid number of operands!");
2139 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2140 assert(
N == 1 &&
"Invalid number of operands!");
2145 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2146 assert(
N == 1 &&
"Invalid number of operands!");
2151 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2152 assert(
N == 1 &&
"Invalid number of operands!");
2157 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2158 assert(
N == 1 &&
"Invalid number of operands!");
2162 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2167 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2168 assert(
N == 1 &&
"Invalid number of operands!");
2172 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2173 assert(
N == 1 &&
"Invalid number of operands!");
2179 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2181 unsigned Imm = getShiftExtendAmount();
2185 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2186 assert(
N == 1 &&
"Invalid number of operands!");
2191 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2194 if (
Reg != AArch64::XZR)
2200 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2201 assert(
N == 1 &&
"Invalid number of operands!");
2208 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2209 assert(
N == 1 &&
"Invalid number of operands!");
2216 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2217 assert(
N == 2 &&
"Invalid number of operands!");
2228 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2229 assert(
N == 2 &&
"Invalid number of operands!");
2237 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2238 assert(
N == 1 &&
"Invalid number of operands!");
2250 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2251 assert(
N == 1 &&
"Invalid number of operands!");
2258 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2259 assert(
N == 1 &&
"Invalid number of operands!");
2264 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2265 assert(
N == 1 &&
"Invalid number of operands!");
2270 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2272 static std::unique_ptr<AArch64Operand>
2273 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2274 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2275 Op->Tok.Data = Str.data();
2276 Op->Tok.Length = Str.size();
2277 Op->Tok.IsSuffix = IsSuffix;
2283 static std::unique_ptr<AArch64Operand>
2284 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2285 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2287 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2288 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2290 Op->Reg.Kind = Kind;
2291 Op->Reg.ElementWidth = 0;
2292 Op->Reg.EqualityTy = EqTy;
2293 Op->Reg.ShiftExtend.Type = ExtTy;
2294 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2295 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2301 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2302 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2304 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2305 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2306 Kind == RegKind::SVEPredicateVector ||
2307 Kind == RegKind::SVEPredicateAsCounter) &&
2308 "Invalid vector kind");
2309 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2311 Op->Reg.ElementWidth = ElementWidth;
2315 static std::unique_ptr<AArch64Operand>
2316 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2317 unsigned NumElements,
unsigned ElementWidth,
2318 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2319 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2320 Op->VectorList.Reg =
Reg;
2322 Op->VectorList.Stride = Stride;
2323 Op->VectorList.NumElements = NumElements;
2324 Op->VectorList.ElementWidth = ElementWidth;
2325 Op->VectorList.RegisterKind = RegisterKind;
2331 static std::unique_ptr<AArch64Operand>
2332 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2333 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2334 Op->VectorIndex.Val =
Idx;
2340 static std::unique_ptr<AArch64Operand>
2341 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2342 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2343 Op->MatrixTileList.RegMask = RegMask;
2349 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2350 const unsigned ElementWidth) {
2351 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2353 {{0, AArch64::ZAB0},
2354 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2355 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2356 {{8, AArch64::ZAB0},
2357 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2358 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2359 {{16, AArch64::ZAH0},
2360 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2361 {{16, AArch64::ZAH1},
2362 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2363 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2364 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2365 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2366 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2369 if (ElementWidth == 64)
2372 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2373 assert(!Regs.empty() &&
"Invalid tile or element width!");
2378 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2379 SMLoc
E, MCContext &Ctx) {
2380 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2387 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2388 unsigned ShiftAmount,
2391 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2392 Op->ShiftedImm .Val = Val;
2393 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2399 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2400 unsigned Last, SMLoc S,
2403 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2405 Op->ImmRange.Last =
Last;
2410 static std::unique_ptr<AArch64Operand>
2412 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2413 Op->CondCode.Code =
Code;
2419 static std::unique_ptr<AArch64Operand>
2420 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2421 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2423 Op->FPImm.IsExact = IsExact;
2429 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2433 bool HasnXSModifier) {
2434 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2435 Op->Barrier.Val = Val;
2436 Op->Barrier.Data = Str.data();
2437 Op->Barrier.Length = Str.size();
2438 Op->Barrier.HasnXSModifier = HasnXSModifier;
2444 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2447 uint32_t PStateField,
2449 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2450 Op->SysReg.Data = Str.data();
2451 Op->SysReg.Length = Str.size();
2452 Op->SysReg.MRSReg = MRSReg;
2453 Op->SysReg.MSRReg = MSRReg;
2454 Op->SysReg.PStateField = PStateField;
2460 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2461 SMLoc
E, MCContext &Ctx) {
2462 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2463 Op->SysCRImm.Val = Val;
2469 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2473 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2474 Op->Prefetch.Val = Val;
2475 Op->Barrier.Data = Str.data();
2476 Op->Barrier.Length = Str.size();
2482 static std::unique_ptr<AArch64Operand>
2483 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2484 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2485 Op->TIndexHint.Val = Val;
2486 Op->TIndexHint.Data = Str.data();
2487 Op->TIndexHint.Length = Str.size();
2493 static std::unique_ptr<AArch64Operand>
2494 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2495 SMLoc S, SMLoc
E, MCContext &Ctx) {
2496 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2497 Op->MatrixReg.Reg =
Reg;
2498 Op->MatrixReg.ElementWidth = ElementWidth;
2499 Op->MatrixReg.Kind = Kind;
2505 static std::unique_ptr<AArch64Operand>
2506 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2507 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2508 Op->SVCR.PStateField = PStateField;
2509 Op->SVCR.Data = Str.data();
2510 Op->SVCR.Length = Str.size();
2516 static std::unique_ptr<AArch64Operand>
2518 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2519 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2520 Op->ShiftExtend.Type = ShOp;
2521 Op->ShiftExtend.Amount = Val;
2522 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2534 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2535 if (!getFPImmIsExact())
2540 StringRef
Name = getBarrierName();
2542 OS <<
"<barrier " <<
Name <<
">";
2544 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2550 case k_ShiftedImm: {
2551 unsigned Shift = getShiftedImmShift();
2552 OS <<
"<shiftedimm ";
2559 OS << getFirstImmVal();
2560 OS <<
":" << getLastImmVal() <<
">";
2566 case k_VectorList: {
2567 OS <<
"<vectorlist ";
2568 MCRegister
Reg = getVectorListStart();
2569 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2570 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2575 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2578 OS <<
"<sysreg: " << getSysReg() <<
'>';
2584 OS <<
"c" << getSysCR();
2587 StringRef
Name = getPrefetchName();
2589 OS <<
"<prfop " <<
Name <<
">";
2591 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2595 OS << getTIndexHintName();
2597 case k_MatrixRegister:
2598 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2600 case k_MatrixTileList: {
2601 OS <<
"<matrixlist ";
2602 unsigned RegMask = getMatrixTileListRegMask();
2603 unsigned MaxBits = 8;
2604 for (
unsigned I = MaxBits;
I > 0; --
I)
2605 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2614 OS <<
"<register " <<
getReg().
id() <<
">";
2615 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2620 << getShiftExtendAmount();
2621 if (!hasShiftExtendAmount())
2637 .
Case(
"v0", AArch64::Q0)
2638 .
Case(
"v1", AArch64::Q1)
2639 .
Case(
"v2", AArch64::Q2)
2640 .
Case(
"v3", AArch64::Q3)
2641 .
Case(
"v4", AArch64::Q4)
2642 .
Case(
"v5", AArch64::Q5)
2643 .
Case(
"v6", AArch64::Q6)
2644 .
Case(
"v7", AArch64::Q7)
2645 .
Case(
"v8", AArch64::Q8)
2646 .
Case(
"v9", AArch64::Q9)
2647 .
Case(
"v10", AArch64::Q10)
2648 .
Case(
"v11", AArch64::Q11)
2649 .
Case(
"v12", AArch64::Q12)
2650 .
Case(
"v13", AArch64::Q13)
2651 .
Case(
"v14", AArch64::Q14)
2652 .
Case(
"v15", AArch64::Q15)
2653 .
Case(
"v16", AArch64::Q16)
2654 .
Case(
"v17", AArch64::Q17)
2655 .
Case(
"v18", AArch64::Q18)
2656 .
Case(
"v19", AArch64::Q19)
2657 .
Case(
"v20", AArch64::Q20)
2658 .
Case(
"v21", AArch64::Q21)
2659 .
Case(
"v22", AArch64::Q22)
2660 .
Case(
"v23", AArch64::Q23)
2661 .
Case(
"v24", AArch64::Q24)
2662 .
Case(
"v25", AArch64::Q25)
2663 .
Case(
"v26", AArch64::Q26)
2664 .
Case(
"v27", AArch64::Q27)
2665 .
Case(
"v28", AArch64::Q28)
2666 .
Case(
"v29", AArch64::Q29)
2667 .
Case(
"v30", AArch64::Q30)
2668 .
Case(
"v31", AArch64::Q31)
2677 RegKind VectorKind) {
2678 std::pair<int, int> Res = {-1, -1};
2680 switch (VectorKind) {
2681 case RegKind::NeonVector:
2684 .Case(
".1d", {1, 64})
2685 .Case(
".1q", {1, 128})
2687 .Case(
".2h", {2, 16})
2688 .Case(
".2b", {2, 8})
2689 .Case(
".2s", {2, 32})
2690 .Case(
".2d", {2, 64})
2693 .Case(
".4b", {4, 8})
2694 .Case(
".4h", {4, 16})
2695 .Case(
".4s", {4, 32})
2696 .Case(
".8b", {8, 8})
2697 .Case(
".8h", {8, 16})
2698 .Case(
".16b", {16, 8})
2703 .Case(
".h", {0, 16})
2704 .Case(
".s", {0, 32})
2705 .Case(
".d", {0, 64})
2708 case RegKind::SVEPredicateAsCounter:
2709 case RegKind::SVEPredicateVector:
2710 case RegKind::SVEDataVector:
2711 case RegKind::Matrix:
2715 .Case(
".h", {0, 16})
2716 .Case(
".s", {0, 32})
2717 .Case(
".d", {0, 64})
2718 .Case(
".q", {0, 128})
2725 if (Res == std::make_pair(-1, -1))
2726 return std::nullopt;
2728 return std::optional<std::pair<int, int>>(Res);
2737 .
Case(
"z0", AArch64::Z0)
2738 .
Case(
"z1", AArch64::Z1)
2739 .
Case(
"z2", AArch64::Z2)
2740 .
Case(
"z3", AArch64::Z3)
2741 .
Case(
"z4", AArch64::Z4)
2742 .
Case(
"z5", AArch64::Z5)
2743 .
Case(
"z6", AArch64::Z6)
2744 .
Case(
"z7", AArch64::Z7)
2745 .
Case(
"z8", AArch64::Z8)
2746 .
Case(
"z9", AArch64::Z9)
2747 .
Case(
"z10", AArch64::Z10)
2748 .
Case(
"z11", AArch64::Z11)
2749 .
Case(
"z12", AArch64::Z12)
2750 .
Case(
"z13", AArch64::Z13)
2751 .
Case(
"z14", AArch64::Z14)
2752 .
Case(
"z15", AArch64::Z15)
2753 .
Case(
"z16", AArch64::Z16)
2754 .
Case(
"z17", AArch64::Z17)
2755 .
Case(
"z18", AArch64::Z18)
2756 .
Case(
"z19", AArch64::Z19)
2757 .
Case(
"z20", AArch64::Z20)
2758 .
Case(
"z21", AArch64::Z21)
2759 .
Case(
"z22", AArch64::Z22)
2760 .
Case(
"z23", AArch64::Z23)
2761 .
Case(
"z24", AArch64::Z24)
2762 .
Case(
"z25", AArch64::Z25)
2763 .
Case(
"z26", AArch64::Z26)
2764 .
Case(
"z27", AArch64::Z27)
2765 .
Case(
"z28", AArch64::Z28)
2766 .
Case(
"z29", AArch64::Z29)
2767 .
Case(
"z30", AArch64::Z30)
2768 .
Case(
"z31", AArch64::Z31)
2774 .
Case(
"p0", AArch64::P0)
2775 .
Case(
"p1", AArch64::P1)
2776 .
Case(
"p2", AArch64::P2)
2777 .
Case(
"p3", AArch64::P3)
2778 .
Case(
"p4", AArch64::P4)
2779 .
Case(
"p5", AArch64::P5)
2780 .
Case(
"p6", AArch64::P6)
2781 .
Case(
"p7", AArch64::P7)
2782 .
Case(
"p8", AArch64::P8)
2783 .
Case(
"p9", AArch64::P9)
2784 .
Case(
"p10", AArch64::P10)
2785 .
Case(
"p11", AArch64::P11)
2786 .
Case(
"p12", AArch64::P12)
2787 .
Case(
"p13", AArch64::P13)
2788 .
Case(
"p14", AArch64::P14)
2789 .
Case(
"p15", AArch64::P15)
2795 .
Case(
"pn0", AArch64::PN0)
2796 .
Case(
"pn1", AArch64::PN1)
2797 .
Case(
"pn2", AArch64::PN2)
2798 .
Case(
"pn3", AArch64::PN3)
2799 .
Case(
"pn4", AArch64::PN4)
2800 .
Case(
"pn5", AArch64::PN5)
2801 .
Case(
"pn6", AArch64::PN6)
2802 .
Case(
"pn7", AArch64::PN7)
2803 .
Case(
"pn8", AArch64::PN8)
2804 .
Case(
"pn9", AArch64::PN9)
2805 .
Case(
"pn10", AArch64::PN10)
2806 .
Case(
"pn11", AArch64::PN11)
2807 .
Case(
"pn12", AArch64::PN12)
2808 .
Case(
"pn13", AArch64::PN13)
2809 .
Case(
"pn14", AArch64::PN14)
2810 .
Case(
"pn15", AArch64::PN15)
2816 .
Case(
"za0.d", AArch64::ZAD0)
2817 .
Case(
"za1.d", AArch64::ZAD1)
2818 .
Case(
"za2.d", AArch64::ZAD2)
2819 .
Case(
"za3.d", AArch64::ZAD3)
2820 .
Case(
"za4.d", AArch64::ZAD4)
2821 .
Case(
"za5.d", AArch64::ZAD5)
2822 .
Case(
"za6.d", AArch64::ZAD6)
2823 .
Case(
"za7.d", AArch64::ZAD7)
2824 .
Case(
"za0.s", AArch64::ZAS0)
2825 .
Case(
"za1.s", AArch64::ZAS1)
2826 .
Case(
"za2.s", AArch64::ZAS2)
2827 .
Case(
"za3.s", AArch64::ZAS3)
2828 .
Case(
"za0.h", AArch64::ZAH0)
2829 .
Case(
"za1.h", AArch64::ZAH1)
2830 .
Case(
"za0.b", AArch64::ZAB0)
2836 .
Case(
"za", AArch64::ZA)
2837 .
Case(
"za0.q", AArch64::ZAQ0)
2838 .
Case(
"za1.q", AArch64::ZAQ1)
2839 .
Case(
"za2.q", AArch64::ZAQ2)
2840 .
Case(
"za3.q", AArch64::ZAQ3)
2841 .
Case(
"za4.q", AArch64::ZAQ4)
2842 .
Case(
"za5.q", AArch64::ZAQ5)
2843 .
Case(
"za6.q", AArch64::ZAQ6)
2844 .
Case(
"za7.q", AArch64::ZAQ7)
2845 .
Case(
"za8.q", AArch64::ZAQ8)
2846 .
Case(
"za9.q", AArch64::ZAQ9)
2847 .
Case(
"za10.q", AArch64::ZAQ10)
2848 .
Case(
"za11.q", AArch64::ZAQ11)
2849 .
Case(
"za12.q", AArch64::ZAQ12)
2850 .
Case(
"za13.q", AArch64::ZAQ13)
2851 .
Case(
"za14.q", AArch64::ZAQ14)
2852 .
Case(
"za15.q", AArch64::ZAQ15)
2853 .
Case(
"za0.d", AArch64::ZAD0)
2854 .
Case(
"za1.d", AArch64::ZAD1)
2855 .
Case(
"za2.d", AArch64::ZAD2)
2856 .
Case(
"za3.d", AArch64::ZAD3)
2857 .
Case(
"za4.d", AArch64::ZAD4)
2858 .
Case(
"za5.d", AArch64::ZAD5)
2859 .
Case(
"za6.d", AArch64::ZAD6)
2860 .
Case(
"za7.d", AArch64::ZAD7)
2861 .
Case(
"za0.s", AArch64::ZAS0)
2862 .
Case(
"za1.s", AArch64::ZAS1)
2863 .
Case(
"za2.s", AArch64::ZAS2)
2864 .
Case(
"za3.s", AArch64::ZAS3)
2865 .
Case(
"za0.h", AArch64::ZAH0)
2866 .
Case(
"za1.h", AArch64::ZAH1)
2867 .
Case(
"za0.b", AArch64::ZAB0)
2868 .
Case(
"za0h.q", AArch64::ZAQ0)
2869 .
Case(
"za1h.q", AArch64::ZAQ1)
2870 .
Case(
"za2h.q", AArch64::ZAQ2)
2871 .
Case(
"za3h.q", AArch64::ZAQ3)
2872 .
Case(
"za4h.q", AArch64::ZAQ4)
2873 .
Case(
"za5h.q", AArch64::ZAQ5)
2874 .
Case(
"za6h.q", AArch64::ZAQ6)
2875 .
Case(
"za7h.q", AArch64::ZAQ7)
2876 .
Case(
"za8h.q", AArch64::ZAQ8)
2877 .
Case(
"za9h.q", AArch64::ZAQ9)
2878 .
Case(
"za10h.q", AArch64::ZAQ10)
2879 .
Case(
"za11h.q", AArch64::ZAQ11)
2880 .
Case(
"za12h.q", AArch64::ZAQ12)
2881 .
Case(
"za13h.q", AArch64::ZAQ13)
2882 .
Case(
"za14h.q", AArch64::ZAQ14)
2883 .
Case(
"za15h.q", AArch64::ZAQ15)
2884 .
Case(
"za0h.d", AArch64::ZAD0)
2885 .
Case(
"za1h.d", AArch64::ZAD1)
2886 .
Case(
"za2h.d", AArch64::ZAD2)
2887 .
Case(
"za3h.d", AArch64::ZAD3)
2888 .
Case(
"za4h.d", AArch64::ZAD4)
2889 .
Case(
"za5h.d", AArch64::ZAD5)
2890 .
Case(
"za6h.d", AArch64::ZAD6)
2891 .
Case(
"za7h.d", AArch64::ZAD7)
2892 .
Case(
"za0h.s", AArch64::ZAS0)
2893 .
Case(
"za1h.s", AArch64::ZAS1)
2894 .
Case(
"za2h.s", AArch64::ZAS2)
2895 .
Case(
"za3h.s", AArch64::ZAS3)
2896 .
Case(
"za0h.h", AArch64::ZAH0)
2897 .
Case(
"za1h.h", AArch64::ZAH1)
2898 .
Case(
"za0h.b", AArch64::ZAB0)
2899 .
Case(
"za0v.q", AArch64::ZAQ0)
2900 .
Case(
"za1v.q", AArch64::ZAQ1)
2901 .
Case(
"za2v.q", AArch64::ZAQ2)
2902 .
Case(
"za3v.q", AArch64::ZAQ3)
2903 .
Case(
"za4v.q", AArch64::ZAQ4)
2904 .
Case(
"za5v.q", AArch64::ZAQ5)
2905 .
Case(
"za6v.q", AArch64::ZAQ6)
2906 .
Case(
"za7v.q", AArch64::ZAQ7)
2907 .
Case(
"za8v.q", AArch64::ZAQ8)
2908 .
Case(
"za9v.q", AArch64::ZAQ9)
2909 .
Case(
"za10v.q", AArch64::ZAQ10)
2910 .
Case(
"za11v.q", AArch64::ZAQ11)
2911 .
Case(
"za12v.q", AArch64::ZAQ12)
2912 .
Case(
"za13v.q", AArch64::ZAQ13)
2913 .
Case(
"za14v.q", AArch64::ZAQ14)
2914 .
Case(
"za15v.q", AArch64::ZAQ15)
2915 .
Case(
"za0v.d", AArch64::ZAD0)
2916 .
Case(
"za1v.d", AArch64::ZAD1)
2917 .
Case(
"za2v.d", AArch64::ZAD2)
2918 .
Case(
"za3v.d", AArch64::ZAD3)
2919 .
Case(
"za4v.d", AArch64::ZAD4)
2920 .
Case(
"za5v.d", AArch64::ZAD5)
2921 .
Case(
"za6v.d", AArch64::ZAD6)
2922 .
Case(
"za7v.d", AArch64::ZAD7)
2923 .
Case(
"za0v.s", AArch64::ZAS0)
2924 .
Case(
"za1v.s", AArch64::ZAS1)
2925 .
Case(
"za2v.s", AArch64::ZAS2)
2926 .
Case(
"za3v.s", AArch64::ZAS3)
2927 .
Case(
"za0v.h", AArch64::ZAH0)
2928 .
Case(
"za1v.h", AArch64::ZAH1)
2929 .
Case(
"za0v.b", AArch64::ZAB0)
2933bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2935 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2938ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2940 StartLoc = getLoc();
2941 ParseStatus Res = tryParseScalarRegister(
Reg);
2947MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2949 MCRegister
Reg = MCRegister();
2951 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2954 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2957 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2960 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2963 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2965 if (
Name.equals_insensitive(
"zt0"))
2966 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2970 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2974 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2975 .Case(
"fp", AArch64::FP)
2976 .Case(
"lr", AArch64::LR)
2977 .Case(
"x31", AArch64::XZR)
2978 .Case(
"w31", AArch64::WZR)
2980 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2986 if (Entry == RegisterReqs.
end())
2987 return MCRegister();
2990 if (Kind ==
Entry->getValue().first)
2996unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2998 case RegKind::Scalar:
2999 case RegKind::NeonVector:
3000 case RegKind::SVEDataVector:
3002 case RegKind::Matrix:
3003 case RegKind::SVEPredicateVector:
3004 case RegKind::SVEPredicateAsCounter:
3006 case RegKind::LookupTable:
3015ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3016 const AsmToken &Tok = getTok();
3021 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3035 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3038 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3039 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3043 if (BadNum || CRNum > 15)
3044 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3048 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3055 const AsmToken &Tok = getTok();
3057 unsigned MaxVal = 63;
3062 const MCExpr *ImmVal;
3063 if (getParser().parseExpression(ImmVal))
3068 return TokError(
"immediate value expected for prefetch operand");
3071 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3074 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3075 Operands.push_back(AArch64Operand::CreatePrefetch(
3076 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3082 return TokError(
"prefetch hint expected");
3084 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3086 return TokError(
"prefetch hint expected");
3088 Operands.push_back(AArch64Operand::CreatePrefetch(
3095template <
bool IsSVEPrefetch>
3098 const AsmToken &Tok = getTok();
3100 auto LookupByName = [](StringRef
N) {
3101 if (IsSVEPrefetch) {
3102 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3103 return std::optional<unsigned>(Res->Encoding);
3104 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3105 return std::optional<unsigned>(Res->Encoding);
3106 return std::optional<unsigned>();
3109 auto LookupByEncoding = [](
unsigned E) {
3110 if (IsSVEPrefetch) {
3111 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3112 return std::optional<StringRef>(
3113 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3114 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3115 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3116 return std::optional<StringRef>();
3118 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3124 const MCExpr *ImmVal;
3125 if (getParser().parseExpression(ImmVal))
3130 return TokError(
"immediate value expected for prefetch operand");
3133 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3136 auto PRFM = LookupByEncoding(MCE->
getValue());
3137 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3143 return TokError(
"prefetch hint expected");
3145 auto PRFM = LookupByName(Tok.
getString());
3147 return TokError(
"prefetch hint expected");
3149 Operands.push_back(AArch64Operand::CreatePrefetch(
3156 SMLoc StartLoc = getLoc();
3162 auto RegTok = getTok();
3163 if (!tryParseScalarRegister(RegNum).isSuccess())
3166 if (RegNum != AArch64::XZR) {
3167 getLexer().UnLex(RegTok);
3174 if (!tryParseScalarRegister(RegNum).isSuccess())
3175 return TokError(
"expected register operand");
3177 if (RegNum != AArch64::XZR)
3178 return TokError(
"xzr must be followed by xzr");
3182 Operands.push_back(AArch64Operand::CreateReg(
3183 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3191 const AsmToken &Tok = getTok();
3193 return TokError(
"invalid operand for instruction");
3195 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3197 return TokError(
"invalid operand for instruction");
3199 Operands.push_back(AArch64Operand::CreateTIndexHint(
3209 const MCExpr *Expr =
nullptr;
3215 if (parseSymbolicImmVal(Expr))
3221 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3230 return Error(S,
"gotpage label reference not allowed an addend");
3242 return Error(S,
"page or gotpage label reference expected");
3259 const MCExpr *Expr =
nullptr;
3268 if (parseSymbolicImmVal(Expr))
3274 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3286 return Error(S,
"unexpected adr label");
3296template <
bool AddFPZeroAsLiteral>
3305 const AsmToken &Tok = getTok();
3309 return TokError(
"invalid floating point immediate");
3314 if (Tok.
getIntVal() > 255 || isNegative)
3315 return TokError(
"encoded floating point value out of range");
3319 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3322 APFloat RealVal(APFloat::IEEEdouble());
3324 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3326 return TokError(
"invalid floating point representation");
3329 RealVal.changeSign();
3331 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3335 Operands.push_back(AArch64Operand::CreateFPImm(
3336 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3360 const MCExpr *
Imm =
nullptr;
3361 if (parseSymbolicImmVal(
Imm))
3372 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3376 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3382 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3383 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3391 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3393 int64_t ShiftAmount = getTok().getIntVal();
3395 if (ShiftAmount < 0)
3396 return Error(getLoc(),
"positive shift amount required");
3400 if (ShiftAmount == 0 &&
Imm !=
nullptr) {
3406 Operands.push_back(AArch64Operand::CreateShiftedImm(
Imm, ShiftAmount, S,
3414AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3448 Suggestion =
"nfrst";
3455 bool invertCondCode) {
3457 const AsmToken &Tok = getTok();
3461 std::string Suggestion;
3464 std::string
Msg =
"invalid condition code";
3465 if (!Suggestion.empty())
3466 Msg +=
", did you mean " + Suggestion +
"?";
3467 return TokError(
Msg);
3471 if (invertCondCode) {
3473 return TokError(
"condition codes AL and NV are invalid for this instruction");
3478 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3483 const AsmToken &Tok = getTok();
3487 return TokError(
"invalid operand for instruction");
3489 unsigned PStateImm = -1;
3490 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3493 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3494 PStateImm = SVCR->Encoding;
3503 const AsmToken &Tok = getTok();
3508 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3510 unsigned ElementWidth = 0;
3511 auto DotPosition =
Name.find(
'.');
3513 const auto &KindRes =
3517 "Expected the register to be followed by element width suffix");
3518 ElementWidth = KindRes->second;
3520 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3521 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3526 if (parseOperand(
Operands,
false,
false))
3533 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3537 size_t DotPosition =
Name.find(
'.');
3540 StringRef Head =
Name.take_front(DotPosition);
3541 StringRef
Tail =
Name.drop_front(DotPosition);
3542 StringRef RowOrColumn = Head.
take_back();
3544 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3545 .Case(
"h", MatrixKind::Row)
3546 .Case(
"v", MatrixKind::Col)
3547 .Default(MatrixKind::Tile);
3553 "Expected the register to be followed by element width suffix");
3554 unsigned ElementWidth = KindRes->second;
3558 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3564 if (parseOperand(
Operands,
false,
false))
3574 const AsmToken &Tok = getTok();
3577 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3606 return TokError(
"expected #imm after shift specifier");
3612 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3621 return Error(
E,
"expected integer shift amount");
3623 const MCExpr *ImmVal;
3624 if (getParser().parseExpression(ImmVal))
3629 return Error(
E,
"expected constant '#imm' after shift specifier");
3632 Operands.push_back(AArch64Operand::CreateShiftExtend(
3638 {{
"crc"}, {AArch64::FeatureCRC}},
3639 {{
"sm4"}, {AArch64::FeatureSM4}},
3640 {{
"sha3"}, {AArch64::FeatureSHA3}},
3641 {{
"sha2"}, {AArch64::FeatureSHA2}},
3642 {{
"aes"}, {AArch64::FeatureAES}},
3643 {{
"crypto"}, {AArch64::FeatureCrypto}},
3644 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3645 {{
"simd"}, {AArch64::FeatureNEON}},
3646 {{
"ras"}, {AArch64::FeatureRAS}},
3647 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3648 {{
"lse"}, {AArch64::FeatureLSE}},
3649 {{
"predres"}, {AArch64::FeaturePredRes}},
3650 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3651 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3652 {{
"mte"}, {AArch64::FeatureMTE}},
3653 {{
"memtag"}, {AArch64::FeatureMTE}},
3654 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3655 {{
"pan"}, {AArch64::FeaturePAN}},
3656 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3657 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3658 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3659 {{
"rng"}, {AArch64::FeatureRandGen}},
3660 {{
"sve"}, {AArch64::FeatureSVE}},
3661 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3662 {{
"sve2"}, {AArch64::FeatureSVE2}},
3663 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3664 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3665 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3666 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3667 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3668 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3669 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3671 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3672 AArch64::FeatureSVE2}},
3673 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3674 {{
"ls64"}, {AArch64::FeatureLS64}},
3675 {{
"xs"}, {AArch64::FeatureXS}},
3676 {{
"pauth"}, {AArch64::FeaturePAuth}},
3677 {{
"flagm"}, {AArch64::FeatureFlagM}},
3678 {{
"rme"}, {AArch64::FeatureRME}},
3679 {{
"sme"}, {AArch64::FeatureSME}},
3680 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3681 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3682 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3683 {{
"sme2"}, {AArch64::FeatureSME2}},
3684 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3685 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3686 {{
"hbc"}, {AArch64::FeatureHBC}},
3687 {{
"mops"}, {AArch64::FeatureMOPS}},
3688 {{
"mec"}, {AArch64::FeatureMEC}},
3689 {{
"the"}, {AArch64::FeatureTHE}},
3690 {{
"d128"}, {AArch64::FeatureD128}},
3691 {{
"lse128"}, {AArch64::FeatureLSE128}},
3692 {{
"ite"}, {AArch64::FeatureITE}},
3693 {{
"cssc"}, {AArch64::FeatureCSSC}},
3694 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3695 {{
"gcs"}, {AArch64::FeatureGCS}},
3696 {{
"bf16"}, {AArch64::FeatureBF16}},
3697 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3698 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3699 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3700 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3701 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3702 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3703 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3704 {{
"lor"}, {AArch64::FeatureLOR}},
3705 {{
"profile"}, {AArch64::FeatureSPE}},
3709 {{
"rdm"}, {AArch64::FeatureRDM}},
3710 {{
"rdma"}, {AArch64::FeatureRDM}},
3711 {{
"sb"}, {AArch64::FeatureSB}},
3712 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3713 {{
"fp8"}, {AArch64::FeatureFP8}},
3714 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3715 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3716 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3717 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3718 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3719 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3720 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3721 {{
"lut"}, {AArch64::FeatureLUT}},
3722 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3723 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3724 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3725 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3726 {{
"cpa"}, {AArch64::FeatureCPA}},
3727 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3728 {{
"pops"}, {AArch64::FeaturePoPS}},
3729 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3730 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3731 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3732 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3733 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3734 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3735 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3736 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3737 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3738 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3739 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3740 {{
"lsui"}, {AArch64::FeatureLSUI}},
3741 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3742 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3743 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3744 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3745 {{
"lscp"}, {AArch64::FeatureLSCP}},
3746 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3747 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3748 {{
"gcie"}, {AArch64::FeatureGCIE}},
3749 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3750 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3751 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3752 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3753 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3754 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3755 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3756 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3757 {{
"tev"}, {AArch64::FeatureTEV}},
3758 {{
"btie"}, {AArch64::FeatureBTIE}},
3759 {{
"hinte"}, {AArch64::FeatureHINTE}},
3760 {{
"dit"}, {AArch64::FeatureDIT}},
3761 {{
"brbe"}, {AArch64::FeatureBRBE}},
3762 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3763 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3764 {{
"jscvt"}, {AArch64::FeatureJS}},
3765 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3766 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3767 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3768 {{
"cflt"}, {AArch64::FeatureCFLT}},
3769 {{
"lsc64b"}, {AArch64::FeatureLSC64B}},
3774 if (FBS[AArch64::HasV8_0aOps])
3776 if (FBS[AArch64::HasV8_1aOps])
3778 else if (FBS[AArch64::HasV8_2aOps])
3780 else if (FBS[AArch64::HasV8_3aOps])
3782 else if (FBS[AArch64::HasV8_4aOps])
3784 else if (FBS[AArch64::HasV8_5aOps])
3786 else if (FBS[AArch64::HasV8_6aOps])
3788 else if (FBS[AArch64::HasV8_7aOps])
3790 else if (FBS[AArch64::HasV8_8aOps])
3792 else if (FBS[AArch64::HasV8_9aOps])
3794 else if (FBS[AArch64::HasV9_0aOps])
3796 else if (FBS[AArch64::HasV9_1aOps])
3798 else if (FBS[AArch64::HasV9_2aOps])
3800 else if (FBS[AArch64::HasV9_3aOps])
3802 else if (FBS[AArch64::HasV9_4aOps])
3804 else if (FBS[AArch64::HasV9_5aOps])
3806 else if (FBS[AArch64::HasV9_6aOps])
3808 else if (FBS[AArch64::HasV9_7aOps])
3810 else if (FBS[AArch64::HasV9_8aOps])
3812 else if (FBS[AArch64::HasV8_0rOps])
3821 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3827 const uint16_t Op2 = Encoding & 7;
3828 const uint16_t Cm = (Encoding & 0x78) >> 3;
3829 const uint16_t Cn = (Encoding & 0x780) >> 7;
3830 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3835 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3837 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3839 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3842 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3848bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3850 if (
Name.contains(
'.'))
3851 return TokError(
"invalid operand");
3856 const AsmToken &Tok = getTok();
3859 bool ExpectRegister =
true;
3860 bool OptionalRegister =
false;
3861 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3862 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3864 if (Mnemonic ==
"ic") {
3865 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3867 return TokError(
"invalid operand for IC instruction");
3868 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3869 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3872 return TokError(Str);
3876 }
else if (Mnemonic ==
"dc") {
3877 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3879 return TokError(
"invalid operand for DC instruction");
3880 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3881 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3884 return TokError(Str);
3887 }
else if (Mnemonic ==
"at") {
3888 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3890 return TokError(
"invalid operand for AT instruction");
3891 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3892 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3895 return TokError(Str);
3898 }
else if (Mnemonic ==
"tlbi") {
3899 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3901 return TokError(
"invalid operand for TLBI instruction");
3902 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3903 std::string Str(
"TLBI " +
3904 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3907 return TokError(Str);
3909 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3910 if (hasAll || hasTLBID)
3911 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3913 }
else if (Mnemonic ==
"gic") {
3914 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3916 return TokError(
"invalid operand for GIC instruction");
3917 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3918 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3921 return TokError(Str);
3925 }
else if (Mnemonic ==
"gsb") {
3926 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3928 return TokError(
"invalid operand for GSB instruction");
3929 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3930 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3933 return TokError(Str);
3935 ExpectRegister =
false;
3937 }
else if (Mnemonic ==
"plbi") {
3938 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3940 return TokError(
"invalid operand for PLBI instruction");
3941 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3942 std::string Str(
"PLBI " +
3943 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3946 return TokError(Str);
3948 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3949 if (hasAll || hasTLBID)
3950 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3952 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3953 Mnemonic ==
"cosp") {
3955 if (
Op.lower() !=
"rctx")
3956 return TokError(
"invalid operand for prediction restriction instruction");
3958 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3959 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3961 if (Mnemonic ==
"cosp" && !hasSpecres2)
3962 return TokError(
"COSP requires: predres2");
3964 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3966 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3967 : Mnemonic ==
"dvp" ? 0b101
3968 : Mnemonic ==
"cosp" ? 0b110
3969 : Mnemonic ==
"cpp" ? 0b111
3972 "Invalid mnemonic for prediction restriction instruction");
3973 const auto SYS_3_7_3 = 0b01101110011;
3974 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3976 createSysAlias(Encoding,
Operands, S);
3981 bool HasRegister =
false;
3986 return TokError(
"expected register operand");
3990 if (!OptionalRegister) {
3991 if (ExpectRegister && !HasRegister)
3992 return TokError(
"specified " + Mnemonic +
" op requires a register");
3993 else if (!ExpectRegister && HasRegister)
3994 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4006bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4011 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4014 SMLoc startLoc = getLoc();
4015 const AsmToken ®Tok = getTok();
4017 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4019 return TokError(
"expected register operand");
4021 Operands.push_back(AArch64Operand::CreateReg(
4022 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4029 const AsmToken &operandTok = getTok();
4031 SMLoc S2 = operandTok.
getLoc();
4034 if (Mnemonic ==
"gicr") {
4035 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4037 return Error(S2,
"invalid operand for GICR instruction");
4038 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4039 std::string Str(
"GICR " +
4040 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4043 return Error(S2, Str);
4056bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4058 if (
Name.contains(
'.'))
4059 return TokError(
"invalid operand");
4063 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4065 const AsmToken &Tok = getTok();
4069 if (Mnemonic ==
"tlbip") {
4070 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4072 return TokError(
"invalid operand for TLBIP instruction");
4075 std::string Str(
"instruction requires: ");
4077 return TokError(Str);
4088 return TokError(
"expected register identifier");
4093 return TokError(
"specified " + Mnemonic +
4094 " op requires a pair of registers");
4103 MCAsmParser &Parser = getParser();
4104 const AsmToken &Tok = getTok();
4108 const MCExpr *ImmVal;
4109 SMLoc ExprLoc = getLoc();
4110 AsmToken IntTok = Tok;
4111 if (getParser().parseExpression(ImmVal))
4115 return Error(ExprLoc,
"immediate value expected for barrier operand");
4117 if (Mnemonic ==
"dsb" &&
Value > 15) {
4125 return Error(ExprLoc,
"barrier operand out of range");
4126 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4127 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4128 Operands.push_back(AArch64Operand::CreateBarrier(
4134 return TokError(
"invalid operand for instruction");
4137 auto DB = AArch64DB::lookupDBByName(Operand);
4139 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4140 return TokError(
"'sy' or #imm operand expected");
4142 if (Mnemonic ==
"dsb") {
4147 return TokError(
"invalid barrier option name");
4151 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4160 const AsmToken &Tok = getTok();
4162 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4163 if (Mnemonic !=
"dsb")
4168 const MCExpr *ImmVal;
4169 SMLoc ExprLoc = getLoc();
4170 if (getParser().parseExpression(ImmVal))
4174 return Error(ExprLoc,
"immediate value expected for barrier operand");
4179 return Error(ExprLoc,
"barrier operand out of range");
4180 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4181 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4182 Operands.push_back(AArch64Operand::CreateBarrier(
4188 return TokError(
"invalid operand for instruction");
4191 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4194 return TokError(
"invalid barrier option name");
4197 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4205 const AsmToken &Tok = getTok();
4210 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4214 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4215 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4216 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4217 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4221 unsigned PStateImm = -1;
4222 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4223 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4224 PStateImm = PState15->Encoding;
4226 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4227 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4228 PStateImm = PState1->Encoding;
4232 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4248 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4256 unsigned ElementWidth = KindRes->second;
4258 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4266 return tryParseVectorIndex(
Operands).isFailure();
4270 SMLoc SIdx = getLoc();
4272 const MCExpr *ImmVal;
4273 if (getParser().parseExpression(ImmVal))
4277 return TokError(
"immediate value expected for vector index");
4284 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4295ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4297 RegKind MatchKind) {
4298 const AsmToken &Tok = getTok();
4307 StringRef Head =
Name.slice(Start,
Next);
4308 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4314 return TokError(
"invalid vector kind qualifier");
4325ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4327 ParseStatus Status =
4328 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4330 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4335template <RegKind RK>
4339 const SMLoc S = getLoc();
4342 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4350 unsigned ElementWidth = KindRes->second;
4351 Operands.push_back(AArch64Operand::CreateVectorReg(
4352 RegNum, RK, ElementWidth, S,
4356 if (RK == RegKind::SVEPredicateAsCounter) {
4357 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4363 if (parseOperand(
Operands,
false,
false))
4374 return Error(S,
"not expecting size suffix");
4382 auto Pred = getTok().getString().lower();
4383 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4384 return Error(getLoc(),
"expecting 'z' predication");
4386 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4387 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4390 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4400 if (!tryParseNeonVectorRegister(
Operands))
4403 if (tryParseZTOperand(
Operands).isSuccess())
4407 if (tryParseGPROperand<false>(
Operands).isSuccess())
4413bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4414 bool HasELFModifier =
false;
4416 SMLoc Loc = getLexer().getLoc();
4418 HasELFModifier =
true;
4421 return TokError(
"expect relocation specifier in operand after ':'");
4423 std::string LowerCase = getTok().getIdentifier().lower();
4424 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4479 return TokError(
"expect relocation specifier in operand after ':'");
4483 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4487 if (getParser().parseExpression(ImmVal))
4495 if (!HasELFModifier &&
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4496 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4506 if (getParser().parsePrimaryExpr(Term, EndLoc))
4518 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4519 unsigned &ElementWidth) -> ParseStatus {
4520 StringRef
Name = getTok().getString();
4521 size_t DotPosition =
Name.find(
'.');
4529 StringRef
Tail =
Name.drop_front(DotPosition);
4530 const std::optional<std::pair<int, int>> &KindRes =
4534 "Expected the register to be followed by element width suffix");
4535 ElementWidth = KindRes->second;
4542 auto LCurly = getTok();
4547 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4553 if (getTok().getString().equals_insensitive(
"za")) {
4559 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4564 SMLoc TileLoc = getLoc();
4566 unsigned FirstReg, ElementWidth;
4567 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4568 if (!ParseRes.isSuccess()) {
4569 getLexer().UnLex(LCurly);
4573 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4575 unsigned PrevReg = FirstReg;
4577 SmallSet<unsigned, 8> DRegs;
4578 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4580 SmallSet<unsigned, 8> SeenRegs;
4581 SeenRegs.
insert(FirstReg);
4585 unsigned Reg, NextElementWidth;
4586 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4587 if (!ParseRes.isSuccess())
4591 if (ElementWidth != NextElementWidth)
4592 return Error(TileLoc,
"mismatched register size suffix");
4595 Warning(TileLoc,
"tile list not in ascending order");
4598 Warning(TileLoc,
"duplicate tile in list");
4601 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4610 unsigned RegMask = 0;
4611 for (
auto Reg : DRegs)
4615 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4620template <RegKind VectorKind>
4623 MCAsmParser &Parser = getParser();
4628 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4629 bool NoMatchIsError) -> ParseStatus {
4630 auto RegTok = getTok();
4631 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4632 if (ParseRes.isSuccess()) {
4639 RegTok.getString().equals_insensitive(
"zt0"))
4643 (ParseRes.isNoMatch() && NoMatchIsError &&
4644 !RegTok.getString().starts_with_insensitive(
"za")))
4645 return Error(Loc,
"vector register expected");
4650 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4652 auto LCurly = getTok();
4656 MCRegister FirstReg;
4657 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4661 if (ParseRes.isNoMatch())
4664 if (!ParseRes.isSuccess())
4667 MCRegister PrevReg = FirstReg;
4670 unsigned Stride = 1;
4672 SMLoc Loc = getLoc();
4676 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4677 if (!ParseRes.isSuccess())
4681 if (Kind != NextKind)
4682 return Error(Loc,
"mismatched register size suffix");
4685 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4687 if (Space == 0 || Space > 3)
4688 return Error(Loc,
"invalid number of vectors");
4693 bool HasCalculatedStride =
false;
4695 SMLoc Loc = getLoc();
4698 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4699 if (!ParseRes.isSuccess())
4703 if (Kind != NextKind)
4704 return Error(Loc,
"mismatched register size suffix");
4706 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4707 unsigned PrevRegVal =
4708 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4709 if (!HasCalculatedStride) {
4710 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4711 : (NumRegs - (PrevRegVal - RegVal));
4712 HasCalculatedStride =
true;
4716 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4717 return Error(Loc,
"registers must have the same sequential stride");
4728 return Error(S,
"invalid number of vectors");
4730 unsigned NumElements = 0;
4731 unsigned ElementWidth = 0;
4732 if (!
Kind.empty()) {
4734 std::tie(NumElements, ElementWidth) = *VK;
4737 Operands.push_back(AArch64Operand::CreateVectorList(
4738 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4742 ParseStatus Res = tryParseVectorIndex(
Operands);
4753 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4754 if (!ParseRes.isSuccess())
4757 return tryParseVectorIndex(
Operands).isFailure();
4761 SMLoc StartLoc = getLoc();
4764 ParseStatus Res = tryParseScalarRegister(RegNum);
4769 Operands.push_back(AArch64Operand::CreateReg(
4770 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4777 return Error(getLoc(),
"index must be absent or #0");
4779 const MCExpr *ImmVal;
4782 return Error(getLoc(),
"index must be absent or #0");
4784 Operands.push_back(AArch64Operand::CreateReg(
4785 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4790 SMLoc StartLoc = getLoc();
4791 const AsmToken &Tok = getTok();
4794 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4799 Operands.push_back(AArch64Operand::CreateReg(
4800 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4806 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4807 const MCExpr *ImmVal;
4808 if (getParser().parseExpression(ImmVal))
4812 return TokError(
"immediate value expected for vector index");
4813 Operands.push_back(AArch64Operand::CreateImm(
4817 if (parseOptionalMulOperand(
Operands))
4822 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4827template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4829 SMLoc StartLoc = getLoc();
4832 ParseStatus Res = tryParseScalarRegister(RegNum);
4838 Operands.push_back(AArch64Operand::CreateReg(
4839 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4848 Res = tryParseOptionalShiftExtend(ExtOpnd);
4852 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4853 Operands.push_back(AArch64Operand::CreateReg(
4854 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4855 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4856 Ext->hasShiftExtendAmount()));
4862 MCAsmParser &Parser = getParser();
4870 if (!getTok().getString().equals_insensitive(
"mul") ||
4871 !(NextIsVL || NextIsHash))
4875 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4880 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4890 const MCExpr *ImmVal;
4893 Operands.push_back(AArch64Operand::CreateImm(
4900 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4904 StringRef &VecGroup) {
4905 MCAsmParser &Parser = getParser();
4906 auto Tok = Parser.
getTok();
4911 .Case(
"vgx2",
"vgx2")
4912 .Case(
"vgx4",
"vgx4")
4924 auto Tok = getTok();
4931 .Case(
"csync",
"csync")
4934 .Case(
"keep",
"keep")
4938 .Case(
"stshstrm",
"stshstrm")
4939 .Case(
"strm",
"strm")
4952 bool invertCondCode) {
4953 MCAsmParser &Parser = getParser();
4956 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4970 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4972 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4975 getLexer().UnLex(SavedTok);
4979 switch (getLexer().getKind()) {
4983 if (parseSymbolicImmVal(Expr))
4984 return Error(S,
"invalid operand");
4988 return parseOptionalShiftExtend(getTok());
4992 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4997 return parseOperand(
Operands,
false,
false);
5000 if (!parseNeonVectorList(
Operands))
5004 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5009 return parseOperand(
Operands,
false,
false);
5014 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
5016 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5026 AsmToken SavedTok = getTok();
5031 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5035 Res = tryParseOptionalShiftExtend(
Operands);
5038 getLexer().UnLex(SavedTok);
5045 if (!parseOptionalMulOperand(
Operands))
5050 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5051 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5052 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh" ||
5054 return parseKeywordOperand(
Operands);
5058 const MCExpr *IdVal, *
Term;
5060 if (getParser().parseExpression(IdVal))
5062 if (getParser().parseAtSpecifier(IdVal,
E))
5064 std::optional<MCBinaryExpr::Opcode> Opcode;
5070 if (getParser().parsePrimaryExpr(Term,
E))
5077 return parseOptionalShiftExtend(getTok());
5088 bool isNegative =
false;
5100 const AsmToken &Tok = getTok();
5104 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5105 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5106 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5107 return TokError(
"unexpected floating point literal");
5108 else if (IntVal != 0 || isNegative)
5109 return TokError(
"expected floating-point constant #0.0");
5117 const MCExpr *ImmVal;
5118 if (parseSymbolicImmVal(ImmVal))
5125 return parseOptionalShiftExtend(Tok);
5128 SMLoc Loc = getLoc();
5129 if (Mnemonic !=
"ldr")
5130 return TokError(
"unexpected token in operand");
5132 const MCExpr *SubExprVal;
5133 if (getParser().parseExpression(SubExprVal))
5137 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5138 return Error(Loc,
"Only valid when first operand is register");
5140 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5148 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5153 if (ShiftAmt <= MaxShiftAmt &&
Imm <= 0xFFFF) {
5154 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5155 Operands.push_back(AArch64Operand::CreateImm(
5159 ShiftAmt,
true, S,
E, Ctx));
5162 APInt Simm = APInt(64,
Imm << ShiftAmt);
5165 return Error(Loc,
"Immediate too large for register");
5168 const MCExpr *CPLoc =
5169 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5170 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5176bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5177 const MCExpr *Expr =
nullptr;
5179 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5182 if (check(!
Value, L,
"expected constant expression"))
5188bool AArch64AsmParser::parseComma() {
5196bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5200 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register"))
5205 unsigned RangeEnd =
Last;
5206 if (
Base == AArch64::X0) {
5207 if (
Last == AArch64::FP) {
5208 RangeEnd = AArch64::X28;
5209 if (
Reg == AArch64::FP) {
5214 if (
Last == AArch64::LR) {
5215 RangeEnd = AArch64::X28;
5216 if (
Reg == AArch64::FP) {
5219 }
else if (
Reg == AArch64::LR) {
5227 Twine(
"expected register in range ") +
5235bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5236 const MCParsedAsmOperand &Op2)
const {
5237 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5238 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5240 if (AOp1.isVectorList() && AOp2.isVectorList())
5241 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5242 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5243 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5245 if (!AOp1.isReg() || !AOp2.isReg())
5248 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5249 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5252 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5253 "Testing equality of non-scalar registers not supported");
5256 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5258 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5260 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5262 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5269bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5270 StringRef Name, SMLoc NameLoc,
5272 Name = StringSwitch<StringRef>(
Name.lower())
5273 .Case(
"beq",
"b.eq")
5274 .Case(
"bne",
"b.ne")
5275 .Case(
"bhs",
"b.hs")
5276 .Case(
"bcs",
"b.cs")
5277 .Case(
"blo",
"b.lo")
5278 .Case(
"bcc",
"b.cc")
5279 .Case(
"bmi",
"b.mi")
5280 .Case(
"bpl",
"b.pl")
5281 .Case(
"bvs",
"b.vs")
5282 .Case(
"bvc",
"b.vc")
5283 .Case(
"bhi",
"b.hi")
5284 .Case(
"bls",
"b.ls")
5285 .Case(
"bge",
"b.ge")
5286 .Case(
"blt",
"b.lt")
5287 .Case(
"bgt",
"b.gt")
5288 .Case(
"ble",
"b.le")
5289 .Case(
"bal",
"b.al")
5290 .Case(
"bnv",
"b.nv")
5295 getTok().getIdentifier().lower() ==
".req") {
5296 parseDirectiveReq(Name, NameLoc);
5304 StringRef Head =
Name.slice(Start,
Next);
5308 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5309 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5310 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5311 return parseSysAlias(Head, NameLoc,
Operands);
5315 return parseSyslAlias(Head, NameLoc,
Operands);
5318 if (Head ==
"tlbip")
5319 return parseSyspAlias(Head, NameLoc,
Operands);
5325 if ((Head ==
"b" || Head ==
"bc" || Head ==
"flt") &&
5329 Head =
Name.slice(Start + 1,
Next);
5333 std::string Suggestion;
5336 std::string
Msg =
"invalid condition code";
5337 if (!Suggestion.empty())
5338 Msg +=
", did you mean " + Suggestion +
"?";
5344 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5354 Operands.push_back(AArch64Operand::CreateToken(
5360 bool condCodeFourthOperand =
5361 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5362 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5363 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5371 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5372 bool condCodeThirdOperand =
5373 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5381 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5382 (
N == 3 && condCodeThirdOperand) ||
5383 (
N == 2 && condCodeSecondOperand),
5384 condCodeSecondOperand || condCodeThirdOperand)) {
5404 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5407 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5410 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5423 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5424 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5425 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5426 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5427 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5428 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5429 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5441bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5442 SmallVectorImpl<SMLoc> &Loc) {
5443 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5450 PrefixInfo
Prefix = NextPrefix;
5451 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5462 return Error(IDLoc,
"instruction is unpredictable when following a"
5463 " movprfx, suggest replacing movprfx with mov");
5467 return Error(Loc[0],
"instruction is unpredictable when following a"
5468 " movprfx writing to a different destination");
5475 return Error(Loc[0],
"instruction is unpredictable when following a"
5476 " movprfx and destination also used as non-destructive"
5480 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5481 if (
Prefix.isPredicated()) {
5495 return Error(IDLoc,
"instruction is unpredictable when following a"
5496 " predicated movprfx, suggest using unpredicated movprfx");
5500 return Error(IDLoc,
"instruction is unpredictable when following a"
5501 " predicated movprfx using a different general predicate");
5505 return Error(IDLoc,
"instruction is unpredictable when following a"
5506 " predicated movprfx with a different element size");
5512 if (IsWindowsArm64EC) {
5518 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5519 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5520 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5521 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5522 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5523 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5524 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5525 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5526 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5527 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5529 " is disallowed on ARM64EC.");
5539 case AArch64::LDPSWpre:
5540 case AArch64::LDPWpost:
5541 case AArch64::LDPWpre:
5542 case AArch64::LDPXpost:
5543 case AArch64::LDPXpre: {
5548 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5549 "is also a destination");
5551 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5552 "is also a destination");
5555 case AArch64::LDR_ZA:
5556 case AArch64::STR_ZA: {
5559 return Error(Loc[1],
5560 "unpredictable instruction, immediate and offset mismatch.");
5563 case AArch64::LDPDi:
5564 case AArch64::LDPQi:
5565 case AArch64::LDPSi:
5566 case AArch64::LDPSWi:
5567 case AArch64::LDPWi:
5568 case AArch64::LDPXi: {
5572 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5575 case AArch64::LDPDpost:
5576 case AArch64::LDPDpre:
5577 case AArch64::LDPQpost:
5578 case AArch64::LDPQpre:
5579 case AArch64::LDPSpost:
5580 case AArch64::LDPSpre:
5581 case AArch64::LDPSWpost: {
5585 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5588 case AArch64::STPDpost:
5589 case AArch64::STPDpre:
5590 case AArch64::STPQpost:
5591 case AArch64::STPQpre:
5592 case AArch64::STPSpost:
5593 case AArch64::STPSpre:
5594 case AArch64::STPWpost:
5595 case AArch64::STPWpre:
5596 case AArch64::STPXpost:
5597 case AArch64::STPXpre: {
5602 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5603 "is also a source");
5605 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5606 "is also a source");
5609 case AArch64::LDRBBpre:
5610 case AArch64::LDRBpre:
5611 case AArch64::LDRHHpre:
5612 case AArch64::LDRHpre:
5613 case AArch64::LDRSBWpre:
5614 case AArch64::LDRSBXpre:
5615 case AArch64::LDRSHWpre:
5616 case AArch64::LDRSHXpre:
5617 case AArch64::LDRSWpre:
5618 case AArch64::LDRWpre:
5619 case AArch64::LDRXpre:
5620 case AArch64::LDRBBpost:
5621 case AArch64::LDRBpost:
5622 case AArch64::LDRHHpost:
5623 case AArch64::LDRHpost:
5624 case AArch64::LDRSBWpost:
5625 case AArch64::LDRSBXpost:
5626 case AArch64::LDRSHWpost:
5627 case AArch64::LDRSHXpost:
5628 case AArch64::LDRSWpost:
5629 case AArch64::LDRWpost:
5630 case AArch64::LDRXpost: {
5634 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5635 "is also a source");
5638 case AArch64::STRBBpost:
5639 case AArch64::STRBpost:
5640 case AArch64::STRHHpost:
5641 case AArch64::STRHpost:
5642 case AArch64::STRWpost:
5643 case AArch64::STRXpost:
5644 case AArch64::STRBBpre:
5645 case AArch64::STRBpre:
5646 case AArch64::STRHHpre:
5647 case AArch64::STRHpre:
5648 case AArch64::STRWpre:
5649 case AArch64::STRXpre: {
5653 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5654 "is also a source");
5657 case AArch64::STXRB:
5658 case AArch64::STXRH:
5659 case AArch64::STXRW:
5660 case AArch64::STXRX:
5661 case AArch64::STLXRB:
5662 case AArch64::STLXRH:
5663 case AArch64::STLXRW:
5664 case AArch64::STLXRX: {
5670 return Error(Loc[0],
5671 "unpredictable STXR instruction, status is also a source");
5674 case AArch64::STXPW:
5675 case AArch64::STXPX:
5676 case AArch64::STLXPW:
5677 case AArch64::STLXPX: {
5684 return Error(Loc[0],
5685 "unpredictable STXP instruction, status is also a source");
5688 case AArch64::LDRABwriteback:
5689 case AArch64::LDRAAwriteback: {
5693 return Error(Loc[0],
5694 "unpredictable LDRA instruction, writeback base"
5695 " is also a destination");
5702 case AArch64::CPYFP:
5703 case AArch64::CPYFPWN:
5704 case AArch64::CPYFPRN:
5705 case AArch64::CPYFPN:
5706 case AArch64::CPYFPWT:
5707 case AArch64::CPYFPWTWN:
5708 case AArch64::CPYFPWTRN:
5709 case AArch64::CPYFPWTN:
5710 case AArch64::CPYFPRT:
5711 case AArch64::CPYFPRTWN:
5712 case AArch64::CPYFPRTRN:
5713 case AArch64::CPYFPRTN:
5714 case AArch64::CPYFPT:
5715 case AArch64::CPYFPTWN:
5716 case AArch64::CPYFPTRN:
5717 case AArch64::CPYFPTN:
5718 case AArch64::CPYFM:
5719 case AArch64::CPYFMWN:
5720 case AArch64::CPYFMRN:
5721 case AArch64::CPYFMN:
5722 case AArch64::CPYFMWT:
5723 case AArch64::CPYFMWTWN:
5724 case AArch64::CPYFMWTRN:
5725 case AArch64::CPYFMWTN:
5726 case AArch64::CPYFMRT:
5727 case AArch64::CPYFMRTWN:
5728 case AArch64::CPYFMRTRN:
5729 case AArch64::CPYFMRTN:
5730 case AArch64::CPYFMT:
5731 case AArch64::CPYFMTWN:
5732 case AArch64::CPYFMTRN:
5733 case AArch64::CPYFMTN:
5734 case AArch64::CPYFE:
5735 case AArch64::CPYFEWN:
5736 case AArch64::CPYFERN:
5737 case AArch64::CPYFEN:
5738 case AArch64::CPYFEWT:
5739 case AArch64::CPYFEWTWN:
5740 case AArch64::CPYFEWTRN:
5741 case AArch64::CPYFEWTN:
5742 case AArch64::CPYFERT:
5743 case AArch64::CPYFERTWN:
5744 case AArch64::CPYFERTRN:
5745 case AArch64::CPYFERTN:
5746 case AArch64::CPYFET:
5747 case AArch64::CPYFETWN:
5748 case AArch64::CPYFETRN:
5749 case AArch64::CPYFETN:
5751 case AArch64::CPYPWN:
5752 case AArch64::CPYPRN:
5753 case AArch64::CPYPN:
5754 case AArch64::CPYPWT:
5755 case AArch64::CPYPWTWN:
5756 case AArch64::CPYPWTRN:
5757 case AArch64::CPYPWTN:
5758 case AArch64::CPYPRT:
5759 case AArch64::CPYPRTWN:
5760 case AArch64::CPYPRTRN:
5761 case AArch64::CPYPRTN:
5762 case AArch64::CPYPT:
5763 case AArch64::CPYPTWN:
5764 case AArch64::CPYPTRN:
5765 case AArch64::CPYPTN:
5767 case AArch64::CPYMWN:
5768 case AArch64::CPYMRN:
5769 case AArch64::CPYMN:
5770 case AArch64::CPYMWT:
5771 case AArch64::CPYMWTWN:
5772 case AArch64::CPYMWTRN:
5773 case AArch64::CPYMWTN:
5774 case AArch64::CPYMRT:
5775 case AArch64::CPYMRTWN:
5776 case AArch64::CPYMRTRN:
5777 case AArch64::CPYMRTN:
5778 case AArch64::CPYMT:
5779 case AArch64::CPYMTWN:
5780 case AArch64::CPYMTRN:
5781 case AArch64::CPYMTN:
5783 case AArch64::CPYEWN:
5784 case AArch64::CPYERN:
5785 case AArch64::CPYEN:
5786 case AArch64::CPYEWT:
5787 case AArch64::CPYEWTWN:
5788 case AArch64::CPYEWTRN:
5789 case AArch64::CPYEWTN:
5790 case AArch64::CPYERT:
5791 case AArch64::CPYERTWN:
5792 case AArch64::CPYERTRN:
5793 case AArch64::CPYERTN:
5794 case AArch64::CPYET:
5795 case AArch64::CPYETWN:
5796 case AArch64::CPYETRN:
5797 case AArch64::CPYETN: {
5808 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5809 " registers are the same");
5811 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5812 " registers are the same");
5814 return Error(Loc[0],
"invalid CPY instruction, source and size"
5815 " registers are the same");
5819 case AArch64::SETPT:
5820 case AArch64::SETPN:
5821 case AArch64::SETPTN:
5823 case AArch64::SETMT:
5824 case AArch64::SETMN:
5825 case AArch64::SETMTN:
5827 case AArch64::SETET:
5828 case AArch64::SETEN:
5829 case AArch64::SETETN:
5830 case AArch64::SETGP:
5831 case AArch64::SETGPT:
5832 case AArch64::SETGPN:
5833 case AArch64::SETGPTN:
5834 case AArch64::SETGM:
5835 case AArch64::SETGMT:
5836 case AArch64::SETGMN:
5837 case AArch64::SETGMTN:
5838 case AArch64::MOPSSETGE:
5839 case AArch64::MOPSSETGET:
5840 case AArch64::MOPSSETGEN:
5841 case AArch64::MOPSSETGETN: {
5851 return Error(Loc[0],
"invalid SET instruction, destination and size"
5852 " registers are the same");
5854 return Error(Loc[0],
"invalid SET instruction, destination and source"
5855 " registers are the same");
5857 return Error(Loc[0],
"invalid SET instruction, source and size"
5858 " registers are the same");
5861 case AArch64::SETGOP:
5862 case AArch64::SETGOPT:
5863 case AArch64::SETGOPN:
5864 case AArch64::SETGOPTN:
5865 case AArch64::SETGOM:
5866 case AArch64::SETGOMT:
5867 case AArch64::SETGOMN:
5868 case AArch64::SETGOMTN:
5869 case AArch64::SETGOE:
5870 case AArch64::SETGOET:
5871 case AArch64::SETGOEN:
5872 case AArch64::SETGOETN: {
5881 return Error(Loc[0],
"invalid SET instruction, destination and size"
5882 " registers are the same");
5891 case AArch64::ADDSWri:
5892 case AArch64::ADDSXri:
5893 case AArch64::ADDWri:
5894 case AArch64::ADDXri:
5895 case AArch64::SUBSWri:
5896 case AArch64::SUBSXri:
5897 case AArch64::SUBWri:
5898 case AArch64::SUBXri: {
5906 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5931 return Error(Loc.
back(),
"invalid immediate expression");
5944 unsigned VariantID = 0);
5946bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5950 case Match_InvalidTiedOperand: {
5952 if (
Op.isVectorList())
5953 return Error(
Loc,
"operand must match destination register list");
5955 assert(
Op.isReg() &&
"Unexpected operand type");
5956 switch (
Op.getRegEqualityTy()) {
5957 case RegConstraintEqualityTy::EqualsSubReg:
5958 return Error(
Loc,
"operand must be 64-bit form of destination register");
5959 case RegConstraintEqualityTy::EqualsSuperReg:
5960 return Error(
Loc,
"operand must be 32-bit form of destination register");
5961 case RegConstraintEqualityTy::EqualsReg:
5962 return Error(
Loc,
"operand must match destination register");
5966 case Match_MissingFeature:
5968 "instruction requires a CPU feature not currently enabled");
5969 case Match_InvalidOperand:
5970 return Error(Loc,
"invalid operand for instruction");
5971 case Match_InvalidSuffix:
5972 return Error(Loc,
"invalid type suffix for instruction");
5973 case Match_InvalidCondCode:
5974 return Error(Loc,
"expected AArch64 condition code");
5975 case Match_AddSubRegExtendSmall:
5977 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5978 case Match_AddSubRegExtendLarge:
5980 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5981 case Match_AddSubSecondSource:
5983 "expected compatible register, symbol or integer in range [0, 4095]");
5984 case Match_LogicalSecondSource:
5985 return Error(Loc,
"expected compatible register or logical immediate");
5986 case Match_InvalidMovImm32Shift:
5987 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5988 case Match_InvalidMovImm64Shift:
5989 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5990 case Match_AddSubRegShift32:
5992 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5993 case Match_AddSubRegShift64:
5995 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5996 case Match_InvalidFPImm:
5998 "expected compatible register or floating-point constant");
5999 case Match_InvalidMemoryIndexedSImm6:
6000 return Error(Loc,
"index must be an integer in range [-32, 31].");
6001 case Match_InvalidMemoryIndexedSImm5:
6002 return Error(Loc,
"index must be an integer in range [-16, 15].");
6003 case Match_InvalidMemoryIndexed1SImm4:
6004 return Error(Loc,
"index must be an integer in range [-8, 7].");
6005 case Match_InvalidMemoryIndexed2SImm4:
6006 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6007 case Match_InvalidMemoryIndexed3SImm4:
6008 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6009 case Match_InvalidMemoryIndexed4SImm4:
6010 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6011 case Match_InvalidMemoryIndexed16SImm4:
6012 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6013 case Match_InvalidMemoryIndexed32SImm4:
6014 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6015 case Match_InvalidMemoryIndexed1SImm6:
6016 return Error(Loc,
"index must be an integer in range [-32, 31].");
6017 case Match_InvalidMemoryIndexedSImm8:
6018 return Error(Loc,
"index must be an integer in range [-128, 127].");
6019 case Match_InvalidMemoryIndexedSImm9:
6020 return Error(Loc,
"index must be an integer in range [-256, 255].");
6021 case Match_InvalidMemoryIndexed16SImm9:
6022 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6023 case Match_InvalidMemoryIndexed8SImm10:
6024 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6025 case Match_InvalidMemoryIndexed4SImm7:
6026 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6027 case Match_InvalidMemoryIndexed8SImm7:
6028 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6029 case Match_InvalidMemoryIndexed16SImm7:
6030 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6031 case Match_InvalidMemoryIndexed8UImm5:
6032 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6033 case Match_InvalidMemoryIndexed8UImm3:
6034 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6035 case Match_InvalidMemoryIndexed4UImm5:
6036 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6037 case Match_InvalidMemoryIndexed2UImm5:
6038 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6039 case Match_InvalidMemoryIndexed8UImm6:
6040 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6041 case Match_InvalidMemoryIndexed16UImm6:
6042 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6043 case Match_InvalidMemoryIndexed4UImm6:
6044 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6045 case Match_InvalidMemoryIndexed2UImm6:
6046 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6047 case Match_InvalidMemoryIndexed1UImm6:
6048 return Error(Loc,
"index must be in range [0, 63].");
6049 case Match_InvalidMemoryWExtend8:
6051 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6052 case Match_InvalidMemoryWExtend16:
6054 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6055 case Match_InvalidMemoryWExtend32:
6057 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6058 case Match_InvalidMemoryWExtend64:
6060 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6061 case Match_InvalidMemoryWExtend128:
6063 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6064 case Match_InvalidMemoryXExtend8:
6066 "expected 'lsl' or 'sxtx' with optional shift of #0");
6067 case Match_InvalidMemoryXExtend16:
6069 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6070 case Match_InvalidMemoryXExtend32:
6072 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6073 case Match_InvalidMemoryXExtend64:
6075 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6076 case Match_InvalidMemoryXExtend128:
6078 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6079 case Match_InvalidMemoryIndexed1:
6080 return Error(Loc,
"index must be an integer in range [0, 4095].");
6081 case Match_InvalidMemoryIndexed2:
6082 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6083 case Match_InvalidMemoryIndexed4:
6084 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6085 case Match_InvalidMemoryIndexed8:
6086 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6087 case Match_InvalidMemoryIndexed16:
6088 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6089 case Match_InvalidImm0_0:
6090 return Error(Loc,
"immediate must be 0.");
6091 case Match_InvalidImm0_1:
6092 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6093 case Match_InvalidImm0_3:
6094 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6095 case Match_InvalidImm0_7:
6096 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6097 case Match_InvalidImm0_15:
6098 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6099 case Match_InvalidImm0_31:
6100 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6101 case Match_InvalidImm0_63:
6102 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6103 case Match_InvalidImm0_127:
6104 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6105 case Match_InvalidImm0_255:
6106 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6107 case Match_InvalidImm0_511:
6108 return Error(Loc,
"immediate must be an integer in range [0, 511].");
6109 case Match_InvalidImm0_65535:
6110 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6111 case Match_InvalidHinteUImm16:
6113 "immediate must be an integer in range [0, 65535], excluding "
6114 "values in range [12319, 16383] where (value - 12319) is a "
6116 case Match_InvalidImm1_8:
6117 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6118 case Match_InvalidImm1_16:
6119 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6120 case Match_InvalidImm1_32:
6121 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6122 case Match_InvalidImm1_64:
6123 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6124 case Match_InvalidImm1_512:
6125 return Error(Loc,
"immediate must be an integer in range [1, 512].");
6126 case Match_InvalidImmM1_62:
6127 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6128 case Match_InvalidImmM1_510:
6129 return Error(Loc,
"immediate must be an integer in range [-1, 510].");
6130 case Match_InvalidImmM255_256:
6131 return Error(Loc,
"immediate must be an integer in range [-255, 256].");
6132 case Match_InvalidImmM257_254:
6133 return Error(Loc,
"immediate must be an integer in range [-257, 254].");
6134 case Match_InvalidMemoryIndexedRange2UImm0:
6135 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6136 case Match_InvalidMemoryIndexedRange2UImm1:
6137 return Error(Loc,
"vector select offset must be an immediate range of the "
6138 "form <immf>:<imml>, where the first "
6139 "immediate is a multiple of 2 in the range [0, 2], and "
6140 "the second immediate is immf + 1.");
6141 case Match_InvalidMemoryIndexedRange2UImm2:
6142 case Match_InvalidMemoryIndexedRange2UImm3:
6145 "vector select offset must be an immediate range of the form "
6147 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6149 "depending on the instruction, and the second immediate is immf + 1.");
6150 case Match_InvalidMemoryIndexedRange4UImm0:
6151 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6152 case Match_InvalidMemoryIndexedRange4UImm1:
6153 case Match_InvalidMemoryIndexedRange4UImm2:
6156 "vector select offset must be an immediate range of the form "
6158 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6160 "depending on the instruction, and the second immediate is immf + 3.");
6161 case Match_InvalidSVEAddSubImm8:
6162 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6163 " with a shift amount of 0");
6164 case Match_InvalidSVEAddSubImm16:
6165 case Match_InvalidSVEAddSubImm32:
6166 case Match_InvalidSVEAddSubImm64:
6167 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6168 "multiple of 256 in range [256, 65280]");
6169 case Match_InvalidSVECpyImm8:
6170 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6171 " with a shift amount of 0");
6172 case Match_InvalidSVECpyImm16:
6173 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6174 "multiple of 256 in range [-32768, 65280]");
6175 case Match_InvalidSVECpyImm32:
6176 case Match_InvalidSVECpyImm64:
6177 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6178 "multiple of 256 in range [-32768, 32512]");
6179 case Match_InvalidIndexRange0_0:
6180 return Error(Loc,
"expected lane specifier '[0]'");
6181 case Match_InvalidIndexRange1_1:
6182 return Error(Loc,
"expected lane specifier '[1]'");
6183 case Match_InvalidIndexRange0_15:
6184 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6185 case Match_InvalidIndexRange0_7:
6186 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6187 case Match_InvalidIndexRange0_3:
6188 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6189 case Match_InvalidIndexRange0_1:
6190 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6191 case Match_InvalidSVEIndexRange0_63:
6192 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6193 case Match_InvalidSVEIndexRange0_31:
6194 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6195 case Match_InvalidSVEIndexRange0_15:
6196 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6197 case Match_InvalidSVEIndexRange0_7:
6198 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6199 case Match_InvalidSVEIndexRange0_3:
6200 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6201 case Match_InvalidLabel:
6202 return Error(Loc,
"expected label or encodable integer pc offset");
6204 return Error(Loc,
"expected readable system register");
6206 case Match_InvalidSVCR:
6207 return Error(Loc,
"expected writable system register or pstate");
6208 case Match_InvalidComplexRotationEven:
6209 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6210 case Match_InvalidComplexRotationOdd:
6211 return Error(Loc,
"complex rotation must be 90 or 270.");
6212 case Match_MnemonicFail: {
6215 ComputeAvailableFeatures(STI->getFeatureBits()));
6216 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6218 case Match_InvalidGPR64shifted8:
6219 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6220 case Match_InvalidGPR64shifted16:
6221 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6222 case Match_InvalidGPR64shifted32:
6223 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6224 case Match_InvalidGPR64shifted64:
6225 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6226 case Match_InvalidGPR64shifted128:
6228 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6229 case Match_InvalidGPR64NoXZRshifted8:
6230 return Error(Loc,
"register must be x0..x30 without shift");
6231 case Match_InvalidGPR64NoXZRshifted16:
6232 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6233 case Match_InvalidGPR64NoXZRshifted32:
6234 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6235 case Match_InvalidGPR64NoXZRshifted64:
6236 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6237 case Match_InvalidGPR64NoXZRshifted128:
6238 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6239 case Match_InvalidZPR32UXTW8:
6240 case Match_InvalidZPR32SXTW8:
6241 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6242 case Match_InvalidZPR32UXTW16:
6243 case Match_InvalidZPR32SXTW16:
6244 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6245 case Match_InvalidZPR32UXTW32:
6246 case Match_InvalidZPR32SXTW32:
6247 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6248 case Match_InvalidZPR32UXTW64:
6249 case Match_InvalidZPR32SXTW64:
6250 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6251 case Match_InvalidZPR64UXTW8:
6252 case Match_InvalidZPR64SXTW8:
6253 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6254 case Match_InvalidZPR64UXTW16:
6255 case Match_InvalidZPR64SXTW16:
6256 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6257 case Match_InvalidZPR64UXTW32:
6258 case Match_InvalidZPR64SXTW32:
6259 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6260 case Match_InvalidZPR64UXTW64:
6261 case Match_InvalidZPR64SXTW64:
6262 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6263 case Match_InvalidZPR32LSL8:
6264 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6265 case Match_InvalidZPR32LSL16:
6266 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6267 case Match_InvalidZPR32LSL32:
6268 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6269 case Match_InvalidZPR32LSL64:
6270 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6271 case Match_InvalidZPR64LSL8:
6272 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6273 case Match_InvalidZPR64LSL16:
6274 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6275 case Match_InvalidZPR64LSL32:
6276 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6277 case Match_InvalidZPR64LSL64:
6278 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6279 case Match_InvalidZPR0:
6280 return Error(Loc,
"expected register without element width suffix");
6281 case Match_InvalidZPR8:
6282 case Match_InvalidZPR16:
6283 case Match_InvalidZPR32:
6284 case Match_InvalidZPR64:
6285 case Match_InvalidZPR128:
6286 return Error(Loc,
"invalid element width");
6287 case Match_InvalidZPR_3b8:
6288 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6289 case Match_InvalidZPR_3b16:
6290 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6291 case Match_InvalidZPR_3b32:
6292 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6293 case Match_InvalidZPR_4b8:
6295 "Invalid restricted vector register, expected z0.b..z15.b");
6296 case Match_InvalidZPR_4b16:
6297 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6298 case Match_InvalidZPR_4b32:
6299 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6300 case Match_InvalidZPR_4b64:
6301 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6302 case Match_InvalidZPRMul2_Lo8:
6303 return Error(Loc,
"Invalid restricted vector register, expected even "
6304 "register in z0.b..z14.b");
6305 case Match_InvalidZPRMul2_Hi8:
6306 return Error(Loc,
"Invalid restricted vector register, expected even "
6307 "register in z16.b..z30.b");
6308 case Match_InvalidZPRMul2_Lo16:
6309 return Error(Loc,
"Invalid restricted vector register, expected even "
6310 "register in z0.h..z14.h");
6311 case Match_InvalidZPRMul2_Hi16:
6312 return Error(Loc,
"Invalid restricted vector register, expected even "
6313 "register in z16.h..z30.h");
6314 case Match_InvalidZPRMul2_Lo32:
6315 return Error(Loc,
"Invalid restricted vector register, expected even "
6316 "register in z0.s..z14.s");
6317 case Match_InvalidZPRMul2_Hi32:
6318 return Error(Loc,
"Invalid restricted vector register, expected even "
6319 "register in z16.s..z30.s");
6320 case Match_InvalidZPRMul2_Lo64:
6321 return Error(Loc,
"Invalid restricted vector register, expected even "
6322 "register in z0.d..z14.d");
6323 case Match_InvalidZPRMul2_Hi64:
6324 return Error(Loc,
"Invalid restricted vector register, expected even "
6325 "register in z16.d..z30.d");
6326 case Match_InvalidZPR_K0:
6327 return Error(Loc,
"invalid restricted vector register, expected register "
6328 "in z20..z23 or z28..z31");
6329 case Match_InvalidSVEPattern:
6330 return Error(Loc,
"invalid predicate pattern");
6331 case Match_InvalidSVEPPRorPNRAnyReg:
6332 case Match_InvalidSVEPPRorPNRBReg:
6333 case Match_InvalidSVEPredicateAnyReg:
6334 case Match_InvalidSVEPredicateBReg:
6335 case Match_InvalidSVEPredicateHReg:
6336 case Match_InvalidSVEPredicateSReg:
6337 case Match_InvalidSVEPredicateDReg:
6338 return Error(Loc,
"invalid predicate register.");
6339 case Match_InvalidSVEPredicate3bAnyReg:
6340 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6341 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6342 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6343 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6344 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6345 return Error(Loc,
"Invalid predicate register, expected PN in range "
6346 "pn8..pn15 with element suffix.");
6347 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6348 return Error(Loc,
"invalid restricted predicate-as-counter register "
6349 "expected pn8..pn15");
6350 case Match_InvalidSVEPNPredicateBReg:
6351 case Match_InvalidSVEPNPredicateHReg:
6352 case Match_InvalidSVEPNPredicateSReg:
6353 case Match_InvalidSVEPNPredicateDReg:
6354 return Error(Loc,
"Invalid predicate register, expected PN in range "
6355 "pn0..pn15 with element suffix.");
6356 case Match_InvalidSVEVecLenSpecifier:
6357 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6358 case Match_InvalidSVEPredicateListMul2x8:
6359 case Match_InvalidSVEPredicateListMul2x16:
6360 case Match_InvalidSVEPredicateListMul2x32:
6361 case Match_InvalidSVEPredicateListMul2x64:
6362 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6363 "predicate registers, where the first vector is a multiple of 2 "
6364 "and with correct element type");
6365 case Match_InvalidSVEExactFPImmOperandHalfOne:
6366 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6367 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6368 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6369 case Match_InvalidSVEExactFPImmOperandZeroOne:
6370 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6371 case Match_InvalidMatrixTileVectorH8:
6372 case Match_InvalidMatrixTileVectorV8:
6373 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6374 case Match_InvalidMatrixTileVectorH16:
6375 case Match_InvalidMatrixTileVectorV16:
6377 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6378 case Match_InvalidMatrixTileVectorH32:
6379 case Match_InvalidMatrixTileVectorV32:
6381 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6382 case Match_InvalidMatrixTileVectorH64:
6383 case Match_InvalidMatrixTileVectorV64:
6385 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6386 case Match_InvalidMatrixTileVectorH128:
6387 case Match_InvalidMatrixTileVectorV128:
6389 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6390 case Match_InvalidMatrixTile16:
6391 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6392 case Match_InvalidMatrixTile32:
6393 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6394 case Match_InvalidMatrixTile64:
6395 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6396 case Match_InvalidMatrix:
6397 return Error(Loc,
"invalid matrix operand, expected za");
6398 case Match_InvalidMatrix8:
6399 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6400 case Match_InvalidMatrix16:
6401 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6402 case Match_InvalidMatrix32:
6403 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6404 case Match_InvalidMatrix64:
6405 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6406 case Match_InvalidMatrixIndexGPR32_12_15:
6407 return Error(Loc,
"operand must be a register in range [w12, w15]");
6408 case Match_InvalidMatrixIndexGPR32_8_11:
6409 return Error(Loc,
"operand must be a register in range [w8, w11]");
6410 case Match_InvalidSVEVectorList2x8Mul2:
6411 case Match_InvalidSVEVectorList2x16Mul2:
6412 case Match_InvalidSVEVectorList2x32Mul2:
6413 case Match_InvalidSVEVectorList2x64Mul2:
6414 case Match_InvalidSVEVectorList2x128Mul2:
6415 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6416 "SVE vectors, where the first vector is a multiple of 2 "
6417 "and with matching element types");
6418 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6419 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6420 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6421 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6422 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6423 "SVE vectors in the range z0-z14, where the first vector "
6424 "is a multiple of 2 "
6425 "and with matching element types");
6426 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6427 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6428 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6429 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6431 "Invalid vector list, expected list with 2 consecutive "
6432 "SVE vectors in the range z16-z30, where the first vector "
6433 "is a multiple of 2 "
6434 "and with matching element types");
6435 case Match_InvalidSVEVectorList4x8Mul4:
6436 case Match_InvalidSVEVectorList4x16Mul4:
6437 case Match_InvalidSVEVectorList4x32Mul4:
6438 case Match_InvalidSVEVectorList4x64Mul4:
6439 case Match_InvalidSVEVectorList4x128Mul4:
6440 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6441 "SVE vectors, where the first vector is a multiple of 4 "
6442 "and with matching element types");
6443 case Match_InvalidSVEVectorList3x0_3b:
6444 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6445 "SVE vectors starting at z0-z7");
6446 case Match_InvalidLookupTable:
6447 return Error(Loc,
"Invalid lookup table, expected zt0");
6448 case Match_InvalidSVEVectorListStrided2x8:
6449 case Match_InvalidSVEVectorListStrided2x16:
6450 case Match_InvalidSVEVectorListStrided2x32:
6451 case Match_InvalidSVEVectorListStrided2x64:
6454 "Invalid vector list, expected list with each SVE vector in the list "
6455 "8 registers apart, and the first register in the range [z0, z7] or "
6456 "[z16, z23] and with correct element type");
6457 case Match_InvalidSVEVectorListStrided4x8:
6458 case Match_InvalidSVEVectorListStrided4x16:
6459 case Match_InvalidSVEVectorListStrided4x32:
6460 case Match_InvalidSVEVectorListStrided4x64:
6463 "Invalid vector list, expected list with each SVE vector in the list "
6464 "4 registers apart, and the first register in the range [z0, z3] or "
6465 "[z16, z19] and with correct element type");
6466 case Match_AddSubLSLImm3ShiftLarge:
6468 "expected 'lsl' with optional integer in range [0, 7]");
6476bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6480 bool MatchingInlineAsm) {
6482 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6483 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6486 unsigned NumOperands =
Operands.size();
6488 if (NumOperands == 4 && Tok ==
"lsl") {
6489 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6490 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6491 if (Op2.isScalarReg() && Op3.isImm()) {
6497 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6499 NewOp3Val = (32 - Op3Val) & 0x1f;
6500 NewOp4Val = 31 - Op3Val;
6502 NewOp3Val = (64 - Op3Val) & 0x3f;
6503 NewOp4Val = 63 - Op3Val;
6510 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6511 Operands.push_back(AArch64Operand::CreateImm(
6512 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6513 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6517 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6519 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6520 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6521 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6523 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6527 if (LSBCE && WidthCE) {
6532 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6538 if (LSB >= RegWidth)
6539 return Error(LSBOp.getStartLoc(),
6540 "expected integer in range [0, 31]");
6541 if (Width < 1 || Width > RegWidth)
6542 return Error(WidthOp.getStartLoc(),
6543 "expected integer in range [1, 32]");
6547 ImmR = (32 - LSB) & 0x1f;
6549 ImmR = (64 - LSB) & 0x3f;
6553 if (ImmR != 0 && ImmS >= ImmR)
6554 return Error(WidthOp.getStartLoc(),
6555 "requested insert overflows register");
6560 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6561 Operands[2] = AArch64Operand::CreateReg(
6562 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6564 Operands[3] = AArch64Operand::CreateImm(
6565 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6567 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6571 }
else if (NumOperands == 5) {
6574 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6575 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6576 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6577 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6579 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6583 if (Op3CE && Op4CE) {
6588 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6594 if (Op3Val >= RegWidth)
6595 return Error(Op3.getStartLoc(),
6596 "expected integer in range [0, 31]");
6597 if (Op4Val < 1 || Op4Val > RegWidth)
6598 return Error(Op4.getStartLoc(),
6599 "expected integer in range [1, 32]");
6603 NewOp3Val = (32 - Op3Val) & 0x1f;
6605 NewOp3Val = (64 - Op3Val) & 0x3f;
6609 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6610 return Error(Op4.getStartLoc(),
6611 "requested insert overflows register");
6613 const MCExpr *NewOp3 =
6615 const MCExpr *NewOp4 =
6617 Operands[3] = AArch64Operand::CreateImm(
6618 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6619 Operands[4] = AArch64Operand::CreateImm(
6620 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6622 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6624 else if (Tok ==
"sbfiz")
6625 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6627 else if (Tok ==
"ubfiz")
6628 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6637 }
else if (NumOperands == 5 &&
6638 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6639 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6640 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6641 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6643 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6647 if (Op3CE && Op4CE) {
6652 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6658 if (Op3Val >= RegWidth)
6659 return Error(Op3.getStartLoc(),
6660 "expected integer in range [0, 31]");
6661 if (Op4Val < 1 || Op4Val > RegWidth)
6662 return Error(Op4.getStartLoc(),
6663 "expected integer in range [1, 32]");
6665 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6667 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6668 return Error(Op4.getStartLoc(),
6669 "requested extract overflows register");
6671 const MCExpr *NewOp4 =
6673 Operands[4] = AArch64Operand::CreateImm(
6674 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6676 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6678 else if (Tok ==
"sbfx")
6679 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6681 else if (Tok ==
"ubfx")
6682 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6695 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6696 NumOperands == 4 && Tok ==
"movi") {
6697 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6698 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6699 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6700 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6701 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6702 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6703 if (Suffix.
lower() ==
".2d" &&
6705 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6706 " correctly on this CPU, converting to equivalent movi.16b");
6708 unsigned Idx = Op1.isToken() ? 1 : 2;
6710 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6718 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6721 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6722 if (
Op.isScalarReg()) {
6724 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6725 Op.getStartLoc(),
Op.getEndLoc(),
6730 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6731 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6732 if (
Op.isScalarReg() &&
6733 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6737 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6738 if (
Op.isScalarReg()) {
6740 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6747 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6748 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6749 if (
Op.isScalarReg() &&
6750 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6754 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6755 if (
Op.isScalarReg()) {
6757 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6765 FeatureBitset MissingFeatures;
6768 unsigned MatchResult =
6769 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6770 MatchingInlineAsm, 1);
6774 if (MatchResult != Match_Success) {
6777 auto ShortFormNEONErrorInfo = ErrorInfo;
6778 auto ShortFormNEONMatchResult = MatchResult;
6779 auto ShortFormNEONMissingFeatures = MissingFeatures;
6782 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6783 MatchingInlineAsm, 0);
6788 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6790 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6791 MatchResult = ShortFormNEONMatchResult;
6792 ErrorInfo = ShortFormNEONErrorInfo;
6793 MissingFeatures = ShortFormNEONMissingFeatures;
6797 switch (MatchResult) {
6798 case Match_Success: {
6802 for (
unsigned i = 1; i < NumOperands; ++i)
6804 if (validateInstruction(Inst, IDLoc, OperandLocs))
6808 Out.emitInstruction(Inst, getSTI());
6811 case Match_MissingFeature: {
6812 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6815 std::string
Msg =
"instruction requires:";
6816 for (
unsigned Feature : MissingFeatures) {
6822 case Match_MnemonicFail:
6823 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6824 case Match_InvalidOperand: {
6825 SMLoc ErrorLoc = IDLoc;
6827 if (ErrorInfo != ~0ULL) {
6829 return Error(IDLoc,
"too few operands for instruction",
6830 SMRange(IDLoc, getTok().getLoc()));
6832 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6833 if (ErrorLoc == SMLoc())
6838 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6839 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6840 MatchResult = Match_InvalidSuffix;
6842 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6844 case Match_InvalidTiedOperand:
6845 case Match_InvalidMemoryIndexed1:
6846 case Match_InvalidMemoryIndexed2:
6847 case Match_InvalidMemoryIndexed4:
6848 case Match_InvalidMemoryIndexed8:
6849 case Match_InvalidMemoryIndexed16:
6850 case Match_InvalidCondCode:
6851 case Match_AddSubLSLImm3ShiftLarge:
6852 case Match_AddSubRegExtendSmall:
6853 case Match_AddSubRegExtendLarge:
6854 case Match_AddSubSecondSource:
6855 case Match_LogicalSecondSource:
6856 case Match_AddSubRegShift32:
6857 case Match_AddSubRegShift64:
6858 case Match_InvalidMovImm32Shift:
6859 case Match_InvalidMovImm64Shift:
6860 case Match_InvalidFPImm:
6861 case Match_InvalidMemoryWExtend8:
6862 case Match_InvalidMemoryWExtend16:
6863 case Match_InvalidMemoryWExtend32:
6864 case Match_InvalidMemoryWExtend64:
6865 case Match_InvalidMemoryWExtend128:
6866 case Match_InvalidMemoryXExtend8:
6867 case Match_InvalidMemoryXExtend16:
6868 case Match_InvalidMemoryXExtend32:
6869 case Match_InvalidMemoryXExtend64:
6870 case Match_InvalidMemoryXExtend128:
6871 case Match_InvalidMemoryIndexed1SImm4:
6872 case Match_InvalidMemoryIndexed2SImm4:
6873 case Match_InvalidMemoryIndexed3SImm4:
6874 case Match_InvalidMemoryIndexed4SImm4:
6875 case Match_InvalidMemoryIndexed1SImm6:
6876 case Match_InvalidMemoryIndexed16SImm4:
6877 case Match_InvalidMemoryIndexed32SImm4:
6878 case Match_InvalidMemoryIndexed4SImm7:
6879 case Match_InvalidMemoryIndexed8SImm7:
6880 case Match_InvalidMemoryIndexed16SImm7:
6881 case Match_InvalidMemoryIndexed8UImm5:
6882 case Match_InvalidMemoryIndexed8UImm3:
6883 case Match_InvalidMemoryIndexed4UImm5:
6884 case Match_InvalidMemoryIndexed2UImm5:
6885 case Match_InvalidMemoryIndexed1UImm6:
6886 case Match_InvalidMemoryIndexed2UImm6:
6887 case Match_InvalidMemoryIndexed4UImm6:
6888 case Match_InvalidMemoryIndexed8UImm6:
6889 case Match_InvalidMemoryIndexed16UImm6:
6890 case Match_InvalidMemoryIndexedSImm6:
6891 case Match_InvalidMemoryIndexedSImm5:
6892 case Match_InvalidMemoryIndexedSImm8:
6893 case Match_InvalidMemoryIndexedSImm9:
6894 case Match_InvalidMemoryIndexed16SImm9:
6895 case Match_InvalidMemoryIndexed8SImm10:
6896 case Match_InvalidImm0_0:
6897 case Match_InvalidImm0_1:
6898 case Match_InvalidImm0_3:
6899 case Match_InvalidImm0_7:
6900 case Match_InvalidImm0_15:
6901 case Match_InvalidImm0_31:
6902 case Match_InvalidImm0_63:
6903 case Match_InvalidImm0_127:
6904 case Match_InvalidImm0_255:
6905 case Match_InvalidImm0_511:
6906 case Match_InvalidImm0_65535:
6907 case Match_InvalidHinteUImm16:
6908 case Match_InvalidImm1_8:
6909 case Match_InvalidImm1_16:
6910 case Match_InvalidImm1_32:
6911 case Match_InvalidImm1_64:
6912 case Match_InvalidImm1_512:
6913 case Match_InvalidImmM1_62:
6914 case Match_InvalidImmM1_510:
6915 case Match_InvalidImmM255_256:
6916 case Match_InvalidImmM257_254:
6917 case Match_InvalidMemoryIndexedRange2UImm0:
6918 case Match_InvalidMemoryIndexedRange2UImm1:
6919 case Match_InvalidMemoryIndexedRange2UImm2:
6920 case Match_InvalidMemoryIndexedRange2UImm3:
6921 case Match_InvalidMemoryIndexedRange4UImm0:
6922 case Match_InvalidMemoryIndexedRange4UImm1:
6923 case Match_InvalidMemoryIndexedRange4UImm2:
6924 case Match_InvalidSVEAddSubImm8:
6925 case Match_InvalidSVEAddSubImm16:
6926 case Match_InvalidSVEAddSubImm32:
6927 case Match_InvalidSVEAddSubImm64:
6928 case Match_InvalidSVECpyImm8:
6929 case Match_InvalidSVECpyImm16:
6930 case Match_InvalidSVECpyImm32:
6931 case Match_InvalidSVECpyImm64:
6932 case Match_InvalidIndexRange0_0:
6933 case Match_InvalidIndexRange1_1:
6934 case Match_InvalidIndexRange0_15:
6935 case Match_InvalidIndexRange0_7:
6936 case Match_InvalidIndexRange0_3:
6937 case Match_InvalidIndexRange0_1:
6938 case Match_InvalidSVEIndexRange0_63:
6939 case Match_InvalidSVEIndexRange0_31:
6940 case Match_InvalidSVEIndexRange0_15:
6941 case Match_InvalidSVEIndexRange0_7:
6942 case Match_InvalidSVEIndexRange0_3:
6943 case Match_InvalidLabel:
6944 case Match_InvalidComplexRotationEven:
6945 case Match_InvalidComplexRotationOdd:
6946 case Match_InvalidGPR64shifted8:
6947 case Match_InvalidGPR64shifted16:
6948 case Match_InvalidGPR64shifted32:
6949 case Match_InvalidGPR64shifted64:
6950 case Match_InvalidGPR64shifted128:
6951 case Match_InvalidGPR64NoXZRshifted8:
6952 case Match_InvalidGPR64NoXZRshifted16:
6953 case Match_InvalidGPR64NoXZRshifted32:
6954 case Match_InvalidGPR64NoXZRshifted64:
6955 case Match_InvalidGPR64NoXZRshifted128:
6956 case Match_InvalidZPR32UXTW8:
6957 case Match_InvalidZPR32UXTW16:
6958 case Match_InvalidZPR32UXTW32:
6959 case Match_InvalidZPR32UXTW64:
6960 case Match_InvalidZPR32SXTW8:
6961 case Match_InvalidZPR32SXTW16:
6962 case Match_InvalidZPR32SXTW32:
6963 case Match_InvalidZPR32SXTW64:
6964 case Match_InvalidZPR64UXTW8:
6965 case Match_InvalidZPR64SXTW8:
6966 case Match_InvalidZPR64UXTW16:
6967 case Match_InvalidZPR64SXTW16:
6968 case Match_InvalidZPR64UXTW32:
6969 case Match_InvalidZPR64SXTW32:
6970 case Match_InvalidZPR64UXTW64:
6971 case Match_InvalidZPR64SXTW64:
6972 case Match_InvalidZPR32LSL8:
6973 case Match_InvalidZPR32LSL16:
6974 case Match_InvalidZPR32LSL32:
6975 case Match_InvalidZPR32LSL64:
6976 case Match_InvalidZPR64LSL8:
6977 case Match_InvalidZPR64LSL16:
6978 case Match_InvalidZPR64LSL32:
6979 case Match_InvalidZPR64LSL64:
6980 case Match_InvalidZPR0:
6981 case Match_InvalidZPR8:
6982 case Match_InvalidZPR16:
6983 case Match_InvalidZPR32:
6984 case Match_InvalidZPR64:
6985 case Match_InvalidZPR128:
6986 case Match_InvalidZPR_3b8:
6987 case Match_InvalidZPR_3b16:
6988 case Match_InvalidZPR_3b32:
6989 case Match_InvalidZPR_4b8:
6990 case Match_InvalidZPR_4b16:
6991 case Match_InvalidZPR_4b32:
6992 case Match_InvalidZPR_4b64:
6993 case Match_InvalidSVEPPRorPNRAnyReg:
6994 case Match_InvalidSVEPPRorPNRBReg:
6995 case Match_InvalidSVEPredicateAnyReg:
6996 case Match_InvalidSVEPattern:
6997 case Match_InvalidSVEVecLenSpecifier:
6998 case Match_InvalidSVEPredicateBReg:
6999 case Match_InvalidSVEPredicateHReg:
7000 case Match_InvalidSVEPredicateSReg:
7001 case Match_InvalidSVEPredicateDReg:
7002 case Match_InvalidSVEPredicate3bAnyReg:
7003 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7004 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7005 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7006 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7007 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7008 case Match_InvalidSVEPNPredicateBReg:
7009 case Match_InvalidSVEPNPredicateHReg:
7010 case Match_InvalidSVEPNPredicateSReg:
7011 case Match_InvalidSVEPNPredicateDReg:
7012 case Match_InvalidSVEPredicateListMul2x8:
7013 case Match_InvalidSVEPredicateListMul2x16:
7014 case Match_InvalidSVEPredicateListMul2x32:
7015 case Match_InvalidSVEPredicateListMul2x64:
7016 case Match_InvalidSVEExactFPImmOperandHalfOne:
7017 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7018 case Match_InvalidSVEExactFPImmOperandZeroOne:
7019 case Match_InvalidMatrixTile16:
7020 case Match_InvalidMatrixTile32:
7021 case Match_InvalidMatrixTile64:
7022 case Match_InvalidMatrix:
7023 case Match_InvalidMatrix8:
7024 case Match_InvalidMatrix16:
7025 case Match_InvalidMatrix32:
7026 case Match_InvalidMatrix64:
7027 case Match_InvalidMatrixTileVectorH8:
7028 case Match_InvalidMatrixTileVectorH16:
7029 case Match_InvalidMatrixTileVectorH32:
7030 case Match_InvalidMatrixTileVectorH64:
7031 case Match_InvalidMatrixTileVectorH128:
7032 case Match_InvalidMatrixTileVectorV8:
7033 case Match_InvalidMatrixTileVectorV16:
7034 case Match_InvalidMatrixTileVectorV32:
7035 case Match_InvalidMatrixTileVectorV64:
7036 case Match_InvalidMatrixTileVectorV128:
7037 case Match_InvalidSVCR:
7038 case Match_InvalidMatrixIndexGPR32_12_15:
7039 case Match_InvalidMatrixIndexGPR32_8_11:
7040 case Match_InvalidLookupTable:
7041 case Match_InvalidZPRMul2_Lo8:
7042 case Match_InvalidZPRMul2_Hi8:
7043 case Match_InvalidZPRMul2_Lo16:
7044 case Match_InvalidZPRMul2_Hi16:
7045 case Match_InvalidZPRMul2_Lo32:
7046 case Match_InvalidZPRMul2_Hi32:
7047 case Match_InvalidZPRMul2_Lo64:
7048 case Match_InvalidZPRMul2_Hi64:
7049 case Match_InvalidZPR_K0:
7050 case Match_InvalidSVEVectorList2x8Mul2:
7051 case Match_InvalidSVEVectorList2x16Mul2:
7052 case Match_InvalidSVEVectorList2x32Mul2:
7053 case Match_InvalidSVEVectorList2x64Mul2:
7054 case Match_InvalidSVEVectorList2x128Mul2:
7055 case Match_InvalidSVEVectorList4x8Mul4:
7056 case Match_InvalidSVEVectorList4x16Mul4:
7057 case Match_InvalidSVEVectorList4x32Mul4:
7058 case Match_InvalidSVEVectorList4x64Mul4:
7059 case Match_InvalidSVEVectorList4x128Mul4:
7060 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7061 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7062 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7063 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7064 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7065 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7066 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7067 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7068 case Match_InvalidSVEVectorList3x0_3b:
7069 case Match_InvalidSVEVectorListStrided2x8:
7070 case Match_InvalidSVEVectorListStrided2x16:
7071 case Match_InvalidSVEVectorListStrided2x32:
7072 case Match_InvalidSVEVectorListStrided2x64:
7073 case Match_InvalidSVEVectorListStrided4x8:
7074 case Match_InvalidSVEVectorListStrided4x16:
7075 case Match_InvalidSVEVectorListStrided4x32:
7076 case Match_InvalidSVEVectorListStrided4x64:
7080 return Error(IDLoc,
"too few operands for instruction",
7081 SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
7084 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
7085 if (ErrorLoc == SMLoc())
7087 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7095bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7102 SMLoc Loc = DirectiveID.
getLoc();
7103 if (IDVal ==
".arch")
7104 parseDirectiveArch(Loc);
7105 else if (IDVal ==
".cpu")
7106 parseDirectiveCPU(Loc);
7107 else if (IDVal ==
".tlsdesccall")
7108 parseDirectiveTLSDescCall(Loc,
false);
7109 else if (IDVal ==
".tlsauthdesccall")
7110 parseDirectiveTLSDescCall(Loc,
true);
7111 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7112 parseDirectiveLtorg(Loc);
7113 else if (IDVal ==
".unreq")
7114 parseDirectiveUnreq(Loc);
7115 else if (IDVal ==
".inst")
7116 parseDirectiveInst(Loc);
7117 else if (IDVal ==
".cfi_negate_ra_state")
7118 parseDirectiveCFINegateRAState();
7119 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7120 parseDirectiveCFINegateRAStateWithPC();
7121 else if (IDVal ==
".cfi_set_ra_state")
7122 parseDirectiveCFILLVMSetRAState();
7123 else if (IDVal ==
".cfi_b_key_frame")
7124 parseDirectiveCFIBKeyFrame();
7125 else if (IDVal ==
".cfi_mte_tagged_frame")
7126 parseDirectiveCFIMTETaggedFrame();
7127 else if (IDVal ==
".arch_extension")
7128 parseDirectiveArchExtension(Loc);
7129 else if (IDVal ==
".variant_pcs")
7130 parseDirectiveVariantPCS(Loc);
7133 parseDirectiveLOH(IDVal, Loc);
7136 }
else if (IsCOFF) {
7137 if (IDVal ==
".seh_stackalloc")
7138 parseDirectiveSEHAllocStack(Loc);
7139 else if (IDVal ==
".seh_endprologue")
7140 parseDirectiveSEHPrologEnd(Loc);
7141 else if (IDVal ==
".seh_save_r19r20_x")
7142 parseDirectiveSEHSaveR19R20X(Loc);
7143 else if (IDVal ==
".seh_save_fplr")
7144 parseDirectiveSEHSaveFPLR(Loc);
7145 else if (IDVal ==
".seh_save_fplr_x")
7146 parseDirectiveSEHSaveFPLRX(Loc);
7147 else if (IDVal ==
".seh_save_reg")
7148 parseDirectiveSEHSaveReg(Loc);
7149 else if (IDVal ==
".seh_save_reg_x")
7150 parseDirectiveSEHSaveRegX(Loc);
7151 else if (IDVal ==
".seh_save_regp")
7152 parseDirectiveSEHSaveRegP(Loc);
7153 else if (IDVal ==
".seh_save_regp_x")
7154 parseDirectiveSEHSaveRegPX(Loc);
7155 else if (IDVal ==
".seh_save_lrpair")
7156 parseDirectiveSEHSaveLRPair(Loc);
7157 else if (IDVal ==
".seh_save_freg")
7158 parseDirectiveSEHSaveFReg(Loc);
7159 else if (IDVal ==
".seh_save_freg_x")
7160 parseDirectiveSEHSaveFRegX(Loc);
7161 else if (IDVal ==
".seh_save_fregp")
7162 parseDirectiveSEHSaveFRegP(Loc);
7163 else if (IDVal ==
".seh_save_fregp_x")
7164 parseDirectiveSEHSaveFRegPX(Loc);
7165 else if (IDVal ==
".seh_set_fp")
7166 parseDirectiveSEHSetFP(Loc);
7167 else if (IDVal ==
".seh_add_fp")
7168 parseDirectiveSEHAddFP(Loc);
7169 else if (IDVal ==
".seh_nop")
7170 parseDirectiveSEHNop(Loc);
7171 else if (IDVal ==
".seh_save_next")
7172 parseDirectiveSEHSaveNext(Loc);
7173 else if (IDVal ==
".seh_startepilogue")
7174 parseDirectiveSEHEpilogStart(Loc);
7175 else if (IDVal ==
".seh_endepilogue")
7176 parseDirectiveSEHEpilogEnd(Loc);
7177 else if (IDVal ==
".seh_trap_frame")
7178 parseDirectiveSEHTrapFrame(Loc);
7179 else if (IDVal ==
".seh_pushframe")
7180 parseDirectiveSEHMachineFrame(Loc);
7181 else if (IDVal ==
".seh_context")
7182 parseDirectiveSEHContext(Loc);
7183 else if (IDVal ==
".seh_ec_context")
7184 parseDirectiveSEHECContext(Loc);
7185 else if (IDVal ==
".seh_clear_unwound_to_call")
7186 parseDirectiveSEHClearUnwoundToCall(Loc);
7187 else if (IDVal ==
".seh_pac_sign_lr")
7188 parseDirectiveSEHPACSignLR(Loc);
7189 else if (IDVal ==
".seh_save_any_reg")
7190 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7191 else if (IDVal ==
".seh_save_any_reg_p")
7192 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7193 else if (IDVal ==
".seh_save_any_reg_x")
7194 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7195 else if (IDVal ==
".seh_save_any_reg_px")
7196 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7197 else if (IDVal ==
".seh_allocz")
7198 parseDirectiveSEHAllocZ(Loc);
7199 else if (IDVal ==
".seh_save_zreg")
7200 parseDirectiveSEHSaveZReg(Loc);
7201 else if (IDVal ==
".seh_save_preg")
7202 parseDirectiveSEHSavePReg(Loc);
7206 if (IDVal ==
".aeabi_subsection")
7207 parseDirectiveAeabiSubSectionHeader(Loc);
7208 else if (IDVal ==
".aeabi_attribute")
7209 parseDirectiveAeabiAArch64Attr(Loc);
7222 if (!NoCrypto && Crypto) {
7225 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7226 ArchInfo == AArch64::ARMV8_3A) {
7230 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7231 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7232 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7233 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7234 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7235 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7241 }
else if (NoCrypto) {
7244 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7245 ArchInfo == AArch64::ARMV8_3A) {
7246 RequestedExtensions.
push_back(
"nosha2");
7249 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7250 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7251 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7252 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7253 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7254 ArchInfo == AArch64::ARMV9_4A) {
7256 RequestedExtensions.
push_back(
"nosha3");
7257 RequestedExtensions.
push_back(
"nosha2");
7269bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7270 SMLoc CurLoc = getLoc();
7272 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7273 StringRef Arch, ExtensionString;
7274 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7278 return Error(CurLoc,
"unknown arch name");
7284 std::vector<StringRef> AArch64Features;
7285 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7288 MCSubtargetInfo &STI = copySTI();
7289 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7291 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7294 if (!ExtensionString.
empty())
7295 ExtensionString.
split(RequestedExtensions,
'+');
7300 for (
auto Name : RequestedExtensions) {
7304 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7311 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7319 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7320 setAvailableFeatures(Features);
7322 getTargetStreamer().emitDirectiveArch(Name);
7328bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7329 SMLoc ExtLoc = getLoc();
7331 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7336 bool EnableFeature =
true;
7337 StringRef
Name = FullName;
7338 if (
Name.starts_with_insensitive(
"no")) {
7339 EnableFeature =
false;
7348 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7350 MCSubtargetInfo &STI = copySTI();
7355 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7356 setAvailableFeatures(Features);
7358 getTargetStreamer().emitDirectiveArchExtension(FullName);
7364bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7365 SMLoc CurLoc = getLoc();
7367 StringRef CPU, ExtensionString;
7368 std::tie(CPU, ExtensionString) =
7369 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7375 if (!ExtensionString.
empty())
7376 ExtensionString.
split(RequestedExtensions,
'+');
7380 Error(CurLoc,
"unknown CPU name");
7385 MCSubtargetInfo &STI = copySTI();
7389 for (
auto Name : RequestedExtensions) {
7393 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7400 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7408 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7409 setAvailableFeatures(Features);
7415bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7417 return Error(Loc,
"expected expression following '.inst' directive");
7419 auto parseOp = [&]() ->
bool {
7421 const MCExpr *Expr =
nullptr;
7422 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7425 if (check(!
Value, L,
"expected constant expression"))
7427 getTargetStreamer().emitInst(
Value->getValue());
7431 return parseMany(parseOp);
7437bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth) {
7439 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7450 Inst.
setOpcode(IsAuth ? AArch64::TLSAUTHDESCCALL : AArch64::TLSDESCCALL);
7453 getParser().getStreamer().emitInstruction(Inst, getSTI());
7459bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7463 return TokError(
"expected an identifier or a number in directive");
7466 int64_t
Id = getTok().getIntVal();
7468 return TokError(
"invalid numeric identifier in directive");
7471 StringRef
Name = getTok().getIdentifier();
7477 return TokError(
"invalid identifier in directive");
7485 assert(NbArgs != -1 &&
"Invalid number of arguments");
7488 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7490 if (getParser().parseIdentifier(Name))
7491 return TokError(
"expected identifier in directive");
7494 if (Idx + 1 == NbArgs)
7502 getStreamer().emitLOHDirective(Kind, Args);
7508bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7511 getTargetStreamer().emitCurrentConstantPool();
7517bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7519 SMLoc SRegLoc = getLoc();
7520 RegKind RegisterKind = RegKind::Scalar;
7522 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7526 RegisterKind = RegKind::NeonVector;
7527 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7533 return Error(SRegLoc,
"vector register without type specifier expected");
7538 RegisterKind = RegKind::SVEDataVector;
7540 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7546 return Error(SRegLoc,
7547 "sve vector register without type specifier expected");
7552 RegisterKind = RegKind::SVEPredicateVector;
7553 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7559 return Error(SRegLoc,
7560 "sve predicate register without type specifier expected");
7564 return Error(SRegLoc,
"register name or alias expected");
7570 auto pair = std::make_pair(RegisterKind, RegNum);
7571 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7572 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7579bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7581 return TokError(
"unexpected input in .unreq directive.");
7582 RegisterReqs.
erase(getTok().getIdentifier().lower());
7587bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7590 getStreamer().emitCFINegateRAState();
7594bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7597 getStreamer().emitCFINegateRAStateWithPC();
7604bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7606 if (getParser().parseAbsoluteExpression(State))
7611 SMLoc ExprLoc = getLoc();
7612 if (getParser().parseExpression(Expr))
7617 getStreamer().emitCFILLVMSetRAState(
7618 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7620 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7624 "expected an integer offset or a symbol for .cfi_set_ra_state");
7631bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7634 getStreamer().emitCFIBKeyFrame();
7640bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7643 getStreamer().emitCFIMTETaggedFrame();
7649bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7651 if (getParser().parseIdentifier(Name))
7652 return TokError(
"expected symbol name");
7655 getTargetStreamer().emitDirectiveVariantPCS(
7662bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7664 if (parseImmExpr(
Size))
7666 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7672bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7673 getTargetStreamer().emitARM64WinCFIPrologEnd();
7679bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7681 if (parseImmExpr(
Offset))
7683 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7689bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7691 if (parseImmExpr(
Offset))
7693 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7699bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7701 if (parseImmExpr(
Offset))
7703 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7709bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7712 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7713 parseComma() || parseImmExpr(
Offset))
7715 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7721bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7724 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7725 parseComma() || parseImmExpr(
Offset))
7727 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7733bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7736 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7737 parseComma() || parseImmExpr(
Offset))
7739 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7745bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7748 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7749 parseComma() || parseImmExpr(
Offset))
7751 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7757bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7761 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7762 parseComma() || parseImmExpr(
Offset))
7764 if (check(((
Reg - 19) % 2 != 0), L,
7765 "expected register with even offset from x19"))
7767 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7773bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7776 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7777 parseComma() || parseImmExpr(
Offset))
7779 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7785bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7788 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7789 parseComma() || parseImmExpr(
Offset))
7791 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7797bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7800 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7801 parseComma() || parseImmExpr(
Offset))
7803 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7809bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7812 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7813 parseComma() || parseImmExpr(
Offset))
7815 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7821bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7822 getTargetStreamer().emitARM64WinCFISetFP();
7828bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7830 if (parseImmExpr(
Size))
7832 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7838bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7839 getTargetStreamer().emitARM64WinCFINop();
7845bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7846 getTargetStreamer().emitARM64WinCFISaveNext();
7852bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7853 getTargetStreamer().emitARM64WinCFIEpilogStart();
7859bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7860 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7866bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7867 getTargetStreamer().emitARM64WinCFITrapFrame();
7873bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7874 getTargetStreamer().emitARM64WinCFIMachineFrame();
7880bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7881 getTargetStreamer().emitARM64WinCFIContext();
7887bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7888 getTargetStreamer().emitARM64WinCFIECContext();
7894bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7895 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7901bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7902 getTargetStreamer().emitARM64WinCFIPACSignLR();
7911bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7916 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register") ||
7917 parseComma() || parseImmExpr(
Offset))
7920 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7921 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7922 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7923 return Error(L,
"invalid save_any_reg offset");
7924 unsigned EncodedReg;
7925 if (
Reg == AArch64::FP)
7927 else if (
Reg == AArch64::LR)
7930 EncodedReg =
Reg - AArch64::X0;
7932 if (
Reg == AArch64::LR)
7933 return Error(Start,
"lr cannot be paired with another register");
7935 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7937 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7940 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7942 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7944 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7945 unsigned EncodedReg =
Reg - AArch64::D0;
7946 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7947 return Error(L,
"invalid save_any_reg offset");
7949 if (
Reg == AArch64::D31)
7950 return Error(Start,
"d31 cannot be paired with another register");
7952 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7954 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7957 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7959 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7961 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7962 unsigned EncodedReg =
Reg - AArch64::Q0;
7964 return Error(L,
"invalid save_any_reg offset");
7966 if (
Reg == AArch64::Q31)
7967 return Error(Start,
"q31 cannot be paired with another register");
7969 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7971 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7974 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7976 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7979 return Error(Start,
"save_any_reg register must be x, q or d register");
7986bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7988 if (parseImmExpr(
Offset))
7990 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7996bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8001 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8004 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8005 "expected register in range z8 to z23"))
8007 if (parseComma() || parseImmExpr(
Offset))
8009 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8015bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8020 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8023 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8024 "expected register in range p4 to p15"))
8026 if (parseComma() || parseImmExpr(
Offset))
8028 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8032bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8038 MCAsmParser &Parser = getParser();
8041 StringRef SubsectionName;
8052 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8053 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8058 if (SubsectionExists) {
8059 getTargetStreamer().emitAttributesSubsection(
8062 SubsectionExists->IsOptional),
8064 SubsectionExists->ParameterType));
8070 "Could not switch to subsection '" + SubsectionName +
8071 "' using subsection name, subsection has not been defined");
8094 if (SubsectionExists) {
8095 if (IsOptional != SubsectionExists->IsOptional) {
8097 "optionality mismatch! subsection '" + SubsectionName +
8098 "' already exists with optionality defined as '" +
8100 SubsectionExists->IsOptional) +
8108 "optionality parameter not found, expected required|optional");
8115 "aeabi_feature_and_bits must be marked as optional");
8122 "aeabi_pauthabi must be marked as required");
8142 if (SubsectionExists) {
8143 if (
Type != SubsectionExists->ParameterType) {
8145 "type mismatch! subsection '" + SubsectionName +
8146 "' already exists with type defined as '" +
8148 SubsectionExists->ParameterType) +
8156 "type parameter not found, expected uleb128|ntbs");
8164 SubsectionName +
" must be marked as ULEB128");
8173 "attributes subsection header directive");
8177 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8182bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8186 MCAsmParser &Parser = getParser();
8188 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8189 getTargetStreamer().getActiveAttributesSubsection();
8190 if (
nullptr == ActiveSubsection) {
8192 "no active subsection, build attribute can not be added");
8195 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8196 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8204 ActiveSubsectionName)
8207 StringRef TagStr =
"";
8210 Tag = getTok().getIntVal();
8213 switch (ActiveSubsectionID) {
8218 "' \nExcept for public subsections, "
8219 "tags have to be an unsigned int.");
8226 TagStr +
"' for subsection '" +
8227 ActiveSubsectionName +
"'");
8235 TagStr +
"' for subsection '" +
8236 ActiveSubsectionName +
"'");
8254 unsigned ValueInt = unsigned(-1);
8255 std::string ValueStr =
"";
8260 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8263 ValueInt = getTok().getIntVal();
8268 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8276 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8287 if (0 != ValueInt && 1 != ValueInt) {
8289 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8290 "' options are 0|1");
8299 "unexpected token for AArch64 build attributes tag and value "
8300 "attribute directive");
8304 if (
unsigned(-1) != ValueInt) {
8305 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8307 if (
"" != ValueStr) {
8308 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8314bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8315 SMLoc Loc = getLoc();
8317 return TokError(
"expected '%' relocation specifier");
8318 StringRef
Identifier = getParser().getTok().getIdentifier();
8321 return TokError(
"invalid relocation specifier");
8327 const MCExpr *SubExpr;
8328 if (getParser().parseParenExpression(SubExpr,
E))
8335bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8338 return parseExprWithSpecifier(Res, EndLoc);
8340 if (getParser().parseExpression(Res))
8342 MCAsmParser &Parser = getParser();
8346 return Error(getLoc(),
"expected relocation specifier");
8349 SMLoc Loc = getLoc();
8351 if (Identifier ==
"auth")
8352 return parseAuthExpr(Res, EndLoc);
8356 if (Identifier ==
"got")
8360 return Error(Loc,
"invalid relocation specifier");
8365 return Error(Loc,
"@ specifier only allowed after a symbol");
8368 std::optional<MCBinaryExpr::Opcode> Opcode;
8376 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8387bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8388 MCAsmParser &Parser = getParser();
8390 AsmToken Tok = Parser.
getTok();
8397 return TokError(
"expected key name");
8402 return TokError(
"invalid key '" + KeyStr +
"'");
8409 return TokError(
"expected integer discriminator");
8413 return TokError(
"integer discriminator " + Twine(Discriminator) +
8414 " out of range [0, 0xFFFF]");
8417 bool UseAddressDiversity =
false;
8422 return TokError(
"expected 'addr'");
8423 UseAddressDiversity =
true;
8432 UseAddressDiversity, Ctx, Res->
getLoc());
8436bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8445 ELFSpec = AE->getSpecifier();
8446 Expr = AE->getSubExpr();
8486#define GET_REGISTER_MATCHER
8487#define GET_SUBTARGET_FEATURE_NAME
8488#define GET_MATCHER_IMPLEMENTATION
8489#define GET_MNEMONIC_SPELL_CHECKER
8490#include "AArch64GenAsmMatcher.inc"
8496 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8498 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8500 return Match_InvalidOperand;
8503 return Match_InvalidOperand;
8504 if (CE->getValue() == ExpectedVal)
8505 return Match_Success;
8506 return Match_InvalidOperand;
8511 return Match_InvalidOperand;
8517 if (
Op.isTokenEqual(
"za"))
8518 return Match_Success;
8519 return Match_InvalidOperand;
8525#define MATCH_HASH(N) \
8526 case MCK__HASH_##N: \
8527 return MatchesOpImmediate(N);
8553#define MATCH_HASH_MINUS(N) \
8554 case MCK__HASH__MINUS_##N: \
8555 return MatchesOpImmediate(-N);
8559#undef MATCH_HASH_MINUS
8568 return Error(S,
"expected register");
8570 MCRegister FirstReg;
8571 ParseStatus Res = tryParseScalarRegister(FirstReg);
8573 return Error(S,
"expected first even register of a consecutive same-size "
8574 "even/odd register pair");
8576 const MCRegisterClass &WRegClass =
8577 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8578 const MCRegisterClass &XRegClass =
8579 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8581 bool isXReg = XRegClass.
contains(FirstReg),
8582 isWReg = WRegClass.
contains(FirstReg);
8583 if (!isXReg && !isWReg)
8584 return Error(S,
"expected first even register of a consecutive same-size "
8585 "even/odd register pair");
8587 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8590 if (FirstEncoding & 0x1)
8591 return Error(S,
"expected first even register of a consecutive same-size "
8592 "even/odd register pair");
8595 return Error(getLoc(),
"expected comma");
8600 MCRegister SecondReg;
8601 Res = tryParseScalarRegister(SecondReg);
8603 return Error(
E,
"expected second odd register of a consecutive same-size "
8604 "even/odd register pair");
8607 (isXReg && !XRegClass.
contains(SecondReg)) ||
8608 (isWReg && !WRegClass.
contains(SecondReg)))
8609 return Error(
E,
"expected second odd register of a consecutive same-size "
8610 "even/odd register pair");
8615 FirstReg, AArch64::sube64,
8616 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8619 FirstReg, AArch64::sube32,
8620 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8623 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8629template <
bool ParseShiftExtend,
bool ParseSuffix>
8631 const SMLoc S = getLoc();
8637 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8642 if (ParseSuffix &&
Kind.empty())
8649 unsigned ElementWidth = KindRes->second;
8653 Operands.push_back(AArch64Operand::CreateVectorReg(
8654 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8656 ParseStatus Res = tryParseVectorIndex(
Operands);
8667 Res = tryParseOptionalShiftExtend(ExtOpnd);
8671 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8672 Operands.push_back(AArch64Operand::CreateVectorReg(
8673 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8674 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8675 Ext->hasShiftExtendAmount()));
8681 SMLoc
SS = getLoc();
8682 const AsmToken &TokE = getTok();
8687 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8692 int64_t Pattern = Pat->Encoding;
8693 assert(Pattern >= 0 && Pattern < 32);
8705 SMLoc
SS = getLoc();
8706 const AsmToken &TokE = getTok();
8708 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8714 Pattern = Pat->Encoding;
8715 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8725 SMLoc
SS = getLoc();
8728 if (!tryParseScalarRegister(XReg).isSuccess())
8734 XReg, AArch64::x8sub_0,
8735 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8738 "expected an even-numbered x-register in the range [x0,x22]");
8741 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8755 if (getParser().parseExpression(ImmF))
8765 SMLoc
E = getTok().getLoc();
8767 if (getParser().parseExpression(ImmL))
8774 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
@ End
Run the machine verifier once, at the end of the pipeline.
StringTable::Offset ArchFeature
AArch64::ExtensionBitset DefaultExts
Compile-time data representation of enum entries.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
bool haveFeatures(FeatureBitset ActiveFeatures) const