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 parseDirectiveSEHEndC(SMLoc L);
212 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
213 bool parseDirectiveSEHSaveFPLR(SMLoc L);
214 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
215 bool parseDirectiveSEHSaveReg(SMLoc L);
216 bool parseDirectiveSEHSaveRegX(SMLoc L);
217 bool parseDirectiveSEHSaveRegP(SMLoc L);
218 bool parseDirectiveSEHSaveRegPX(SMLoc L);
219 bool parseDirectiveSEHSaveLRPair(SMLoc L);
220 bool parseDirectiveSEHSaveFReg(SMLoc L);
221 bool parseDirectiveSEHSaveFRegX(SMLoc L);
222 bool parseDirectiveSEHSaveFRegP(SMLoc L);
223 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
224 bool parseDirectiveSEHSetFP(SMLoc L);
225 bool parseDirectiveSEHAddFP(SMLoc L);
226 bool parseDirectiveSEHNop(SMLoc L);
227 bool parseDirectiveSEHSaveNext(SMLoc L);
228 bool parseDirectiveSEHEpilogStart(SMLoc L);
229 bool parseDirectiveSEHEpilogEnd(SMLoc L);
230 bool parseDirectiveSEHTrapFrame(SMLoc L);
231 bool parseDirectiveSEHMachineFrame(SMLoc L);
232 bool parseDirectiveSEHContext(SMLoc L);
233 bool parseDirectiveSEHECContext(SMLoc L);
234 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
235 bool parseDirectiveSEHPACSignLR(SMLoc L);
236 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
237 bool parseDirectiveSEHAllocZ(SMLoc L);
238 bool parseDirectiveSEHSaveZReg(SMLoc L);
239 bool parseDirectiveSEHSavePReg(SMLoc L);
240 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
241 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
243 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
244 SmallVectorImpl<SMLoc> &Loc);
245 unsigned getNumRegsForRegKind(RegKind K);
246 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
249 bool MatchingInlineAsm)
override;
253#define GET_ASSEMBLER_HEADER
254#include "AArch64GenAsmMatcher.inc"
268 template <
bool IsSVEPrefetch = false>
274 template <
bool AddFPZeroAsLiteral>
282 template <
bool ParseShiftExtend,
283 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
286 template <
bool ParseShiftExtend,
bool ParseSuffix>
288 template <RegKind RK>
292 template <RegKind VectorKind>
294 bool ExpectMatch =
false);
302 enum AArch64MatchResultTy {
303 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
304#define GET_OPERAND_DIAGNOSTIC_TYPES
305#include "AArch64GenAsmMatcher.inc"
308 bool IsWindowsArm64EC;
310 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
311 const MCInstrInfo &MII)
312 : MCTargetAsmParser(STI, MII) {
316 MCStreamer &S = getParser().getStreamer();
318 new AArch64TargetStreamer(S);
330 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
333 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
334 const MCParsedAsmOperand &Op2)
const override;
335 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
337 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
338 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
339 SMLoc &EndLoc)
override;
340 bool ParseDirective(AsmToken DirectiveID)
override;
341 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
342 unsigned Kind)
override;
374 SMLoc StartLoc, EndLoc;
383 struct ShiftExtendOp {
386 bool HasExplicitAmount;
396 RegConstraintEqualityTy EqualityTy;
412 ShiftExtendOp ShiftExtend;
417 unsigned ElementWidth;
421 struct MatrixTileListOp {
422 unsigned RegMask = 0;
425 struct VectorListOp {
429 unsigned NumElements;
430 unsigned ElementWidth;
431 RegKind RegisterKind;
434 struct VectorIndexOp {
442 struct ShiftedImmOp {
444 unsigned ShiftAmount;
473 uint32_t PStateField;
486 struct TIndexHintOp {
495 unsigned PStateField;
501 struct MatrixRegOp MatrixReg;
502 struct MatrixTileListOp MatrixTileList;
503 struct VectorListOp VectorList;
504 struct VectorIndexOp VectorIndex;
506 struct ShiftedImmOp ShiftedImm;
507 struct ImmRangeOp ImmRange;
509 struct FPImmOp FPImm;
511 struct SysRegOp SysReg;
512 struct SysCRImmOp SysCRImm;
514 struct TIndexHintOp TIndexHint;
515 struct ShiftExtendOp ShiftExtend;
524 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
526 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
528 StartLoc =
o.StartLoc;
538 ShiftedImm =
o.ShiftedImm;
541 ImmRange =
o.ImmRange;
555 case k_MatrixRegister:
556 MatrixReg =
o.MatrixReg;
558 case k_MatrixTileList:
559 MatrixTileList =
o.MatrixTileList;
562 VectorList =
o.VectorList;
565 VectorIndex =
o.VectorIndex;
571 SysCRImm =
o.SysCRImm;
577 TIndexHint =
o.TIndexHint;
580 ShiftExtend =
o.ShiftExtend;
589 SMLoc getStartLoc()
const override {
return StartLoc; }
591 SMLoc getEndLoc()
const override {
return EndLoc; }
594 assert(Kind == k_Token &&
"Invalid access!");
595 return StringRef(Tok.Data, Tok.Length);
598 bool isTokenSuffix()
const {
599 assert(Kind == k_Token &&
"Invalid access!");
603 const MCExpr *
getImm()
const {
604 assert(Kind == k_Immediate &&
"Invalid access!");
608 const MCExpr *getShiftedImmVal()
const {
609 assert(Kind == k_ShiftedImm &&
"Invalid access!");
610 return ShiftedImm.Val;
613 unsigned getShiftedImmShift()
const {
614 assert(Kind == k_ShiftedImm &&
"Invalid access!");
615 return ShiftedImm.ShiftAmount;
618 unsigned getFirstImmVal()
const {
619 assert(Kind == k_ImmRange &&
"Invalid access!");
620 return ImmRange.First;
623 unsigned getLastImmVal()
const {
624 assert(Kind == k_ImmRange &&
"Invalid access!");
625 return ImmRange.Last;
629 assert(Kind == k_CondCode &&
"Invalid access!");
634 assert (Kind == k_FPImm &&
"Invalid access!");
635 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
638 bool getFPImmIsExact()
const {
639 assert (Kind == k_FPImm &&
"Invalid access!");
640 return FPImm.IsExact;
643 unsigned getBarrier()
const {
644 assert(Kind == k_Barrier &&
"Invalid access!");
648 StringRef getBarrierName()
const {
649 assert(Kind == k_Barrier &&
"Invalid access!");
653 bool getBarriernXSModifier()
const {
654 assert(Kind == k_Barrier &&
"Invalid access!");
658 MCRegister
getReg()
const override {
659 assert(Kind == k_Register &&
"Invalid access!");
663 MCRegister getMatrixReg()
const {
664 assert(Kind == k_MatrixRegister &&
"Invalid access!");
665 return MatrixReg.Reg;
668 unsigned getMatrixElementWidth()
const {
669 assert(Kind == k_MatrixRegister &&
"Invalid access!");
670 return MatrixReg.ElementWidth;
673 MatrixKind getMatrixKind()
const {
674 assert(Kind == k_MatrixRegister &&
"Invalid access!");
675 return MatrixReg.Kind;
678 unsigned getMatrixTileListRegMask()
const {
679 assert(isMatrixTileList() &&
"Invalid access!");
680 return MatrixTileList.RegMask;
683 RegConstraintEqualityTy getRegEqualityTy()
const {
684 assert(Kind == k_Register &&
"Invalid access!");
685 return Reg.EqualityTy;
688 MCRegister getVectorListStart()
const {
689 assert(Kind == k_VectorList &&
"Invalid access!");
690 return VectorList.Reg;
693 unsigned getVectorListCount()
const {
694 assert(Kind == k_VectorList &&
"Invalid access!");
695 return VectorList.Count;
698 unsigned getVectorListStride()
const {
699 assert(Kind == k_VectorList &&
"Invalid access!");
700 return VectorList.Stride;
703 int getVectorIndex()
const {
704 assert(Kind == k_VectorIndex &&
"Invalid access!");
705 return VectorIndex.Val;
708 StringRef getSysReg()
const {
709 assert(Kind == k_SysReg &&
"Invalid access!");
710 return StringRef(SysReg.Data, SysReg.Length);
713 unsigned getSysCR()
const {
714 assert(Kind == k_SysCR &&
"Invalid access!");
718 unsigned getPrefetch()
const {
719 assert(Kind == k_Prefetch &&
"Invalid access!");
723 unsigned getTIndexHint()
const {
724 assert(Kind == k_TIndexHint &&
"Invalid access!");
725 return TIndexHint.Val;
728 StringRef getTIndexHintName()
const {
729 assert(Kind == k_TIndexHint &&
"Invalid access!");
730 return StringRef(TIndexHint.Data, TIndexHint.Length);
733 StringRef getSVCR()
const {
734 assert(Kind == k_SVCR &&
"Invalid access!");
735 return StringRef(SVCR.Data, SVCR.Length);
738 StringRef getPrefetchName()
const {
739 assert(Kind == k_Prefetch &&
"Invalid access!");
744 if (Kind == k_ShiftExtend)
745 return ShiftExtend.Type;
746 if (Kind == k_Register)
747 return Reg.ShiftExtend.Type;
751 unsigned getShiftExtendAmount()
const {
752 if (Kind == k_ShiftExtend)
753 return ShiftExtend.Amount;
754 if (Kind == k_Register)
755 return Reg.ShiftExtend.Amount;
759 bool hasShiftExtendAmount()
const {
760 if (Kind == k_ShiftExtend)
761 return ShiftExtend.HasExplicitAmount;
762 if (Kind == k_Register)
763 return Reg.ShiftExtend.HasExplicitAmount;
767 bool isImm()
const override {
return Kind == k_Immediate; }
768 bool isMem()
const override {
return false; }
770 bool isUImm6()
const {
777 return (Val >= 0 && Val < 64);
780 template <
int W
idth> DiagnosticPredicate isSImm()
const {
781 return isSImmScaled<Width, 1>();
784 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
785 return isImmScaled<Bits, Scale>(
true);
788 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
789 DiagnosticPredicate isUImmScaled()
const {
790 if (IsRange && isImmRange() &&
791 (getLastImmVal() != getFirstImmVal() +
Offset))
794 return isImmScaled<Bits, Scale, IsRange>(
false);
797 template <
int Bits,
int Scale,
bool IsRange = false>
798 DiagnosticPredicate isImmScaled(
bool Signed)
const {
799 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
800 (isImmRange() && !IsRange))
805 Val = getFirstImmVal();
813 int64_t MinVal, MaxVal;
815 int64_t Shift =
Bits - 1;
816 MinVal = (int64_t(1) << Shift) * -Scale;
817 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
820 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
823 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
829 DiagnosticPredicate isSVEPattern()
const {
836 if (Val >= 0 && Val < 32)
841 DiagnosticPredicate isSVEVecLenSpecifier()
const {
848 if (Val >= 0 && Val <= 1)
853 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
857 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
886 template <
int Scale> DiagnosticPredicate isUImm12Offset()
const {
892 return DiagnosticPredicate(isSymbolicUImm12Offset(
getImm()));
895 if ((Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000)
900 template <
int N,
int M> DiagnosticPredicate isImmInRange()
const {
907 if (Val >=
N && Val <= M)
912 bool isHinteUImm16()
const {
919 return Val >= 0 && Val <= 65535 &&
920 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
925 template <
typename T>
926 bool isLogicalImm()
const {
943 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
945 bool isImmRange()
const {
return Kind == k_ImmRange; }
950 template <
unsigned W
idth>
951 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
952 if (isShiftedImm() && Width == getShiftedImmShift())
954 return std::make_pair(
CE->getValue(), Width);
958 int64_t Val =
CE->getValue();
960 return std::make_pair(Val >> Width, Width);
962 return std::make_pair(Val, 0u);
968 bool isAddSubImm()
const {
969 if (!isShiftedImm() && !isImm())
975 if (isShiftedImm()) {
976 unsigned Shift = ShiftedImm.ShiftAmount;
977 Expr = ShiftedImm.Val;
978 if (Shift != 0 && Shift != 12)
987 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1003 if (
auto ShiftedVal = getShiftedVal<12>())
1004 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1011 bool isAddSubImmNeg()
const {
1012 if (!isShiftedImm() && !isImm())
1016 if (
auto ShiftedVal = getShiftedVal<12>())
1017 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1027 template <
typename T>
1028 DiagnosticPredicate isSVECpyImm()
const {
1032 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1033 std::is_same<int8_t, T>::value;
1034 if (
auto ShiftedImm = getShiftedVal<8>())
1035 if (!(IsByte && ShiftedImm->second) &&
1037 << ShiftedImm->second))
1046 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1050 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1051 std::is_same<int8_t, T>::value;
1052 if (
auto ShiftedImm = getShiftedVal<8>())
1053 if (!(IsByte && ShiftedImm->second) &&
1055 << ShiftedImm->second))
1061 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1062 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1067 bool isCondCode()
const {
return Kind == k_CondCode; }
1069 bool isSIMDImmType10()
const {
1079 bool isBranchTarget()
const {
1088 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1089 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1099 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1109 bool isMovWSymbolG3()
const {
1113 bool isMovWSymbolG2()
const {
1120 bool isMovWSymbolG1()
const {
1128 bool isMovWSymbolG0()
const {
1136 template<
int RegW
idth,
int Shift>
1137 bool isMOVZMovAlias()
const {
1138 if (!isImm())
return false;
1151 template<
int RegW
idth,
int Shift>
1152 bool isMOVNMovAlias()
const {
1153 if (!isImm())
return false;
1156 if (!CE)
return false;
1162 bool isFPImm()
const {
1163 return Kind == k_FPImm &&
1167 bool isBarrier()
const {
1168 return Kind == k_Barrier && !getBarriernXSModifier();
1170 bool isBarriernXS()
const {
1171 return Kind == k_Barrier && getBarriernXSModifier();
1173 bool isSysReg()
const {
return Kind == k_SysReg; }
1175 bool isMRSSystemRegister()
const {
1176 if (!isSysReg())
return false;
1178 return SysReg.MRSReg != -1U;
1181 bool isMSRSystemRegister()
const {
1182 if (!isSysReg())
return false;
1183 return SysReg.MSRReg != -1U;
1186 bool isSystemPStateFieldWithImm0_1()
const {
1187 if (!isSysReg())
return false;
1188 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1191 bool isSystemPStateFieldWithImm0_15()
const {
1194 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1197 bool isSVCR()
const {
1200 return SVCR.PStateField != -1U;
1203 bool isReg()
const override {
1204 return Kind == k_Register;
1207 bool isVectorList()
const {
return Kind == k_VectorList; }
1209 bool isScalarReg()
const {
1210 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1213 bool isNeonVectorReg()
const {
1214 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1217 bool isNeonVectorRegLo()
const {
1218 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1219 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1220 .contains(
Reg.Reg) ||
1221 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1222 .contains(
Reg.Reg));
1225 bool isNeonVectorReg0to7()
const {
1226 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1227 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1228 .contains(
Reg.Reg));
1231 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1232 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1234 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1237 case AArch64::PPRRegClassID:
1238 case AArch64::PPR_3bRegClassID:
1239 case AArch64::PPR_p8to15RegClassID:
1240 case AArch64::PNRRegClassID:
1241 case AArch64::PNR_p8to15RegClassID:
1242 case AArch64::PPRorPNRRegClassID:
1243 RK = RegKind::SVEPredicateAsCounter;
1249 return (Kind == k_Register &&
Reg.Kind == RK) &&
1250 getAArch64MCRegisterClass(Class).contains(
getReg());
1253 template <
unsigned Class>
bool isSVEVectorReg()
const {
1256 case AArch64::ZPRRegClassID:
1257 case AArch64::ZPR_3bRegClassID:
1258 case AArch64::ZPR_4bRegClassID:
1259 case AArch64::ZPRMul2_LoRegClassID:
1260 case AArch64::ZPRMul2_HiRegClassID:
1261 case AArch64::ZPR_KRegClassID:
1262 RK = RegKind::SVEDataVector;
1264 case AArch64::PPRRegClassID:
1265 case AArch64::PPR_3bRegClassID:
1266 case AArch64::PPR_p8to15RegClassID:
1267 case AArch64::PNRRegClassID:
1268 case AArch64::PNR_p8to15RegClassID:
1269 case AArch64::PPRorPNRRegClassID:
1270 RK = RegKind::SVEPredicateVector;
1276 return (Kind == k_Register &&
Reg.Kind == RK) &&
1277 getAArch64MCRegisterClass(Class).contains(
getReg());
1280 template <
unsigned Class>
bool isFPRasZPR()
const {
1281 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1282 getAArch64MCRegisterClass(Class).contains(
getReg());
1285 template <
int ElementW
idth,
unsigned Class>
1286 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1287 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1290 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1296 template <
int ElementW
idth,
unsigned Class>
1297 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1298 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1299 Reg.Kind != RegKind::SVEPredicateVector))
1302 if ((isSVEPredicateAsCounterReg<Class>() ||
1303 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1304 Reg.ElementWidth == ElementWidth)
1310 template <
int ElementW
idth,
unsigned Class>
1311 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1312 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1315 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1321 template <
int ElementW
idth,
unsigned Class>
1322 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1323 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1326 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1332 template <
int ElementWidth,
unsigned Class,
1334 bool ShiftWidthAlwaysSame>
1335 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1336 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1337 if (!VectorMatch.isMatch())
1343 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1346 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1349 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1355 bool isGPR32as64()
const {
1356 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1357 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1361 bool isGPR64as32()
const {
1362 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1363 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1367 bool isGPR64x8()
const {
1368 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1369 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1373 bool isWSeqPair()
const {
1374 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1375 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1379 bool isXSeqPair()
const {
1380 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1381 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1385 bool isSyspXzrPair()
const {
1389 template<
int64_t Angle,
int64_t Remainder>
1390 DiagnosticPredicate isComplexRotation()
const {
1399 if (
Value % Angle == Remainder &&
Value <= 270)
1404 template <
unsigned RegClassID>
bool isGPR64()
const {
1405 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1406 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1409 template <
unsigned RegClassID,
int ExtW
idth>
1410 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1411 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1415 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1422 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1423 bool isImplicitlyTypedVectorList()
const {
1424 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1425 VectorList.NumElements == 0 &&
1427 (!IsConsecutive || (VectorList.Stride == 1));
1430 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1431 unsigned ElementWidth,
unsigned Stride = 1>
1432 bool isTypedVectorList()
const {
1433 if (Kind != k_VectorList)
1435 if (VectorList.Count != NumRegs)
1437 if (VectorList.RegisterKind != VectorKind)
1439 if (VectorList.ElementWidth != ElementWidth)
1441 if (VectorList.Stride != Stride)
1443 return VectorList.NumElements == NumElements;
1446 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned NumElements,
1447 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1449 DiagnosticPredicate isTypedVectorListInRange()
const {
1451 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1454 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1455 (VectorList.Reg - FirstReg) % Multiple != 0)
1460 template <RegKind
VectorKind,
unsigned NumRegs,
unsigned Stride,
1461 unsigned ElementWidth>
1462 DiagnosticPredicate isTypedVectorListStrided()
const {
1463 bool Res = isTypedVectorList<
VectorKind, NumRegs, 0,
1464 ElementWidth, Stride>();
1467 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1468 ((VectorList.Reg >= AArch64::Z16) &&
1469 (VectorList.Reg < (AArch64::Z16 + Stride))))
1474 template <
int Min,
int Max>
1475 DiagnosticPredicate isVectorIndex()
const {
1476 if (Kind != k_VectorIndex)
1478 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1483 bool isToken()
const override {
return Kind == k_Token; }
1485 bool isTokenEqual(StringRef Str)
const {
1486 return Kind == k_Token &&
getToken() == Str;
1488 bool isSysCR()
const {
return Kind == k_SysCR; }
1489 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1490 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1491 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1492 bool isShifter()
const {
1493 if (!isShiftExtend())
1502 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1503 if (Kind != k_FPImm)
1506 if (getFPImmIsExact()) {
1508 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1510 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1513 APFloat RealVal(APFloat::IEEEdouble());
1515 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1516 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1519 if (
getFPImm().bitwiseIsEqual(RealVal))
1526 template <
unsigned ImmA,
unsigned ImmB>
1527 DiagnosticPredicate isExactFPImm()
const {
1529 if ((Res = isExactFPImm<ImmA>()))
1531 if ((Res = isExactFPImm<ImmB>()))
1536 bool isExtend()
const {
1537 if (!isShiftExtend())
1546 getShiftExtendAmount() <= 4;
1549 bool isExtend64()
const {
1559 bool isExtendLSL64()
const {
1565 getShiftExtendAmount() <= 4;
1568 bool isLSLImm3Shift()
const {
1569 if (!isShiftExtend())
1575 template<
int W
idth>
bool isMemXExtend()
const {
1580 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1581 getShiftExtendAmount() == 0);
1584 template<
int W
idth>
bool isMemWExtend()
const {
1589 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1590 getShiftExtendAmount() == 0);
1593 template <
unsigned w
idth>
1594 bool isArithmeticShifter()
const {
1604 template <
unsigned w
idth>
1605 bool isLogicalShifter()
const {
1613 getShiftExtendAmount() < width;
1616 bool isMovImm32Shifter()
const {
1624 uint64_t Val = getShiftExtendAmount();
1625 return (Val == 0 || Val == 16);
1628 bool isMovImm64Shifter()
const {
1636 uint64_t Val = getShiftExtendAmount();
1637 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1640 bool isLogicalVecShifter()
const {
1645 unsigned Shift = getShiftExtendAmount();
1647 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1650 bool isLogicalVecHalfWordShifter()
const {
1651 if (!isLogicalVecShifter())
1655 unsigned Shift = getShiftExtendAmount();
1657 (Shift == 0 || Shift == 8);
1660 bool isMoveVecShifter()
const {
1661 if (!isShiftExtend())
1665 unsigned Shift = getShiftExtendAmount();
1667 (Shift == 8 || Shift == 16);
1676 bool isSImm9OffsetFB()
const {
1677 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1680 bool isAdrpLabel()
const {
1687 int64_t Val =
CE->getValue();
1688 int64_t Min = - (4096 * (1LL << (21 - 1)));
1689 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1690 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1696 bool isAdrLabel()
const {
1703 int64_t Val =
CE->getValue();
1704 int64_t Min = - (1LL << (21 - 1));
1705 int64_t
Max = ((1LL << (21 - 1)) - 1);
1706 return Val >= Min && Val <=
Max;
1712 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1713 DiagnosticPredicate isMatrixRegOperand()
const {
1716 if (getMatrixKind() != Kind ||
1717 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1718 EltSize != getMatrixElementWidth())
1723 bool isPAuthPCRelLabel16Operand()
const {
1735 return (Val <= 0) && (Val > -(1 << 18));
1738 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1748 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1749 assert(
N == 1 &&
"Invalid number of operands!");
1753 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1754 assert(
N == 1 &&
"Invalid number of operands!");
1758 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1759 assert(
N == 1 &&
"Invalid number of operands!");
1761 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1763 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1770 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1771 assert(
N == 1 &&
"Invalid number of operands!");
1773 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1775 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1782 template <
int W
idth>
1783 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1786 case 8:
Base = AArch64::B0;
break;
1787 case 16:
Base = AArch64::H0;
break;
1788 case 32:
Base = AArch64::S0;
break;
1789 case 64:
Base = AArch64::D0;
break;
1790 case 128:
Base = AArch64::Q0;
break;
1797 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1798 assert(
N == 1 &&
"Invalid number of operands!");
1801 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1802 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1806 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1807 assert(
N == 1 &&
"Invalid number of operands!");
1812 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1813 assert(
N == 1 &&
"Invalid number of operands!");
1814 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1819 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1820 assert(
N == 1 &&
"Invalid number of operands!");
1821 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1826 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1827 assert(
N == 1 &&
"Invalid number of operands!");
1831 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1832 assert(
N == 1 &&
"Invalid number of operands!");
1836 enum VecListIndexType {
1837 VecListIdx_DReg = 0,
1838 VecListIdx_QReg = 1,
1839 VecListIdx_ZReg = 2,
1840 VecListIdx_PReg = 3,
1843 template <VecListIndexType RegTy,
unsigned NumRegs,
1844 bool IsConsecutive =
false>
1845 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1846 assert(
N == 1 &&
"Invalid number of operands!");
1847 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1848 "Expected consecutive registers");
1849 static const unsigned FirstRegs[][5] = {
1851 AArch64::D0, AArch64::D0_D1,
1852 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1854 AArch64::Q0, AArch64::Q0_Q1,
1855 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1857 AArch64::Z0, AArch64::Z0_Z1,
1858 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1860 AArch64::P0, AArch64::P0_P1 }
1863 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1864 " NumRegs must be <= 4 for ZRegs");
1866 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1867 " NumRegs must be <= 2 for PRegs");
1869 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1871 FirstRegs[(
unsigned)RegTy][0]));
1874 template <
unsigned NumRegs>
1875 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1876 assert(
N == 1 &&
"Invalid number of operands!");
1877 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1881 if (getVectorListStart() < AArch64::Z16) {
1882 assert((getVectorListStart() < AArch64::Z8) &&
1883 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1885 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1887 assert((getVectorListStart() < AArch64::Z24) &&
1888 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1890 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1894 if (getVectorListStart() < AArch64::Z16) {
1895 assert((getVectorListStart() < AArch64::Z4) &&
1896 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1898 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1900 assert((getVectorListStart() < AArch64::Z20) &&
1901 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1903 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1911 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1912 assert(
N == 1 &&
"Invalid number of operands!");
1913 unsigned RegMask = getMatrixTileListRegMask();
1914 assert(RegMask <= 0xFF &&
"Invalid mask!");
1918 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1919 assert(
N == 1 &&
"Invalid number of operands!");
1923 template <
unsigned ImmIs0,
unsigned ImmIs1>
1924 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1925 assert(
N == 1 &&
"Invalid number of operands!");
1926 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1930 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1931 assert(
N == 1 &&
"Invalid number of operands!");
1938 template <
int Adj>
void addAdjImmOperands(MCInst &Inst,
unsigned N)
const {
1939 assert(
N == 1 &&
"Invalid number of operands!");
1944 template <
int Shift>
1945 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1946 assert(
N == 2 &&
"Invalid number of operands!");
1947 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1950 }
else if (isShiftedImm()) {
1951 addExpr(Inst, getShiftedImmVal());
1959 template <
int Shift>
1960 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1961 assert(
N == 2 &&
"Invalid number of operands!");
1962 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1969 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1970 assert(
N == 1 &&
"Invalid number of operands!");
1974 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1975 assert(
N == 1 &&
"Invalid number of operands!");
1983 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1984 addImmOperands(Inst,
N);
1988 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1989 assert(
N == 1 &&
"Invalid number of operands!");
1999 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2000 assert(
N == 1 &&
"Invalid number of operands!");
2005 template <
int Scale>
2006 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2007 assert(
N == 1 &&
"Invalid number of operands!");
2012 template <
int Scale>
2013 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2014 assert(
N == 1 &&
"Invalid number of operands!");
2018 template <
typename T>
2019 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2020 assert(
N == 1 &&
"Invalid number of operands!");
2022 std::make_unsigned_t<T> Val = MCE->
getValue();
2027 template <
typename T>
2028 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2029 assert(
N == 1 &&
"Invalid number of operands!");
2031 std::make_unsigned_t<T> Val = ~MCE->getValue();
2036 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2037 assert(
N == 1 &&
"Invalid number of operands!");
2043 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2047 assert(
N == 1 &&
"Invalid number of operands!");
2053 assert(MCE &&
"Invalid constant immediate operand!");
2057 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2061 assert(
N == 1 &&
"Invalid number of operands!");
2070 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2074 assert(
N == 1 &&
"Invalid number of operands!");
2080 assert(MCE &&
"Invalid constant immediate operand!");
2084 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2088 assert(
N == 1 &&
"Invalid number of operands!");
2094 assert(MCE &&
"Invalid constant immediate operand!");
2098 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2102 assert(
N == 1 &&
"Invalid number of operands!");
2108 assert(MCE &&
"Invalid constant immediate operand!");
2112 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2113 assert(
N == 1 &&
"Invalid number of operands!");
2118 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2119 assert(
N == 1 &&
"Invalid number of operands!");
2123 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2124 assert(
N == 1 &&
"Invalid number of operands!");
2128 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2129 assert(
N == 1 &&
"Invalid number of operands!");
2134 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2135 assert(
N == 1 &&
"Invalid number of operands!");
2140 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2141 assert(
N == 1 &&
"Invalid number of operands!");
2146 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2147 assert(
N == 1 &&
"Invalid number of operands!");
2152 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2153 assert(
N == 1 &&
"Invalid number of operands!");
2158 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2159 assert(
N == 1 &&
"Invalid number of operands!");
2163 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2164 assert(
N == 1 &&
"Invalid number of operands!");
2168 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2169 assert(
N == 1 &&
"Invalid number of operands!");
2173 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2174 assert(
N == 1 &&
"Invalid number of operands!");
2180 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2181 assert(
N == 1 &&
"Invalid number of operands!");
2182 unsigned Imm = getShiftExtendAmount();
2186 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2187 assert(
N == 1 &&
"Invalid number of operands!");
2192 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2195 if (
Reg != AArch64::XZR)
2201 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2202 assert(
N == 1 &&
"Invalid number of operands!");
2209 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2210 assert(
N == 1 &&
"Invalid number of operands!");
2217 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2218 assert(
N == 2 &&
"Invalid number of operands!");
2229 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2230 assert(
N == 2 &&
"Invalid number of operands!");
2238 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2239 assert(
N == 1 &&
"Invalid number of operands!");
2251 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2252 assert(
N == 1 &&
"Invalid number of operands!");
2259 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2260 assert(
N == 1 &&
"Invalid number of operands!");
2265 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2266 assert(
N == 1 &&
"Invalid number of operands!");
2271 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2273 static std::unique_ptr<AArch64Operand>
2274 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2275 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2276 Op->Tok.Data = Str.data();
2277 Op->Tok.Length = Str.size();
2278 Op->Tok.IsSuffix = IsSuffix;
2284 static std::unique_ptr<AArch64Operand>
2285 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2286 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2288 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2289 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2291 Op->Reg.Kind = Kind;
2292 Op->Reg.ElementWidth = 0;
2293 Op->Reg.EqualityTy = EqTy;
2294 Op->Reg.ShiftExtend.Type = ExtTy;
2295 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2296 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2302 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2303 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2305 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2306 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2307 Kind == RegKind::SVEPredicateVector ||
2308 Kind == RegKind::SVEPredicateAsCounter) &&
2309 "Invalid vector kind");
2310 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2312 Op->Reg.ElementWidth = ElementWidth;
2316 static std::unique_ptr<AArch64Operand>
2317 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2318 unsigned NumElements,
unsigned ElementWidth,
2319 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2320 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2321 Op->VectorList.Reg =
Reg;
2323 Op->VectorList.Stride = Stride;
2324 Op->VectorList.NumElements = NumElements;
2325 Op->VectorList.ElementWidth = ElementWidth;
2326 Op->VectorList.RegisterKind = RegisterKind;
2332 static std::unique_ptr<AArch64Operand>
2333 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2334 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2335 Op->VectorIndex.Val =
Idx;
2341 static std::unique_ptr<AArch64Operand>
2342 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2343 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2344 Op->MatrixTileList.RegMask = RegMask;
2350 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2351 const unsigned ElementWidth) {
2352 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2354 {{0, AArch64::ZAB0},
2355 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2356 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2357 {{8, AArch64::ZAB0},
2358 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2359 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2360 {{16, AArch64::ZAH0},
2361 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2362 {{16, AArch64::ZAH1},
2363 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2364 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2365 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2366 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2367 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2370 if (ElementWidth == 64)
2373 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2374 assert(!Regs.empty() &&
"Invalid tile or element width!");
2379 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2380 SMLoc
E, MCContext &Ctx) {
2381 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2388 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2389 unsigned ShiftAmount,
2392 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2393 Op->ShiftedImm .Val = Val;
2394 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2400 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2401 unsigned Last, SMLoc S,
2404 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2406 Op->ImmRange.Last =
Last;
2411 static std::unique_ptr<AArch64Operand>
2413 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2414 Op->CondCode.Code =
Code;
2420 static std::unique_ptr<AArch64Operand>
2421 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2422 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2424 Op->FPImm.IsExact = IsExact;
2430 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2434 bool HasnXSModifier) {
2435 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2436 Op->Barrier.Val = Val;
2437 Op->Barrier.Data = Str.data();
2438 Op->Barrier.Length = Str.size();
2439 Op->Barrier.HasnXSModifier = HasnXSModifier;
2445 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2448 uint32_t PStateField,
2450 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2451 Op->SysReg.Data = Str.data();
2452 Op->SysReg.Length = Str.size();
2453 Op->SysReg.MRSReg = MRSReg;
2454 Op->SysReg.MSRReg = MSRReg;
2455 Op->SysReg.PStateField = PStateField;
2461 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2462 SMLoc
E, MCContext &Ctx) {
2463 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2464 Op->SysCRImm.Val = Val;
2470 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2474 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2475 Op->Prefetch.Val = Val;
2476 Op->Barrier.Data = Str.data();
2477 Op->Barrier.Length = Str.size();
2483 static std::unique_ptr<AArch64Operand>
2484 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2485 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2486 Op->TIndexHint.Val = Val;
2487 Op->TIndexHint.Data = Str.data();
2488 Op->TIndexHint.Length = Str.size();
2494 static std::unique_ptr<AArch64Operand>
2495 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2496 SMLoc S, SMLoc
E, MCContext &Ctx) {
2497 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2498 Op->MatrixReg.Reg =
Reg;
2499 Op->MatrixReg.ElementWidth = ElementWidth;
2500 Op->MatrixReg.Kind = Kind;
2506 static std::unique_ptr<AArch64Operand>
2507 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2508 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2509 Op->SVCR.PStateField = PStateField;
2510 Op->SVCR.Data = Str.data();
2511 Op->SVCR.Length = Str.size();
2517 static std::unique_ptr<AArch64Operand>
2519 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2520 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2521 Op->ShiftExtend.Type = ShOp;
2522 Op->ShiftExtend.Amount = Val;
2523 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2535 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2536 if (!getFPImmIsExact())
2541 StringRef
Name = getBarrierName();
2543 OS <<
"<barrier " <<
Name <<
">";
2545 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2551 case k_ShiftedImm: {
2552 unsigned Shift = getShiftedImmShift();
2553 OS <<
"<shiftedimm ";
2560 OS << getFirstImmVal();
2561 OS <<
":" << getLastImmVal() <<
">";
2567 case k_VectorList: {
2568 OS <<
"<vectorlist ";
2569 MCRegister
Reg = getVectorListStart();
2570 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2571 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2576 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2579 OS <<
"<sysreg: " << getSysReg() <<
'>';
2585 OS <<
"c" << getSysCR();
2588 StringRef
Name = getPrefetchName();
2590 OS <<
"<prfop " <<
Name <<
">";
2592 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2596 OS << getTIndexHintName();
2598 case k_MatrixRegister:
2599 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2601 case k_MatrixTileList: {
2602 OS <<
"<matrixlist ";
2603 unsigned RegMask = getMatrixTileListRegMask();
2604 unsigned MaxBits = 8;
2605 for (
unsigned I = MaxBits;
I > 0; --
I)
2606 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2615 OS <<
"<register " <<
getReg().
id() <<
">";
2616 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2621 << getShiftExtendAmount();
2622 if (!hasShiftExtendAmount())
2638 .
Case(
"v0", AArch64::Q0)
2639 .
Case(
"v1", AArch64::Q1)
2640 .
Case(
"v2", AArch64::Q2)
2641 .
Case(
"v3", AArch64::Q3)
2642 .
Case(
"v4", AArch64::Q4)
2643 .
Case(
"v5", AArch64::Q5)
2644 .
Case(
"v6", AArch64::Q6)
2645 .
Case(
"v7", AArch64::Q7)
2646 .
Case(
"v8", AArch64::Q8)
2647 .
Case(
"v9", AArch64::Q9)
2648 .
Case(
"v10", AArch64::Q10)
2649 .
Case(
"v11", AArch64::Q11)
2650 .
Case(
"v12", AArch64::Q12)
2651 .
Case(
"v13", AArch64::Q13)
2652 .
Case(
"v14", AArch64::Q14)
2653 .
Case(
"v15", AArch64::Q15)
2654 .
Case(
"v16", AArch64::Q16)
2655 .
Case(
"v17", AArch64::Q17)
2656 .
Case(
"v18", AArch64::Q18)
2657 .
Case(
"v19", AArch64::Q19)
2658 .
Case(
"v20", AArch64::Q20)
2659 .
Case(
"v21", AArch64::Q21)
2660 .
Case(
"v22", AArch64::Q22)
2661 .
Case(
"v23", AArch64::Q23)
2662 .
Case(
"v24", AArch64::Q24)
2663 .
Case(
"v25", AArch64::Q25)
2664 .
Case(
"v26", AArch64::Q26)
2665 .
Case(
"v27", AArch64::Q27)
2666 .
Case(
"v28", AArch64::Q28)
2667 .
Case(
"v29", AArch64::Q29)
2668 .
Case(
"v30", AArch64::Q30)
2669 .
Case(
"v31", AArch64::Q31)
2678 RegKind VectorKind) {
2679 std::pair<int, int> Res = {-1, -1};
2681 switch (VectorKind) {
2682 case RegKind::NeonVector:
2685 .Case(
".1d", {1, 64})
2686 .Case(
".1q", {1, 128})
2688 .Case(
".2h", {2, 16})
2689 .Case(
".2b", {2, 8})
2690 .Case(
".2s", {2, 32})
2691 .Case(
".2d", {2, 64})
2694 .Case(
".4b", {4, 8})
2695 .Case(
".4h", {4, 16})
2696 .Case(
".4s", {4, 32})
2697 .Case(
".8b", {8, 8})
2698 .Case(
".8h", {8, 16})
2699 .Case(
".16b", {16, 8})
2704 .Case(
".h", {0, 16})
2705 .Case(
".s", {0, 32})
2706 .Case(
".d", {0, 64})
2709 case RegKind::SVEPredicateAsCounter:
2710 case RegKind::SVEPredicateVector:
2711 case RegKind::SVEDataVector:
2712 case RegKind::Matrix:
2716 .Case(
".h", {0, 16})
2717 .Case(
".s", {0, 32})
2718 .Case(
".d", {0, 64})
2719 .Case(
".q", {0, 128})
2726 if (Res == std::make_pair(-1, -1))
2727 return std::nullopt;
2729 return std::optional<std::pair<int, int>>(Res);
2738 .
Case(
"z0", AArch64::Z0)
2739 .
Case(
"z1", AArch64::Z1)
2740 .
Case(
"z2", AArch64::Z2)
2741 .
Case(
"z3", AArch64::Z3)
2742 .
Case(
"z4", AArch64::Z4)
2743 .
Case(
"z5", AArch64::Z5)
2744 .
Case(
"z6", AArch64::Z6)
2745 .
Case(
"z7", AArch64::Z7)
2746 .
Case(
"z8", AArch64::Z8)
2747 .
Case(
"z9", AArch64::Z9)
2748 .
Case(
"z10", AArch64::Z10)
2749 .
Case(
"z11", AArch64::Z11)
2750 .
Case(
"z12", AArch64::Z12)
2751 .
Case(
"z13", AArch64::Z13)
2752 .
Case(
"z14", AArch64::Z14)
2753 .
Case(
"z15", AArch64::Z15)
2754 .
Case(
"z16", AArch64::Z16)
2755 .
Case(
"z17", AArch64::Z17)
2756 .
Case(
"z18", AArch64::Z18)
2757 .
Case(
"z19", AArch64::Z19)
2758 .
Case(
"z20", AArch64::Z20)
2759 .
Case(
"z21", AArch64::Z21)
2760 .
Case(
"z22", AArch64::Z22)
2761 .
Case(
"z23", AArch64::Z23)
2762 .
Case(
"z24", AArch64::Z24)
2763 .
Case(
"z25", AArch64::Z25)
2764 .
Case(
"z26", AArch64::Z26)
2765 .
Case(
"z27", AArch64::Z27)
2766 .
Case(
"z28", AArch64::Z28)
2767 .
Case(
"z29", AArch64::Z29)
2768 .
Case(
"z30", AArch64::Z30)
2769 .
Case(
"z31", AArch64::Z31)
2775 .
Case(
"p0", AArch64::P0)
2776 .
Case(
"p1", AArch64::P1)
2777 .
Case(
"p2", AArch64::P2)
2778 .
Case(
"p3", AArch64::P3)
2779 .
Case(
"p4", AArch64::P4)
2780 .
Case(
"p5", AArch64::P5)
2781 .
Case(
"p6", AArch64::P6)
2782 .
Case(
"p7", AArch64::P7)
2783 .
Case(
"p8", AArch64::P8)
2784 .
Case(
"p9", AArch64::P9)
2785 .
Case(
"p10", AArch64::P10)
2786 .
Case(
"p11", AArch64::P11)
2787 .
Case(
"p12", AArch64::P12)
2788 .
Case(
"p13", AArch64::P13)
2789 .
Case(
"p14", AArch64::P14)
2790 .
Case(
"p15", AArch64::P15)
2796 .
Case(
"pn0", AArch64::PN0)
2797 .
Case(
"pn1", AArch64::PN1)
2798 .
Case(
"pn2", AArch64::PN2)
2799 .
Case(
"pn3", AArch64::PN3)
2800 .
Case(
"pn4", AArch64::PN4)
2801 .
Case(
"pn5", AArch64::PN5)
2802 .
Case(
"pn6", AArch64::PN6)
2803 .
Case(
"pn7", AArch64::PN7)
2804 .
Case(
"pn8", AArch64::PN8)
2805 .
Case(
"pn9", AArch64::PN9)
2806 .
Case(
"pn10", AArch64::PN10)
2807 .
Case(
"pn11", AArch64::PN11)
2808 .
Case(
"pn12", AArch64::PN12)
2809 .
Case(
"pn13", AArch64::PN13)
2810 .
Case(
"pn14", AArch64::PN14)
2811 .
Case(
"pn15", AArch64::PN15)
2817 .
Case(
"za0.d", AArch64::ZAD0)
2818 .
Case(
"za1.d", AArch64::ZAD1)
2819 .
Case(
"za2.d", AArch64::ZAD2)
2820 .
Case(
"za3.d", AArch64::ZAD3)
2821 .
Case(
"za4.d", AArch64::ZAD4)
2822 .
Case(
"za5.d", AArch64::ZAD5)
2823 .
Case(
"za6.d", AArch64::ZAD6)
2824 .
Case(
"za7.d", AArch64::ZAD7)
2825 .
Case(
"za0.s", AArch64::ZAS0)
2826 .
Case(
"za1.s", AArch64::ZAS1)
2827 .
Case(
"za2.s", AArch64::ZAS2)
2828 .
Case(
"za3.s", AArch64::ZAS3)
2829 .
Case(
"za0.h", AArch64::ZAH0)
2830 .
Case(
"za1.h", AArch64::ZAH1)
2831 .
Case(
"za0.b", AArch64::ZAB0)
2837 .
Case(
"za", AArch64::ZA)
2838 .
Case(
"za0.q", AArch64::ZAQ0)
2839 .
Case(
"za1.q", AArch64::ZAQ1)
2840 .
Case(
"za2.q", AArch64::ZAQ2)
2841 .
Case(
"za3.q", AArch64::ZAQ3)
2842 .
Case(
"za4.q", AArch64::ZAQ4)
2843 .
Case(
"za5.q", AArch64::ZAQ5)
2844 .
Case(
"za6.q", AArch64::ZAQ6)
2845 .
Case(
"za7.q", AArch64::ZAQ7)
2846 .
Case(
"za8.q", AArch64::ZAQ8)
2847 .
Case(
"za9.q", AArch64::ZAQ9)
2848 .
Case(
"za10.q", AArch64::ZAQ10)
2849 .
Case(
"za11.q", AArch64::ZAQ11)
2850 .
Case(
"za12.q", AArch64::ZAQ12)
2851 .
Case(
"za13.q", AArch64::ZAQ13)
2852 .
Case(
"za14.q", AArch64::ZAQ14)
2853 .
Case(
"za15.q", AArch64::ZAQ15)
2854 .
Case(
"za0.d", AArch64::ZAD0)
2855 .
Case(
"za1.d", AArch64::ZAD1)
2856 .
Case(
"za2.d", AArch64::ZAD2)
2857 .
Case(
"za3.d", AArch64::ZAD3)
2858 .
Case(
"za4.d", AArch64::ZAD4)
2859 .
Case(
"za5.d", AArch64::ZAD5)
2860 .
Case(
"za6.d", AArch64::ZAD6)
2861 .
Case(
"za7.d", AArch64::ZAD7)
2862 .
Case(
"za0.s", AArch64::ZAS0)
2863 .
Case(
"za1.s", AArch64::ZAS1)
2864 .
Case(
"za2.s", AArch64::ZAS2)
2865 .
Case(
"za3.s", AArch64::ZAS3)
2866 .
Case(
"za0.h", AArch64::ZAH0)
2867 .
Case(
"za1.h", AArch64::ZAH1)
2868 .
Case(
"za0.b", AArch64::ZAB0)
2869 .
Case(
"za0h.q", AArch64::ZAQ0)
2870 .
Case(
"za1h.q", AArch64::ZAQ1)
2871 .
Case(
"za2h.q", AArch64::ZAQ2)
2872 .
Case(
"za3h.q", AArch64::ZAQ3)
2873 .
Case(
"za4h.q", AArch64::ZAQ4)
2874 .
Case(
"za5h.q", AArch64::ZAQ5)
2875 .
Case(
"za6h.q", AArch64::ZAQ6)
2876 .
Case(
"za7h.q", AArch64::ZAQ7)
2877 .
Case(
"za8h.q", AArch64::ZAQ8)
2878 .
Case(
"za9h.q", AArch64::ZAQ9)
2879 .
Case(
"za10h.q", AArch64::ZAQ10)
2880 .
Case(
"za11h.q", AArch64::ZAQ11)
2881 .
Case(
"za12h.q", AArch64::ZAQ12)
2882 .
Case(
"za13h.q", AArch64::ZAQ13)
2883 .
Case(
"za14h.q", AArch64::ZAQ14)
2884 .
Case(
"za15h.q", AArch64::ZAQ15)
2885 .
Case(
"za0h.d", AArch64::ZAD0)
2886 .
Case(
"za1h.d", AArch64::ZAD1)
2887 .
Case(
"za2h.d", AArch64::ZAD2)
2888 .
Case(
"za3h.d", AArch64::ZAD3)
2889 .
Case(
"za4h.d", AArch64::ZAD4)
2890 .
Case(
"za5h.d", AArch64::ZAD5)
2891 .
Case(
"za6h.d", AArch64::ZAD6)
2892 .
Case(
"za7h.d", AArch64::ZAD7)
2893 .
Case(
"za0h.s", AArch64::ZAS0)
2894 .
Case(
"za1h.s", AArch64::ZAS1)
2895 .
Case(
"za2h.s", AArch64::ZAS2)
2896 .
Case(
"za3h.s", AArch64::ZAS3)
2897 .
Case(
"za0h.h", AArch64::ZAH0)
2898 .
Case(
"za1h.h", AArch64::ZAH1)
2899 .
Case(
"za0h.b", AArch64::ZAB0)
2900 .
Case(
"za0v.q", AArch64::ZAQ0)
2901 .
Case(
"za1v.q", AArch64::ZAQ1)
2902 .
Case(
"za2v.q", AArch64::ZAQ2)
2903 .
Case(
"za3v.q", AArch64::ZAQ3)
2904 .
Case(
"za4v.q", AArch64::ZAQ4)
2905 .
Case(
"za5v.q", AArch64::ZAQ5)
2906 .
Case(
"za6v.q", AArch64::ZAQ6)
2907 .
Case(
"za7v.q", AArch64::ZAQ7)
2908 .
Case(
"za8v.q", AArch64::ZAQ8)
2909 .
Case(
"za9v.q", AArch64::ZAQ9)
2910 .
Case(
"za10v.q", AArch64::ZAQ10)
2911 .
Case(
"za11v.q", AArch64::ZAQ11)
2912 .
Case(
"za12v.q", AArch64::ZAQ12)
2913 .
Case(
"za13v.q", AArch64::ZAQ13)
2914 .
Case(
"za14v.q", AArch64::ZAQ14)
2915 .
Case(
"za15v.q", AArch64::ZAQ15)
2916 .
Case(
"za0v.d", AArch64::ZAD0)
2917 .
Case(
"za1v.d", AArch64::ZAD1)
2918 .
Case(
"za2v.d", AArch64::ZAD2)
2919 .
Case(
"za3v.d", AArch64::ZAD3)
2920 .
Case(
"za4v.d", AArch64::ZAD4)
2921 .
Case(
"za5v.d", AArch64::ZAD5)
2922 .
Case(
"za6v.d", AArch64::ZAD6)
2923 .
Case(
"za7v.d", AArch64::ZAD7)
2924 .
Case(
"za0v.s", AArch64::ZAS0)
2925 .
Case(
"za1v.s", AArch64::ZAS1)
2926 .
Case(
"za2v.s", AArch64::ZAS2)
2927 .
Case(
"za3v.s", AArch64::ZAS3)
2928 .
Case(
"za0v.h", AArch64::ZAH0)
2929 .
Case(
"za1v.h", AArch64::ZAH1)
2930 .
Case(
"za0v.b", AArch64::ZAB0)
2934bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2936 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2939ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2941 StartLoc = getLoc();
2942 ParseStatus Res = tryParseScalarRegister(
Reg);
2948MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2950 MCRegister
Reg = MCRegister();
2952 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2955 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2958 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2961 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2964 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2966 if (
Name.equals_insensitive(
"zt0"))
2967 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2971 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2975 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2976 .Case(
"fp", AArch64::FP)
2977 .Case(
"lr", AArch64::LR)
2978 .Case(
"x31", AArch64::XZR)
2979 .Case(
"w31", AArch64::WZR)
2981 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2987 if (Entry == RegisterReqs.
end())
2988 return MCRegister();
2991 if (Kind ==
Entry->getValue().first)
2997unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2999 case RegKind::Scalar:
3000 case RegKind::NeonVector:
3001 case RegKind::SVEDataVector:
3003 case RegKind::Matrix:
3004 case RegKind::SVEPredicateVector:
3005 case RegKind::SVEPredicateAsCounter:
3007 case RegKind::LookupTable:
3016ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3017 const AsmToken &Tok = getTok();
3022 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3036 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3039 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3040 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3044 if (BadNum || CRNum > 15)
3045 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3049 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3056 const AsmToken &Tok = getTok();
3058 unsigned MaxVal = 63;
3063 const MCExpr *ImmVal;
3064 if (getParser().parseExpression(ImmVal))
3069 return TokError(
"immediate value expected for prefetch operand");
3072 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3075 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3076 Operands.push_back(AArch64Operand::CreatePrefetch(
3077 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3083 return TokError(
"prefetch hint expected");
3085 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3087 return TokError(
"prefetch hint expected");
3089 Operands.push_back(AArch64Operand::CreatePrefetch(
3096template <
bool IsSVEPrefetch>
3099 const AsmToken &Tok = getTok();
3101 auto LookupByName = [](StringRef
N) {
3102 if (IsSVEPrefetch) {
3103 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3104 return std::optional<unsigned>(Res->Encoding);
3105 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3106 return std::optional<unsigned>(Res->Encoding);
3107 return std::optional<unsigned>();
3110 auto LookupByEncoding = [](
unsigned E) {
3111 if (IsSVEPrefetch) {
3112 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3113 return std::optional<StringRef>(
3114 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3115 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3116 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3117 return std::optional<StringRef>();
3119 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3125 const MCExpr *ImmVal;
3126 if (getParser().parseExpression(ImmVal))
3131 return TokError(
"immediate value expected for prefetch operand");
3134 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3137 auto PRFM = LookupByEncoding(MCE->
getValue());
3138 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3144 return TokError(
"prefetch hint expected");
3146 auto PRFM = LookupByName(Tok.
getString());
3148 return TokError(
"prefetch hint expected");
3150 Operands.push_back(AArch64Operand::CreatePrefetch(
3157 SMLoc StartLoc = getLoc();
3163 auto RegTok = getTok();
3164 if (!tryParseScalarRegister(RegNum).isSuccess())
3167 if (RegNum != AArch64::XZR) {
3168 getLexer().UnLex(RegTok);
3175 if (!tryParseScalarRegister(RegNum).isSuccess())
3176 return TokError(
"expected register operand");
3178 if (RegNum != AArch64::XZR)
3179 return TokError(
"xzr must be followed by xzr");
3183 Operands.push_back(AArch64Operand::CreateReg(
3184 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3192 const AsmToken &Tok = getTok();
3194 return TokError(
"invalid operand for instruction");
3196 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3198 return TokError(
"invalid operand for instruction");
3200 Operands.push_back(AArch64Operand::CreateTIndexHint(
3210 const MCExpr *Expr =
nullptr;
3216 if (parseSymbolicImmVal(Expr))
3222 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3231 return Error(S,
"gotpage label reference not allowed an addend");
3243 return Error(S,
"page or gotpage label reference expected");
3260 const MCExpr *Expr =
nullptr;
3269 if (parseSymbolicImmVal(Expr))
3275 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3287 return Error(S,
"unexpected adr label");
3297template <
bool AddFPZeroAsLiteral>
3306 const AsmToken &Tok = getTok();
3310 return TokError(
"invalid floating point immediate");
3315 if (Tok.
getIntVal() > 255 || isNegative)
3316 return TokError(
"encoded floating point value out of range");
3320 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3323 APFloat RealVal(APFloat::IEEEdouble());
3325 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3327 return TokError(
"invalid floating point representation");
3330 RealVal.changeSign();
3332 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3336 Operands.push_back(AArch64Operand::CreateFPImm(
3337 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3361 const MCExpr *
Imm =
nullptr;
3362 if (parseSymbolicImmVal(
Imm))
3373 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3377 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3383 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3384 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3392 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3394 int64_t ShiftAmount = getTok().getIntVal();
3396 if (ShiftAmount < 0)
3397 return Error(getLoc(),
"positive shift amount required");
3401 if (ShiftAmount == 0 &&
Imm !=
nullptr) {
3407 Operands.push_back(AArch64Operand::CreateShiftedImm(
Imm, ShiftAmount, S,
3415AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3449 Suggestion =
"nfrst";
3456 bool invertCondCode) {
3458 const AsmToken &Tok = getTok();
3462 std::string Suggestion;
3465 std::string
Msg =
"invalid condition code";
3466 if (!Suggestion.empty())
3467 Msg +=
", did you mean " + Suggestion +
"?";
3468 return TokError(
Msg);
3472 if (invertCondCode) {
3474 return TokError(
"condition codes AL and NV are invalid for this instruction");
3479 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3484 const AsmToken &Tok = getTok();
3488 return TokError(
"invalid operand for instruction");
3490 unsigned PStateImm = -1;
3491 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3494 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3495 PStateImm = SVCR->Encoding;
3504 const AsmToken &Tok = getTok();
3509 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3511 unsigned ElementWidth = 0;
3512 auto DotPosition =
Name.find(
'.');
3514 const auto &KindRes =
3518 "Expected the register to be followed by element width suffix");
3519 ElementWidth = KindRes->second;
3521 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3522 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3527 if (parseOperand(
Operands,
false,
false))
3534 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3538 size_t DotPosition =
Name.find(
'.');
3541 StringRef Head =
Name.take_front(DotPosition);
3542 StringRef
Tail =
Name.drop_front(DotPosition);
3543 StringRef RowOrColumn = Head.
take_back();
3545 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3546 .Case(
"h", MatrixKind::Row)
3547 .Case(
"v", MatrixKind::Col)
3548 .Default(MatrixKind::Tile);
3554 "Expected the register to be followed by element width suffix");
3555 unsigned ElementWidth = KindRes->second;
3559 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3565 if (parseOperand(
Operands,
false,
false))
3575 const AsmToken &Tok = getTok();
3578 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3607 return TokError(
"expected #imm after shift specifier");
3613 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3622 return Error(
E,
"expected integer shift amount");
3624 const MCExpr *ImmVal;
3625 if (getParser().parseExpression(ImmVal))
3630 return Error(
E,
"expected constant '#imm' after shift specifier");
3633 Operands.push_back(AArch64Operand::CreateShiftExtend(
3639 {{
"crc"}, {AArch64::FeatureCRC}},
3640 {{
"sm4"}, {AArch64::FeatureSM4}},
3641 {{
"sha3"}, {AArch64::FeatureSHA3}},
3642 {{
"sha2"}, {AArch64::FeatureSHA2}},
3643 {{
"aes"}, {AArch64::FeatureAES}},
3644 {{
"crypto"}, {AArch64::FeatureCrypto}},
3645 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3646 {{
"simd"}, {AArch64::FeatureNEON}},
3647 {{
"ras"}, {AArch64::FeatureRAS}},
3648 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3649 {{
"lse"}, {AArch64::FeatureLSE}},
3650 {{
"predres"}, {AArch64::FeaturePredRes}},
3651 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3652 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3653 {{
"mte"}, {AArch64::FeatureMTE}},
3654 {{
"memtag"}, {AArch64::FeatureMTE}},
3655 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3656 {{
"pan"}, {AArch64::FeaturePAN}},
3657 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3658 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3659 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3660 {{
"rng"}, {AArch64::FeatureRandGen}},
3661 {{
"sve"}, {AArch64::FeatureSVE}},
3662 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3663 {{
"sve2"}, {AArch64::FeatureSVE2}},
3664 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3665 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3666 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3667 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3668 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3669 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3670 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3672 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3673 AArch64::FeatureSVE2}},
3674 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3675 {{
"ls64"}, {AArch64::FeatureLS64}},
3676 {{
"xs"}, {AArch64::FeatureXS}},
3677 {{
"pauth"}, {AArch64::FeaturePAuth}},
3678 {{
"flagm"}, {AArch64::FeatureFlagM}},
3679 {{
"rme"}, {AArch64::FeatureRME}},
3680 {{
"sme"}, {AArch64::FeatureSME}},
3681 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3682 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3683 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3684 {{
"sme2"}, {AArch64::FeatureSME2}},
3685 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3686 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3687 {{
"hbc"}, {AArch64::FeatureHBC}},
3688 {{
"mops"}, {AArch64::FeatureMOPS}},
3689 {{
"mec"}, {AArch64::FeatureMEC}},
3690 {{
"the"}, {AArch64::FeatureTHE}},
3691 {{
"d128"}, {AArch64::FeatureD128}},
3692 {{
"lse128"}, {AArch64::FeatureLSE128}},
3693 {{
"ite"}, {AArch64::FeatureITE}},
3694 {{
"cssc"}, {AArch64::FeatureCSSC}},
3695 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3696 {{
"gcs"}, {AArch64::FeatureGCS}},
3697 {{
"bf16"}, {AArch64::FeatureBF16}},
3698 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3699 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3700 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3701 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3702 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3703 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3704 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3705 {{
"lor"}, {AArch64::FeatureLOR}},
3706 {{
"profile"}, {AArch64::FeatureSPE}},
3710 {{
"rdm"}, {AArch64::FeatureRDM}},
3711 {{
"rdma"}, {AArch64::FeatureRDM}},
3712 {{
"sb"}, {AArch64::FeatureSB}},
3713 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3714 {{
"fp8"}, {AArch64::FeatureFP8}},
3715 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3716 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3717 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3718 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3719 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3720 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3721 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3722 {{
"lut"}, {AArch64::FeatureLUT}},
3723 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3724 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3725 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3726 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3727 {{
"cpa"}, {AArch64::FeatureCPA}},
3728 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3729 {{
"pops"}, {AArch64::FeaturePoPS}},
3730 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3731 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3732 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3733 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3734 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3735 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3736 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3737 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3738 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3739 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3740 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3741 {{
"lsui"}, {AArch64::FeatureLSUI}},
3742 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3743 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3744 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3745 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3746 {{
"lscp"}, {AArch64::FeatureLSCP}},
3747 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3748 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3749 {{
"gcie"}, {AArch64::FeatureGCIE}},
3750 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3751 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3752 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3753 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3754 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3755 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3756 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3757 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3758 {{
"tev"}, {AArch64::FeatureTEV}},
3759 {{
"btie"}, {AArch64::FeatureBTIE}},
3760 {{
"hinte"}, {AArch64::FeatureHINTE}},
3761 {{
"dit"}, {AArch64::FeatureDIT}},
3762 {{
"brbe"}, {AArch64::FeatureBRBE}},
3763 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3764 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3765 {{
"jscvt"}, {AArch64::FeatureJS}},
3766 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3767 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3768 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3769 {{
"cflt"}, {AArch64::FeatureCFLT}},
3770 {{
"lsc64b"}, {AArch64::FeatureLSC64B}},
3771 {{
"sve-lrcpc"}, {AArch64::FeatureSVE_LRCPC}},
3776 if (FBS[AArch64::HasV8_0aOps])
3778 if (FBS[AArch64::HasV8_1aOps])
3780 else if (FBS[AArch64::HasV8_2aOps])
3782 else if (FBS[AArch64::HasV8_3aOps])
3784 else if (FBS[AArch64::HasV8_4aOps])
3786 else if (FBS[AArch64::HasV8_5aOps])
3788 else if (FBS[AArch64::HasV8_6aOps])
3790 else if (FBS[AArch64::HasV8_7aOps])
3792 else if (FBS[AArch64::HasV8_8aOps])
3794 else if (FBS[AArch64::HasV8_9aOps])
3796 else if (FBS[AArch64::HasV9_0aOps])
3798 else if (FBS[AArch64::HasV9_1aOps])
3800 else if (FBS[AArch64::HasV9_2aOps])
3802 else if (FBS[AArch64::HasV9_3aOps])
3804 else if (FBS[AArch64::HasV9_4aOps])
3806 else if (FBS[AArch64::HasV9_5aOps])
3808 else if (FBS[AArch64::HasV9_6aOps])
3810 else if (FBS[AArch64::HasV9_7aOps])
3812 else if (FBS[AArch64::HasV9_8aOps])
3814 else if (FBS[AArch64::HasV8_0rOps])
3823 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3829 const uint16_t Op2 = Encoding & 7;
3830 const uint16_t Cm = (Encoding & 0x78) >> 3;
3831 const uint16_t Cn = (Encoding & 0x780) >> 7;
3832 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3837 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3839 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3841 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3844 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3850bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3852 if (
Name.contains(
'.'))
3853 return TokError(
"invalid operand");
3858 const AsmToken &Tok = getTok();
3861 bool ExpectRegister =
true;
3862 bool OptionalRegister =
false;
3863 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3864 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3866 if (Mnemonic ==
"ic") {
3867 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3869 return TokError(
"invalid operand for IC instruction");
3870 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3871 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3874 return TokError(Str);
3878 }
else if (Mnemonic ==
"dc") {
3879 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3881 return TokError(
"invalid operand for DC instruction");
3882 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3883 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3886 return TokError(Str);
3889 }
else if (Mnemonic ==
"at") {
3890 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3892 return TokError(
"invalid operand for AT instruction");
3893 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3894 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3897 return TokError(Str);
3900 }
else if (Mnemonic ==
"tlbi") {
3901 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3903 return TokError(
"invalid operand for TLBI instruction");
3904 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3905 std::string Str(
"TLBI " +
3906 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3909 return TokError(Str);
3911 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3912 if (hasAll || hasTLBID)
3913 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3915 }
else if (Mnemonic ==
"gic") {
3916 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3918 return TokError(
"invalid operand for GIC instruction");
3919 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3920 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3923 return TokError(Str);
3927 }
else if (Mnemonic ==
"gsb") {
3928 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3930 return TokError(
"invalid operand for GSB instruction");
3931 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3932 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3935 return TokError(Str);
3937 ExpectRegister =
false;
3939 }
else if (Mnemonic ==
"plbi") {
3940 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3942 return TokError(
"invalid operand for PLBI instruction");
3943 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3944 std::string Str(
"PLBI " +
3945 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3948 return TokError(Str);
3950 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3951 if (hasAll || hasTLBID)
3952 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3954 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3955 Mnemonic ==
"cosp") {
3957 if (
Op.lower() !=
"rctx")
3958 return TokError(
"invalid operand for prediction restriction instruction");
3960 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3961 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3963 if (Mnemonic ==
"cosp" && !hasSpecres2)
3964 return TokError(
"COSP requires: predres2");
3966 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3968 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3969 : Mnemonic ==
"dvp" ? 0b101
3970 : Mnemonic ==
"cosp" ? 0b110
3971 : Mnemonic ==
"cpp" ? 0b111
3974 "Invalid mnemonic for prediction restriction instruction");
3975 const auto SYS_3_7_3 = 0b01101110011;
3976 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3978 createSysAlias(Encoding,
Operands, S);
3983 bool HasRegister =
false;
3988 return TokError(
"expected register operand");
3992 if (!OptionalRegister) {
3993 if (ExpectRegister && !HasRegister)
3994 return TokError(
"specified " + Mnemonic +
" op requires a register");
3995 else if (!ExpectRegister && HasRegister)
3996 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4008bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4013 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4016 SMLoc startLoc = getLoc();
4017 const AsmToken ®Tok = getTok();
4019 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4021 return TokError(
"expected register operand");
4023 Operands.push_back(AArch64Operand::CreateReg(
4024 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4031 const AsmToken &operandTok = getTok();
4033 SMLoc S2 = operandTok.
getLoc();
4036 if (Mnemonic ==
"gicr") {
4037 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4039 return Error(S2,
"invalid operand for GICR instruction");
4040 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4041 std::string Str(
"GICR " +
4042 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4045 return Error(S2, Str);
4058bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4060 if (
Name.contains(
'.'))
4061 return TokError(
"invalid operand");
4065 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4067 const AsmToken &Tok = getTok();
4071 if (Mnemonic ==
"tlbip") {
4072 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4074 return TokError(
"invalid operand for TLBIP instruction");
4077 std::string Str(
"instruction requires: ");
4079 return TokError(Str);
4090 return TokError(
"expected register identifier");
4095 return TokError(
"specified " + Mnemonic +
4096 " op requires a pair of registers");
4105 MCAsmParser &Parser = getParser();
4106 const AsmToken &Tok = getTok();
4110 const MCExpr *ImmVal;
4111 SMLoc ExprLoc = getLoc();
4112 AsmToken IntTok = Tok;
4113 if (getParser().parseExpression(ImmVal))
4117 return Error(ExprLoc,
"immediate value expected for barrier operand");
4119 if (Mnemonic ==
"dsb" &&
Value > 15) {
4127 return Error(ExprLoc,
"barrier operand out of range");
4128 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4129 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4130 Operands.push_back(AArch64Operand::CreateBarrier(
4136 return TokError(
"invalid operand for instruction");
4139 auto DB = AArch64DB::lookupDBByName(Operand);
4141 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4142 return TokError(
"'sy' or #imm operand expected");
4144 if (Mnemonic ==
"dsb") {
4149 return TokError(
"invalid barrier option name");
4153 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4162 const AsmToken &Tok = getTok();
4164 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4165 if (Mnemonic !=
"dsb")
4170 const MCExpr *ImmVal;
4171 SMLoc ExprLoc = getLoc();
4172 if (getParser().parseExpression(ImmVal))
4176 return Error(ExprLoc,
"immediate value expected for barrier operand");
4181 return Error(ExprLoc,
"barrier operand out of range");
4182 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4183 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4184 Operands.push_back(AArch64Operand::CreateBarrier(
4190 return TokError(
"invalid operand for instruction");
4193 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4196 return TokError(
"invalid barrier option name");
4199 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4207 const AsmToken &Tok = getTok();
4212 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4216 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4217 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4218 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4219 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4223 unsigned PStateImm = -1;
4224 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4225 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4226 PStateImm = PState15->Encoding;
4228 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4229 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4230 PStateImm = PState1->Encoding;
4234 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4250 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4258 unsigned ElementWidth = KindRes->second;
4260 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4268 return tryParseVectorIndex(
Operands).isFailure();
4272 SMLoc SIdx = getLoc();
4274 const MCExpr *ImmVal;
4275 if (getParser().parseExpression(ImmVal))
4279 return TokError(
"immediate value expected for vector index");
4286 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4297ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4299 RegKind MatchKind) {
4300 const AsmToken &Tok = getTok();
4309 StringRef Head =
Name.slice(Start,
Next);
4310 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4316 return TokError(
"invalid vector kind qualifier");
4327ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4329 ParseStatus Status =
4330 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4332 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4337template <RegKind RK>
4341 const SMLoc S = getLoc();
4344 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4352 unsigned ElementWidth = KindRes->second;
4353 Operands.push_back(AArch64Operand::CreateVectorReg(
4354 RegNum, RK, ElementWidth, S,
4358 if (RK == RegKind::SVEPredicateAsCounter) {
4359 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4365 if (parseOperand(
Operands,
false,
false))
4376 return Error(S,
"not expecting size suffix");
4384 auto Pred = getTok().getString().lower();
4385 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4386 return Error(getLoc(),
"expecting 'z' predication");
4388 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4389 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4392 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4402 if (!tryParseNeonVectorRegister(
Operands))
4405 if (tryParseZTOperand(
Operands).isSuccess())
4409 if (tryParseGPROperand<false>(
Operands).isSuccess())
4415bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4416 bool HasELFModifier =
false;
4418 SMLoc Loc = getLexer().getLoc();
4420 HasELFModifier =
true;
4423 return TokError(
"expect relocation specifier in operand after ':'");
4425 std::string LowerCase = getTok().getIdentifier().lower();
4426 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4481 return TokError(
"expect relocation specifier in operand after ':'");
4485 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4489 if (getParser().parseExpression(ImmVal))
4497 if (!HasELFModifier &&
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4498 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4508 if (getParser().parsePrimaryExpr(Term, EndLoc))
4520 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4521 unsigned &ElementWidth) -> ParseStatus {
4522 StringRef
Name = getTok().getString();
4523 size_t DotPosition =
Name.find(
'.');
4531 StringRef
Tail =
Name.drop_front(DotPosition);
4532 const std::optional<std::pair<int, int>> &KindRes =
4536 "Expected the register to be followed by element width suffix");
4537 ElementWidth = KindRes->second;
4544 auto LCurly = getTok();
4549 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4555 if (getTok().getString().equals_insensitive(
"za")) {
4561 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4566 SMLoc TileLoc = getLoc();
4568 unsigned FirstReg, ElementWidth;
4569 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4570 if (!ParseRes.isSuccess()) {
4571 getLexer().UnLex(LCurly);
4575 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4577 unsigned PrevReg = FirstReg;
4579 SmallSet<unsigned, 8> DRegs;
4580 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4582 SmallSet<unsigned, 8> SeenRegs;
4583 SeenRegs.
insert(FirstReg);
4587 unsigned Reg, NextElementWidth;
4588 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4589 if (!ParseRes.isSuccess())
4593 if (ElementWidth != NextElementWidth)
4594 return Error(TileLoc,
"mismatched register size suffix");
4597 Warning(TileLoc,
"tile list not in ascending order");
4600 Warning(TileLoc,
"duplicate tile in list");
4603 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4612 unsigned RegMask = 0;
4613 for (
auto Reg : DRegs)
4617 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4622template <RegKind VectorKind>
4625 MCAsmParser &Parser = getParser();
4630 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4631 bool NoMatchIsError) -> ParseStatus {
4632 auto RegTok = getTok();
4633 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4634 if (ParseRes.isSuccess()) {
4641 RegTok.getString().equals_insensitive(
"zt0"))
4645 (ParseRes.isNoMatch() && NoMatchIsError &&
4646 !RegTok.getString().starts_with_insensitive(
"za")))
4647 return Error(Loc,
"vector register expected");
4652 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4654 auto LCurly = getTok();
4658 MCRegister FirstReg;
4659 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4663 if (ParseRes.isNoMatch())
4666 if (!ParseRes.isSuccess())
4669 MCRegister PrevReg = FirstReg;
4672 unsigned Stride = 1;
4674 SMLoc Loc = getLoc();
4678 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4679 if (!ParseRes.isSuccess())
4683 if (Kind != NextKind)
4684 return Error(Loc,
"mismatched register size suffix");
4687 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4689 if (Space == 0 || Space > 3)
4690 return Error(Loc,
"invalid number of vectors");
4695 bool HasCalculatedStride =
false;
4697 SMLoc Loc = getLoc();
4700 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4701 if (!ParseRes.isSuccess())
4705 if (Kind != NextKind)
4706 return Error(Loc,
"mismatched register size suffix");
4708 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4709 unsigned PrevRegVal =
4710 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4711 if (!HasCalculatedStride) {
4712 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4713 : (NumRegs - (PrevRegVal - RegVal));
4714 HasCalculatedStride =
true;
4718 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4719 return Error(Loc,
"registers must have the same sequential stride");
4730 return Error(S,
"invalid number of vectors");
4732 unsigned NumElements = 0;
4733 unsigned ElementWidth = 0;
4734 if (!
Kind.empty()) {
4736 std::tie(NumElements, ElementWidth) = *VK;
4739 Operands.push_back(AArch64Operand::CreateVectorList(
4740 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4744 ParseStatus Res = tryParseVectorIndex(
Operands);
4755 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4756 if (!ParseRes.isSuccess())
4759 return tryParseVectorIndex(
Operands).isFailure();
4763 SMLoc StartLoc = getLoc();
4766 ParseStatus Res = tryParseScalarRegister(RegNum);
4771 Operands.push_back(AArch64Operand::CreateReg(
4772 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4779 return Error(getLoc(),
"index must be absent or #0");
4781 const MCExpr *ImmVal;
4784 return Error(getLoc(),
"index must be absent or #0");
4786 Operands.push_back(AArch64Operand::CreateReg(
4787 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4792 SMLoc StartLoc = getLoc();
4793 const AsmToken &Tok = getTok();
4796 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4801 Operands.push_back(AArch64Operand::CreateReg(
4802 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4808 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4809 const MCExpr *ImmVal;
4810 if (getParser().parseExpression(ImmVal))
4814 return TokError(
"immediate value expected for vector index");
4815 Operands.push_back(AArch64Operand::CreateImm(
4819 if (parseOptionalMulOperand(
Operands))
4824 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4829template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4831 SMLoc StartLoc = getLoc();
4834 ParseStatus Res = tryParseScalarRegister(RegNum);
4840 Operands.push_back(AArch64Operand::CreateReg(
4841 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4850 Res = tryParseOptionalShiftExtend(ExtOpnd);
4854 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4855 Operands.push_back(AArch64Operand::CreateReg(
4856 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4857 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4858 Ext->hasShiftExtendAmount()));
4864 MCAsmParser &Parser = getParser();
4872 if (!getTok().getString().equals_insensitive(
"mul") ||
4873 !(NextIsVL || NextIsHash))
4877 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4882 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4892 const MCExpr *ImmVal;
4895 Operands.push_back(AArch64Operand::CreateImm(
4902 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4906 StringRef &VecGroup) {
4907 MCAsmParser &Parser = getParser();
4908 auto Tok = Parser.
getTok();
4913 .Case(
"vgx2",
"vgx2")
4914 .Case(
"vgx4",
"vgx4")
4926 auto Tok = getTok();
4933 .Case(
"csync",
"csync")
4936 .Case(
"keep",
"keep")
4940 .Case(
"stshstrm",
"stshstrm")
4941 .Case(
"strm",
"strm")
4954 bool invertCondCode) {
4955 MCAsmParser &Parser = getParser();
4958 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4972 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4974 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4977 getLexer().UnLex(SavedTok);
4981 switch (getLexer().getKind()) {
4985 if (parseSymbolicImmVal(Expr))
4986 return Error(S,
"invalid operand");
4990 return parseOptionalShiftExtend(getTok());
4994 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4999 return parseOperand(
Operands,
false,
false);
5002 if (!parseNeonVectorList(
Operands))
5006 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
5011 return parseOperand(
Operands,
false,
false);
5016 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
5018 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5028 AsmToken SavedTok = getTok();
5033 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5037 Res = tryParseOptionalShiftExtend(
Operands);
5040 getLexer().UnLex(SavedTok);
5047 if (!parseOptionalMulOperand(
Operands))
5052 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5053 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5054 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh" ||
5056 return parseKeywordOperand(
Operands);
5060 const MCExpr *IdVal, *
Term;
5062 if (getParser().parseExpression(IdVal))
5064 if (getParser().parseAtSpecifier(IdVal,
E))
5066 std::optional<MCBinaryExpr::Opcode> Opcode;
5072 if (getParser().parsePrimaryExpr(Term,
E))
5079 return parseOptionalShiftExtend(getTok());
5090 bool isNegative =
false;
5102 const AsmToken &Tok = getTok();
5106 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5107 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5108 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5109 return TokError(
"unexpected floating point literal");
5110 else if (IntVal != 0 || isNegative)
5111 return TokError(
"expected floating-point constant #0.0");
5119 const MCExpr *ImmVal;
5120 if (parseSymbolicImmVal(ImmVal))
5127 return parseOptionalShiftExtend(Tok);
5130 SMLoc Loc = getLoc();
5131 if (Mnemonic !=
"ldr")
5132 return TokError(
"unexpected token in operand");
5134 const MCExpr *SubExprVal;
5135 if (getParser().parseExpression(SubExprVal))
5139 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5140 return Error(Loc,
"Only valid when first operand is register");
5142 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5150 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5155 if (ShiftAmt <= MaxShiftAmt &&
Imm <= 0xFFFF) {
5156 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5157 Operands.push_back(AArch64Operand::CreateImm(
5161 ShiftAmt,
true, S,
E, Ctx));
5164 APInt Simm = APInt(64,
Imm << ShiftAmt);
5167 return Error(Loc,
"Immediate too large for register");
5170 const MCExpr *CPLoc =
5171 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5172 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5178bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5179 const MCExpr *Expr =
nullptr;
5181 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5184 if (check(!
Value, L,
"expected constant expression"))
5190bool AArch64AsmParser::parseComma() {
5198bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5202 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register"))
5207 unsigned RangeEnd =
Last;
5208 if (
Base == AArch64::X0) {
5209 if (
Last == AArch64::FP) {
5210 RangeEnd = AArch64::X28;
5211 if (
Reg == AArch64::FP) {
5216 if (
Last == AArch64::LR) {
5217 RangeEnd = AArch64::X28;
5218 if (
Reg == AArch64::FP) {
5221 }
else if (
Reg == AArch64::LR) {
5229 Twine(
"expected register in range ") +
5237bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5238 const MCParsedAsmOperand &Op2)
const {
5239 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5240 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5242 if (AOp1.isVectorList() && AOp2.isVectorList())
5243 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5244 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5245 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5247 if (!AOp1.isReg() || !AOp2.isReg())
5250 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5251 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5254 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5255 "Testing equality of non-scalar registers not supported");
5258 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5260 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5262 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5264 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5271bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5272 StringRef Name, SMLoc NameLoc,
5274 Name = StringSwitch<StringRef>(
Name.lower())
5275 .Case(
"beq",
"b.eq")
5276 .Case(
"bne",
"b.ne")
5277 .Case(
"bhs",
"b.hs")
5278 .Case(
"bcs",
"b.cs")
5279 .Case(
"blo",
"b.lo")
5280 .Case(
"bcc",
"b.cc")
5281 .Case(
"bmi",
"b.mi")
5282 .Case(
"bpl",
"b.pl")
5283 .Case(
"bvs",
"b.vs")
5284 .Case(
"bvc",
"b.vc")
5285 .Case(
"bhi",
"b.hi")
5286 .Case(
"bls",
"b.ls")
5287 .Case(
"bge",
"b.ge")
5288 .Case(
"blt",
"b.lt")
5289 .Case(
"bgt",
"b.gt")
5290 .Case(
"ble",
"b.le")
5291 .Case(
"bal",
"b.al")
5292 .Case(
"bnv",
"b.nv")
5297 getTok().getIdentifier().lower() ==
".req") {
5298 parseDirectiveReq(Name, NameLoc);
5306 StringRef Head =
Name.slice(Start,
Next);
5310 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5311 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5312 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5313 return parseSysAlias(Head, NameLoc,
Operands);
5317 return parseSyslAlias(Head, NameLoc,
Operands);
5320 if (Head ==
"tlbip")
5321 return parseSyspAlias(Head, NameLoc,
Operands);
5327 if ((Head ==
"b" || Head ==
"bc" || Head ==
"flt") &&
5331 Head =
Name.slice(Start + 1,
Next);
5335 std::string Suggestion;
5338 std::string
Msg =
"invalid condition code";
5339 if (!Suggestion.empty())
5340 Msg +=
", did you mean " + Suggestion +
"?";
5346 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5356 Operands.push_back(AArch64Operand::CreateToken(
5362 bool condCodeFourthOperand =
5363 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5364 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5365 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5373 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5374 bool condCodeThirdOperand =
5375 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5383 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5384 (
N == 3 && condCodeThirdOperand) ||
5385 (
N == 2 && condCodeSecondOperand),
5386 condCodeSecondOperand || condCodeThirdOperand)) {
5406 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5409 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5412 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5425 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5426 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5427 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5428 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5429 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5430 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5431 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5443bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5444 SmallVectorImpl<SMLoc> &Loc) {
5445 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5452 PrefixInfo
Prefix = NextPrefix;
5453 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5464 return Error(IDLoc,
"instruction is unpredictable when following a"
5465 " movprfx, suggest replacing movprfx with mov");
5469 return Error(Loc[0],
"instruction is unpredictable when following a"
5470 " movprfx writing to a different destination");
5477 return Error(Loc[0],
"instruction is unpredictable when following a"
5478 " movprfx and destination also used as non-destructive"
5482 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5483 if (
Prefix.isPredicated()) {
5497 return Error(IDLoc,
"instruction is unpredictable when following a"
5498 " predicated movprfx, suggest using unpredicated movprfx");
5502 return Error(IDLoc,
"instruction is unpredictable when following a"
5503 " predicated movprfx using a different general predicate");
5507 return Error(IDLoc,
"instruction is unpredictable when following a"
5508 " predicated movprfx with a different element size");
5514 if (IsWindowsArm64EC) {
5520 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5521 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5522 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5523 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5524 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5525 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5526 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5527 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5528 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5529 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5531 " is disallowed on ARM64EC.");
5541 case AArch64::LDPSWpre:
5542 case AArch64::LDPWpost:
5543 case AArch64::LDPWpre:
5544 case AArch64::LDPXpost:
5545 case AArch64::LDPXpre: {
5550 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5551 "is also a destination");
5553 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5554 "is also a destination");
5557 case AArch64::LDR_ZA:
5558 case AArch64::STR_ZA: {
5561 return Error(Loc[1],
5562 "unpredictable instruction, immediate and offset mismatch.");
5565 case AArch64::LDPDi:
5566 case AArch64::LDPQi:
5567 case AArch64::LDPSi:
5568 case AArch64::LDPSWi:
5569 case AArch64::LDPWi:
5570 case AArch64::LDPXi: {
5574 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5577 case AArch64::LDPDpost:
5578 case AArch64::LDPDpre:
5579 case AArch64::LDPQpost:
5580 case AArch64::LDPQpre:
5581 case AArch64::LDPSpost:
5582 case AArch64::LDPSpre:
5583 case AArch64::LDPSWpost: {
5587 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5590 case AArch64::STPDpost:
5591 case AArch64::STPDpre:
5592 case AArch64::STPQpost:
5593 case AArch64::STPQpre:
5594 case AArch64::STPSpost:
5595 case AArch64::STPSpre:
5596 case AArch64::STPWpost:
5597 case AArch64::STPWpre:
5598 case AArch64::STPXpost:
5599 case AArch64::STPXpre: {
5604 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5605 "is also a source");
5607 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5608 "is also a source");
5611 case AArch64::LDRBBpre:
5612 case AArch64::LDRBpre:
5613 case AArch64::LDRHHpre:
5614 case AArch64::LDRHpre:
5615 case AArch64::LDRSBWpre:
5616 case AArch64::LDRSBXpre:
5617 case AArch64::LDRSHWpre:
5618 case AArch64::LDRSHXpre:
5619 case AArch64::LDRSWpre:
5620 case AArch64::LDRWpre:
5621 case AArch64::LDRXpre:
5622 case AArch64::LDRBBpost:
5623 case AArch64::LDRBpost:
5624 case AArch64::LDRHHpost:
5625 case AArch64::LDRHpost:
5626 case AArch64::LDRSBWpost:
5627 case AArch64::LDRSBXpost:
5628 case AArch64::LDRSHWpost:
5629 case AArch64::LDRSHXpost:
5630 case AArch64::LDRSWpost:
5631 case AArch64::LDRWpost:
5632 case AArch64::LDRXpost: {
5636 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5637 "is also a source");
5640 case AArch64::STRBBpost:
5641 case AArch64::STRBpost:
5642 case AArch64::STRHHpost:
5643 case AArch64::STRHpost:
5644 case AArch64::STRWpost:
5645 case AArch64::STRXpost:
5646 case AArch64::STRBBpre:
5647 case AArch64::STRBpre:
5648 case AArch64::STRHHpre:
5649 case AArch64::STRHpre:
5650 case AArch64::STRWpre:
5651 case AArch64::STRXpre: {
5655 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5656 "is also a source");
5659 case AArch64::STXRB:
5660 case AArch64::STXRH:
5661 case AArch64::STXRW:
5662 case AArch64::STXRX:
5663 case AArch64::STLXRB:
5664 case AArch64::STLXRH:
5665 case AArch64::STLXRW:
5666 case AArch64::STLXRX: {
5672 return Error(Loc[0],
5673 "unpredictable STXR instruction, status is also a source");
5676 case AArch64::STXPW:
5677 case AArch64::STXPX:
5678 case AArch64::STLXPW:
5679 case AArch64::STLXPX: {
5686 return Error(Loc[0],
5687 "unpredictable STXP instruction, status is also a source");
5690 case AArch64::LDRABwriteback:
5691 case AArch64::LDRAAwriteback: {
5695 return Error(Loc[0],
5696 "unpredictable LDRA instruction, writeback base"
5697 " is also a destination");
5704 case AArch64::CPYFP:
5705 case AArch64::CPYFPWN:
5706 case AArch64::CPYFPRN:
5707 case AArch64::CPYFPN:
5708 case AArch64::CPYFPWT:
5709 case AArch64::CPYFPWTWN:
5710 case AArch64::CPYFPWTRN:
5711 case AArch64::CPYFPWTN:
5712 case AArch64::CPYFPRT:
5713 case AArch64::CPYFPRTWN:
5714 case AArch64::CPYFPRTRN:
5715 case AArch64::CPYFPRTN:
5716 case AArch64::CPYFPT:
5717 case AArch64::CPYFPTWN:
5718 case AArch64::CPYFPTRN:
5719 case AArch64::CPYFPTN:
5720 case AArch64::CPYFM:
5721 case AArch64::CPYFMWN:
5722 case AArch64::CPYFMRN:
5723 case AArch64::CPYFMN:
5724 case AArch64::CPYFMWT:
5725 case AArch64::CPYFMWTWN:
5726 case AArch64::CPYFMWTRN:
5727 case AArch64::CPYFMWTN:
5728 case AArch64::CPYFMRT:
5729 case AArch64::CPYFMRTWN:
5730 case AArch64::CPYFMRTRN:
5731 case AArch64::CPYFMRTN:
5732 case AArch64::CPYFMT:
5733 case AArch64::CPYFMTWN:
5734 case AArch64::CPYFMTRN:
5735 case AArch64::CPYFMTN:
5736 case AArch64::CPYFE:
5737 case AArch64::CPYFEWN:
5738 case AArch64::CPYFERN:
5739 case AArch64::CPYFEN:
5740 case AArch64::CPYFEWT:
5741 case AArch64::CPYFEWTWN:
5742 case AArch64::CPYFEWTRN:
5743 case AArch64::CPYFEWTN:
5744 case AArch64::CPYFERT:
5745 case AArch64::CPYFERTWN:
5746 case AArch64::CPYFERTRN:
5747 case AArch64::CPYFERTN:
5748 case AArch64::CPYFET:
5749 case AArch64::CPYFETWN:
5750 case AArch64::CPYFETRN:
5751 case AArch64::CPYFETN:
5753 case AArch64::CPYPWN:
5754 case AArch64::CPYPRN:
5755 case AArch64::CPYPN:
5756 case AArch64::CPYPWT:
5757 case AArch64::CPYPWTWN:
5758 case AArch64::CPYPWTRN:
5759 case AArch64::CPYPWTN:
5760 case AArch64::CPYPRT:
5761 case AArch64::CPYPRTWN:
5762 case AArch64::CPYPRTRN:
5763 case AArch64::CPYPRTN:
5764 case AArch64::CPYPT:
5765 case AArch64::CPYPTWN:
5766 case AArch64::CPYPTRN:
5767 case AArch64::CPYPTN:
5769 case AArch64::CPYMWN:
5770 case AArch64::CPYMRN:
5771 case AArch64::CPYMN:
5772 case AArch64::CPYMWT:
5773 case AArch64::CPYMWTWN:
5774 case AArch64::CPYMWTRN:
5775 case AArch64::CPYMWTN:
5776 case AArch64::CPYMRT:
5777 case AArch64::CPYMRTWN:
5778 case AArch64::CPYMRTRN:
5779 case AArch64::CPYMRTN:
5780 case AArch64::CPYMT:
5781 case AArch64::CPYMTWN:
5782 case AArch64::CPYMTRN:
5783 case AArch64::CPYMTN:
5785 case AArch64::CPYEWN:
5786 case AArch64::CPYERN:
5787 case AArch64::CPYEN:
5788 case AArch64::CPYEWT:
5789 case AArch64::CPYEWTWN:
5790 case AArch64::CPYEWTRN:
5791 case AArch64::CPYEWTN:
5792 case AArch64::CPYERT:
5793 case AArch64::CPYERTWN:
5794 case AArch64::CPYERTRN:
5795 case AArch64::CPYERTN:
5796 case AArch64::CPYET:
5797 case AArch64::CPYETWN:
5798 case AArch64::CPYETRN:
5799 case AArch64::CPYETN: {
5810 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5811 " registers are the same");
5813 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5814 " registers are the same");
5816 return Error(Loc[0],
"invalid CPY instruction, source and size"
5817 " registers are the same");
5821 case AArch64::SETPT:
5822 case AArch64::SETPN:
5823 case AArch64::SETPTN:
5825 case AArch64::SETMT:
5826 case AArch64::SETMN:
5827 case AArch64::SETMTN:
5829 case AArch64::SETET:
5830 case AArch64::SETEN:
5831 case AArch64::SETETN:
5832 case AArch64::SETGP:
5833 case AArch64::SETGPT:
5834 case AArch64::SETGPN:
5835 case AArch64::SETGPTN:
5836 case AArch64::SETGM:
5837 case AArch64::SETGMT:
5838 case AArch64::SETGMN:
5839 case AArch64::SETGMTN:
5840 case AArch64::MOPSSETGE:
5841 case AArch64::MOPSSETGET:
5842 case AArch64::MOPSSETGEN:
5843 case AArch64::MOPSSETGETN: {
5853 return Error(Loc[0],
"invalid SET instruction, destination and size"
5854 " registers are the same");
5856 return Error(Loc[0],
"invalid SET instruction, destination and source"
5857 " registers are the same");
5859 return Error(Loc[0],
"invalid SET instruction, source and size"
5860 " registers are the same");
5863 case AArch64::SETGOP:
5864 case AArch64::SETGOPT:
5865 case AArch64::SETGOPN:
5866 case AArch64::SETGOPTN:
5867 case AArch64::SETGOM:
5868 case AArch64::SETGOMT:
5869 case AArch64::SETGOMN:
5870 case AArch64::SETGOMTN:
5871 case AArch64::SETGOE:
5872 case AArch64::SETGOET:
5873 case AArch64::SETGOEN:
5874 case AArch64::SETGOETN: {
5883 return Error(Loc[0],
"invalid SET instruction, destination and size"
5884 " registers are the same");
5893 case AArch64::ADDSWri:
5894 case AArch64::ADDSXri:
5895 case AArch64::ADDWri:
5896 case AArch64::ADDXri:
5897 case AArch64::SUBSWri:
5898 case AArch64::SUBSXri:
5899 case AArch64::SUBWri:
5900 case AArch64::SUBXri: {
5908 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5933 return Error(Loc.
back(),
"invalid immediate expression");
5946 unsigned VariantID = 0);
5948bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5952 case Match_InvalidTiedOperand: {
5954 if (
Op.isVectorList())
5955 return Error(
Loc,
"operand must match destination register list");
5957 assert(
Op.isReg() &&
"Unexpected operand type");
5958 switch (
Op.getRegEqualityTy()) {
5959 case RegConstraintEqualityTy::EqualsSubReg:
5960 return Error(
Loc,
"operand must be 64-bit form of destination register");
5961 case RegConstraintEqualityTy::EqualsSuperReg:
5962 return Error(
Loc,
"operand must be 32-bit form of destination register");
5963 case RegConstraintEqualityTy::EqualsReg:
5964 return Error(
Loc,
"operand must match destination register");
5968 case Match_MissingFeature:
5970 "instruction requires a CPU feature not currently enabled");
5971 case Match_InvalidOperand:
5972 return Error(Loc,
"invalid operand for instruction");
5973 case Match_InvalidSuffix:
5974 return Error(Loc,
"invalid type suffix for instruction");
5975 case Match_InvalidCondCode:
5976 return Error(Loc,
"expected AArch64 condition code");
5977 case Match_AddSubRegExtendSmall:
5979 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5980 case Match_AddSubRegExtendLarge:
5982 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5983 case Match_AddSubSecondSource:
5985 "expected compatible register, symbol or integer in range [0, 4095]");
5986 case Match_LogicalSecondSource:
5987 return Error(Loc,
"expected compatible register or logical immediate");
5988 case Match_InvalidMovImm32Shift:
5989 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5990 case Match_InvalidMovImm64Shift:
5991 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5992 case Match_AddSubRegShift32:
5994 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5995 case Match_AddSubRegShift64:
5997 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5998 case Match_InvalidFPImm:
6000 "expected compatible register or floating-point constant");
6001 case Match_InvalidMemoryIndexedSImm6:
6002 return Error(Loc,
"index must be an integer in range [-32, 31].");
6003 case Match_InvalidMemoryIndexedSImm5:
6004 return Error(Loc,
"index must be an integer in range [-16, 15].");
6005 case Match_InvalidMemoryIndexed1SImm4:
6006 return Error(Loc,
"index must be an integer in range [-8, 7].");
6007 case Match_InvalidMemoryIndexed2SImm4:
6008 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
6009 case Match_InvalidMemoryIndexed3SImm4:
6010 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
6011 case Match_InvalidMemoryIndexed4SImm4:
6012 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
6013 case Match_InvalidMemoryIndexed16SImm4:
6014 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
6015 case Match_InvalidMemoryIndexed32SImm4:
6016 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6017 case Match_InvalidMemoryIndexed1SImm6:
6018 return Error(Loc,
"index must be an integer in range [-32, 31].");
6019 case Match_InvalidMemoryIndexedSImm8:
6020 return Error(Loc,
"index must be an integer in range [-128, 127].");
6021 case Match_InvalidMemoryIndexedSImm9:
6022 return Error(Loc,
"index must be an integer in range [-256, 255].");
6023 case Match_InvalidMemoryIndexed16SImm9:
6024 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6025 case Match_InvalidMemoryIndexed8SImm10:
6026 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6027 case Match_InvalidMemoryIndexed4SImm7:
6028 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6029 case Match_InvalidMemoryIndexed8SImm7:
6030 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6031 case Match_InvalidMemoryIndexed16SImm7:
6032 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6033 case Match_InvalidMemoryIndexed8UImm5:
6034 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6035 case Match_InvalidMemoryIndexed8UImm3:
6036 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6037 case Match_InvalidMemoryIndexed4UImm5:
6038 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6039 case Match_InvalidMemoryIndexed2UImm5:
6040 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6041 case Match_InvalidMemoryIndexed8UImm6:
6042 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6043 case Match_InvalidMemoryIndexed16UImm6:
6044 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6045 case Match_InvalidMemoryIndexed32UImm8:
6046 return Error(Loc,
"index must be a multiple of 32 in range [0, 8160].");
6047 case Match_InvalidMemoryIndexed4UImm6:
6048 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6049 case Match_InvalidMemoryIndexed2UImm6:
6050 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6051 case Match_InvalidMemoryIndexed1UImm6:
6052 return Error(Loc,
"index must be in range [0, 63].");
6053 case Match_InvalidMemoryWExtend8:
6055 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6056 case Match_InvalidMemoryWExtend16:
6058 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6059 case Match_InvalidMemoryWExtend32:
6061 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6062 case Match_InvalidMemoryWExtend64:
6064 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6065 case Match_InvalidMemoryWExtend128:
6067 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6068 case Match_InvalidMemoryXExtend8:
6070 "expected 'lsl' or 'sxtx' with optional shift of #0");
6071 case Match_InvalidMemoryXExtend16:
6073 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6074 case Match_InvalidMemoryXExtend32:
6076 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6077 case Match_InvalidMemoryXExtend64:
6079 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6080 case Match_InvalidMemoryXExtend128:
6082 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6083 case Match_InvalidMemoryIndexed1:
6084 return Error(Loc,
"index must be an integer in range [0, 4095].");
6085 case Match_InvalidMemoryIndexed2:
6086 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6087 case Match_InvalidMemoryIndexed4:
6088 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6089 case Match_InvalidMemoryIndexed8:
6090 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6091 case Match_InvalidMemoryIndexed16:
6092 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6093 case Match_InvalidImm0_0:
6094 return Error(Loc,
"immediate must be 0.");
6095 case Match_InvalidImm0_1:
6096 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6097 case Match_InvalidImm0_3:
6098 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6099 case Match_InvalidImm0_7:
6100 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6101 case Match_InvalidImm0_15:
6102 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6103 case Match_InvalidImm0_31:
6104 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6105 case Match_InvalidImm0_63:
6106 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6107 case Match_InvalidImm0_127:
6108 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6109 case Match_InvalidImm0_255:
6110 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6111 case Match_InvalidImm0_511:
6112 return Error(Loc,
"immediate must be an integer in range [0, 511].");
6113 case Match_InvalidImm0_65535:
6114 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6115 case Match_InvalidHinteUImm16:
6117 "immediate must be an integer in range [0, 65535], excluding "
6118 "values in range [12319, 16383] where (value - 12319) is a "
6120 case Match_InvalidImm1_8:
6121 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6122 case Match_InvalidImm1_16:
6123 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6124 case Match_InvalidImm1_32:
6125 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6126 case Match_InvalidImm1_64:
6127 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6128 case Match_InvalidImm1_512:
6129 return Error(Loc,
"immediate must be an integer in range [1, 512].");
6130 case Match_InvalidImmM1_62:
6131 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6132 case Match_InvalidImmM1_510:
6133 return Error(Loc,
"immediate must be an integer in range [-1, 510].");
6134 case Match_InvalidImmM255_256:
6135 return Error(Loc,
"immediate must be an integer in range [-255, 256].");
6136 case Match_InvalidImmM257_254:
6137 return Error(Loc,
"immediate must be an integer in range [-257, 254].");
6138 case Match_InvalidMemoryIndexedRange2UImm0:
6139 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6140 case Match_InvalidMemoryIndexedRange2UImm1:
6141 return Error(Loc,
"vector select offset must be an immediate range of the "
6142 "form <immf>:<imml>, where the first "
6143 "immediate is a multiple of 2 in the range [0, 2], and "
6144 "the second immediate is immf + 1.");
6145 case Match_InvalidMemoryIndexedRange2UImm2:
6146 case Match_InvalidMemoryIndexedRange2UImm3:
6149 "vector select offset must be an immediate range of the form "
6151 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6153 "depending on the instruction, and the second immediate is immf + 1.");
6154 case Match_InvalidMemoryIndexedRange4UImm0:
6155 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6156 case Match_InvalidMemoryIndexedRange4UImm1:
6157 case Match_InvalidMemoryIndexedRange4UImm2:
6160 "vector select offset must be an immediate range of the form "
6162 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6164 "depending on the instruction, and the second immediate is immf + 3.");
6165 case Match_InvalidSVEAddSubImm8:
6166 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6167 " with a shift amount of 0");
6168 case Match_InvalidSVEAddSubImm16:
6169 case Match_InvalidSVEAddSubImm32:
6170 case Match_InvalidSVEAddSubImm64:
6171 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6172 "multiple of 256 in range [256, 65280]");
6173 case Match_InvalidSVECpyImm8:
6174 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6175 " with a shift amount of 0");
6176 case Match_InvalidSVECpyImm16:
6177 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6178 "multiple of 256 in range [-32768, 65280]");
6179 case Match_InvalidSVECpyImm32:
6180 case Match_InvalidSVECpyImm64:
6181 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6182 "multiple of 256 in range [-32768, 32512]");
6183 case Match_InvalidIndexRange0_0:
6184 return Error(Loc,
"expected lane specifier '[0]'");
6185 case Match_InvalidIndexRange1_1:
6186 return Error(Loc,
"expected lane specifier '[1]'");
6187 case Match_InvalidIndexRange0_15:
6188 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6189 case Match_InvalidIndexRange0_7:
6190 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6191 case Match_InvalidIndexRange0_3:
6192 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6193 case Match_InvalidIndexRange0_1:
6194 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6195 case Match_InvalidSVEIndexRange0_63:
6196 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6197 case Match_InvalidSVEIndexRange0_31:
6198 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6199 case Match_InvalidSVEIndexRange0_15:
6200 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6201 case Match_InvalidSVEIndexRange0_7:
6202 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6203 case Match_InvalidSVEIndexRange0_3:
6204 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6205 case Match_InvalidLabel:
6206 return Error(Loc,
"expected label or encodable integer pc offset");
6208 return Error(Loc,
"expected readable system register");
6210 case Match_InvalidSVCR:
6211 return Error(Loc,
"expected writable system register or pstate");
6212 case Match_InvalidComplexRotationEven:
6213 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6214 case Match_InvalidComplexRotationOdd:
6215 return Error(Loc,
"complex rotation must be 90 or 270.");
6216 case Match_MnemonicFail: {
6219 ComputeAvailableFeatures(STI->getFeatureBits()));
6220 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6222 case Match_InvalidGPR64shifted8:
6223 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6224 case Match_InvalidGPR64shifted16:
6225 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6226 case Match_InvalidGPR64shifted32:
6227 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6228 case Match_InvalidGPR64shifted64:
6229 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6230 case Match_InvalidGPR64shifted128:
6232 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6233 case Match_InvalidGPR64NoXZRshifted8:
6234 return Error(Loc,
"register must be x0..x30 without shift");
6235 case Match_InvalidGPR64NoXZRshifted16:
6236 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6237 case Match_InvalidGPR64NoXZRshifted32:
6238 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6239 case Match_InvalidGPR64NoXZRshifted64:
6240 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6241 case Match_InvalidGPR64NoXZRshifted128:
6242 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6243 case Match_InvalidZPR32UXTW8:
6244 case Match_InvalidZPR32SXTW8:
6245 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6246 case Match_InvalidZPR32UXTW16:
6247 case Match_InvalidZPR32SXTW16:
6248 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6249 case Match_InvalidZPR32UXTW32:
6250 case Match_InvalidZPR32SXTW32:
6251 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6252 case Match_InvalidZPR32UXTW64:
6253 case Match_InvalidZPR32SXTW64:
6254 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6255 case Match_InvalidZPR64UXTW8:
6256 case Match_InvalidZPR64SXTW8:
6257 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6258 case Match_InvalidZPR64UXTW16:
6259 case Match_InvalidZPR64SXTW16:
6260 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6261 case Match_InvalidZPR64UXTW32:
6262 case Match_InvalidZPR64SXTW32:
6263 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6264 case Match_InvalidZPR64UXTW64:
6265 case Match_InvalidZPR64SXTW64:
6266 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6267 case Match_InvalidZPR32LSL8:
6268 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6269 case Match_InvalidZPR32LSL16:
6270 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6271 case Match_InvalidZPR32LSL32:
6272 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6273 case Match_InvalidZPR32LSL64:
6274 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6275 case Match_InvalidZPR64LSL8:
6276 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6277 case Match_InvalidZPR64LSL16:
6278 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6279 case Match_InvalidZPR64LSL32:
6280 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6281 case Match_InvalidZPR64LSL64:
6282 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6283 case Match_InvalidZPR0:
6284 return Error(Loc,
"expected register without element width suffix");
6285 case Match_InvalidZPR8:
6286 case Match_InvalidZPR16:
6287 case Match_InvalidZPR32:
6288 case Match_InvalidZPR64:
6289 case Match_InvalidZPR128:
6290 return Error(Loc,
"invalid element width");
6291 case Match_InvalidZPR_3b8:
6292 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6293 case Match_InvalidZPR_3b16:
6294 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6295 case Match_InvalidZPR_3b32:
6296 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6297 case Match_InvalidZPR_4b8:
6299 "Invalid restricted vector register, expected z0.b..z15.b");
6300 case Match_InvalidZPR_4b16:
6301 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6302 case Match_InvalidZPR_4b32:
6303 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6304 case Match_InvalidZPR_4b64:
6305 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6306 case Match_InvalidZPRMul2_Lo8:
6307 return Error(Loc,
"Invalid restricted vector register, expected even "
6308 "register in z0.b..z14.b");
6309 case Match_InvalidZPRMul2_Hi8:
6310 return Error(Loc,
"Invalid restricted vector register, expected even "
6311 "register in z16.b..z30.b");
6312 case Match_InvalidZPRMul2_Lo16:
6313 return Error(Loc,
"Invalid restricted vector register, expected even "
6314 "register in z0.h..z14.h");
6315 case Match_InvalidZPRMul2_Hi16:
6316 return Error(Loc,
"Invalid restricted vector register, expected even "
6317 "register in z16.h..z30.h");
6318 case Match_InvalidZPRMul2_Lo32:
6319 return Error(Loc,
"Invalid restricted vector register, expected even "
6320 "register in z0.s..z14.s");
6321 case Match_InvalidZPRMul2_Hi32:
6322 return Error(Loc,
"Invalid restricted vector register, expected even "
6323 "register in z16.s..z30.s");
6324 case Match_InvalidZPRMul2_Lo64:
6325 return Error(Loc,
"Invalid restricted vector register, expected even "
6326 "register in z0.d..z14.d");
6327 case Match_InvalidZPRMul2_Hi64:
6328 return Error(Loc,
"Invalid restricted vector register, expected even "
6329 "register in z16.d..z30.d");
6330 case Match_InvalidZPR_K0:
6331 return Error(Loc,
"invalid restricted vector register, expected register "
6332 "in z20..z23 or z28..z31");
6333 case Match_InvalidSVEPattern:
6334 return Error(Loc,
"invalid predicate pattern");
6335 case Match_InvalidSVEPPRorPNRAnyReg:
6336 case Match_InvalidSVEPPRorPNRBReg:
6337 case Match_InvalidSVEPredicateAnyReg:
6338 case Match_InvalidSVEPredicateBReg:
6339 case Match_InvalidSVEPredicateHReg:
6340 case Match_InvalidSVEPredicateSReg:
6341 case Match_InvalidSVEPredicateDReg:
6342 return Error(Loc,
"invalid predicate register.");
6343 case Match_InvalidSVEPredicate3bAnyReg:
6344 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6345 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6346 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6347 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6348 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6349 return Error(Loc,
"Invalid predicate register, expected PN in range "
6350 "pn8..pn15 with element suffix.");
6351 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6352 return Error(Loc,
"invalid restricted predicate-as-counter register "
6353 "expected pn8..pn15");
6354 case Match_InvalidSVEPNPredicateBReg:
6355 case Match_InvalidSVEPNPredicateHReg:
6356 case Match_InvalidSVEPNPredicateSReg:
6357 case Match_InvalidSVEPNPredicateDReg:
6358 return Error(Loc,
"Invalid predicate register, expected PN in range "
6359 "pn0..pn15 with element suffix.");
6360 case Match_InvalidSVEVecLenSpecifier:
6361 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6362 case Match_InvalidSVEPredicateListMul2x8:
6363 case Match_InvalidSVEPredicateListMul2x16:
6364 case Match_InvalidSVEPredicateListMul2x32:
6365 case Match_InvalidSVEPredicateListMul2x64:
6366 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6367 "predicate registers, where the first vector is a multiple of 2 "
6368 "and with correct element type");
6369 case Match_InvalidSVEExactFPImmOperandHalfOne:
6370 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6371 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6372 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6373 case Match_InvalidSVEExactFPImmOperandZeroOne:
6374 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6375 case Match_InvalidMatrixTileVectorH8:
6376 case Match_InvalidMatrixTileVectorV8:
6377 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6378 case Match_InvalidMatrixTileVectorH16:
6379 case Match_InvalidMatrixTileVectorV16:
6381 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6382 case Match_InvalidMatrixTileVectorH32:
6383 case Match_InvalidMatrixTileVectorV32:
6385 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6386 case Match_InvalidMatrixTileVectorH64:
6387 case Match_InvalidMatrixTileVectorV64:
6389 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6390 case Match_InvalidMatrixTileVectorH128:
6391 case Match_InvalidMatrixTileVectorV128:
6393 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6394 case Match_InvalidMatrixTile16:
6395 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6396 case Match_InvalidMatrixTile32:
6397 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6398 case Match_InvalidMatrixTile64:
6399 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6400 case Match_InvalidMatrix:
6401 return Error(Loc,
"invalid matrix operand, expected za");
6402 case Match_InvalidMatrix8:
6403 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6404 case Match_InvalidMatrix16:
6405 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6406 case Match_InvalidMatrix32:
6407 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6408 case Match_InvalidMatrix64:
6409 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6410 case Match_InvalidMatrixIndexGPR32_12_15:
6411 return Error(Loc,
"operand must be a register in range [w12, w15]");
6412 case Match_InvalidMatrixIndexGPR32_8_11:
6413 return Error(Loc,
"operand must be a register in range [w8, w11]");
6414 case Match_InvalidSVEVectorList2x8Mul2:
6415 case Match_InvalidSVEVectorList2x16Mul2:
6416 case Match_InvalidSVEVectorList2x32Mul2:
6417 case Match_InvalidSVEVectorList2x64Mul2:
6418 case Match_InvalidSVEVectorList2x128Mul2:
6419 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6420 "SVE vectors, where the first vector is a multiple of 2 "
6421 "and with matching element types");
6422 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6423 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6424 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6425 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6426 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6427 "SVE vectors in the range z0-z14, where the first vector "
6428 "is a multiple of 2 "
6429 "and with matching element types");
6430 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6431 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6432 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6433 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6435 "Invalid vector list, expected list with 2 consecutive "
6436 "SVE vectors in the range z16-z30, where the first vector "
6437 "is a multiple of 2 "
6438 "and with matching element types");
6439 case Match_InvalidSVEVectorList4x8Mul4:
6440 case Match_InvalidSVEVectorList4x16Mul4:
6441 case Match_InvalidSVEVectorList4x32Mul4:
6442 case Match_InvalidSVEVectorList4x64Mul4:
6443 case Match_InvalidSVEVectorList4x128Mul4:
6444 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6445 "SVE vectors, where the first vector is a multiple of 4 "
6446 "and with matching element types");
6447 case Match_InvalidSVEVectorList3x0_3b:
6448 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6449 "SVE vectors starting at z0-z7");
6450 case Match_InvalidLookupTable:
6451 return Error(Loc,
"Invalid lookup table, expected zt0");
6452 case Match_InvalidSVEVectorListStrided2x8:
6453 case Match_InvalidSVEVectorListStrided2x16:
6454 case Match_InvalidSVEVectorListStrided2x32:
6455 case Match_InvalidSVEVectorListStrided2x64:
6458 "Invalid vector list, expected list with each SVE vector in the list "
6459 "8 registers apart, and the first register in the range [z0, z7] or "
6460 "[z16, z23] and with correct element type");
6461 case Match_InvalidSVEVectorListStrided4x8:
6462 case Match_InvalidSVEVectorListStrided4x16:
6463 case Match_InvalidSVEVectorListStrided4x32:
6464 case Match_InvalidSVEVectorListStrided4x64:
6467 "Invalid vector list, expected list with each SVE vector in the list "
6468 "4 registers apart, and the first register in the range [z0, z3] or "
6469 "[z16, z19] and with correct element type");
6470 case Match_AddSubLSLImm3ShiftLarge:
6472 "expected 'lsl' with optional integer in range [0, 7]");
6480bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6484 bool MatchingInlineAsm) {
6486 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6487 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6490 unsigned NumOperands =
Operands.size();
6492 if (NumOperands == 4 && Tok ==
"lsl") {
6493 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6494 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6495 if (Op2.isScalarReg() && Op3.isImm()) {
6501 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6503 NewOp3Val = (32 - Op3Val) & 0x1f;
6504 NewOp4Val = 31 - Op3Val;
6506 NewOp3Val = (64 - Op3Val) & 0x3f;
6507 NewOp4Val = 63 - Op3Val;
6514 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6515 Operands.push_back(AArch64Operand::CreateImm(
6516 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6517 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6521 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6523 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6524 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6525 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6527 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6531 if (LSBCE && WidthCE) {
6536 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6542 if (LSB >= RegWidth)
6543 return Error(LSBOp.getStartLoc(),
6544 "expected integer in range [0, 31]");
6545 if (Width < 1 || Width > RegWidth)
6546 return Error(WidthOp.getStartLoc(),
6547 "expected integer in range [1, 32]");
6551 ImmR = (32 - LSB) & 0x1f;
6553 ImmR = (64 - LSB) & 0x3f;
6557 if (ImmR != 0 && ImmS >= ImmR)
6558 return Error(WidthOp.getStartLoc(),
6559 "requested insert overflows register");
6564 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6565 Operands[2] = AArch64Operand::CreateReg(
6566 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6568 Operands[3] = AArch64Operand::CreateImm(
6569 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6571 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6575 }
else if (NumOperands == 5) {
6578 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6579 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6580 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6581 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6583 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6587 if (Op3CE && Op4CE) {
6592 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6598 if (Op3Val >= RegWidth)
6599 return Error(Op3.getStartLoc(),
6600 "expected integer in range [0, 31]");
6601 if (Op4Val < 1 || Op4Val > RegWidth)
6602 return Error(Op4.getStartLoc(),
6603 "expected integer in range [1, 32]");
6607 NewOp3Val = (32 - Op3Val) & 0x1f;
6609 NewOp3Val = (64 - Op3Val) & 0x3f;
6613 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6614 return Error(Op4.getStartLoc(),
6615 "requested insert overflows register");
6617 const MCExpr *NewOp3 =
6619 const MCExpr *NewOp4 =
6621 Operands[3] = AArch64Operand::CreateImm(
6622 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6623 Operands[4] = AArch64Operand::CreateImm(
6624 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6626 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6628 else if (Tok ==
"sbfiz")
6629 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6631 else if (Tok ==
"ubfiz")
6632 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6641 }
else if (NumOperands == 5 &&
6642 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6643 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6644 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6645 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6647 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6651 if (Op3CE && Op4CE) {
6656 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6662 if (Op3Val >= RegWidth)
6663 return Error(Op3.getStartLoc(),
6664 "expected integer in range [0, 31]");
6665 if (Op4Val < 1 || Op4Val > RegWidth)
6666 return Error(Op4.getStartLoc(),
6667 "expected integer in range [1, 32]");
6669 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6671 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6672 return Error(Op4.getStartLoc(),
6673 "requested extract overflows register");
6675 const MCExpr *NewOp4 =
6677 Operands[4] = AArch64Operand::CreateImm(
6678 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6680 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6682 else if (Tok ==
"sbfx")
6683 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6685 else if (Tok ==
"ubfx")
6686 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6699 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6700 NumOperands == 4 && Tok ==
"movi") {
6701 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6702 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6703 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6704 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6705 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6706 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6707 if (Suffix.
lower() ==
".2d" &&
6709 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6710 " correctly on this CPU, converting to equivalent movi.16b");
6712 unsigned Idx = Op1.isToken() ? 1 : 2;
6714 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6722 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6725 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6726 if (
Op.isScalarReg()) {
6728 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6729 Op.getStartLoc(),
Op.getEndLoc(),
6734 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6735 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6736 if (
Op.isScalarReg() &&
6737 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6741 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6742 if (
Op.isScalarReg()) {
6744 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6751 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6752 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6753 if (
Op.isScalarReg() &&
6754 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6758 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6759 if (
Op.isScalarReg()) {
6761 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6769 FeatureBitset MissingFeatures;
6772 unsigned MatchResult =
6773 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6774 MatchingInlineAsm, 1);
6778 if (MatchResult != Match_Success) {
6781 auto ShortFormNEONErrorInfo = ErrorInfo;
6782 auto ShortFormNEONMatchResult = MatchResult;
6783 auto ShortFormNEONMissingFeatures = MissingFeatures;
6786 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6787 MatchingInlineAsm, 0);
6792 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6794 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6795 MatchResult = ShortFormNEONMatchResult;
6796 ErrorInfo = ShortFormNEONErrorInfo;
6797 MissingFeatures = ShortFormNEONMissingFeatures;
6801 switch (MatchResult) {
6802 case Match_Success: {
6806 for (
unsigned i = 1; i < NumOperands; ++i)
6808 if (validateInstruction(Inst, IDLoc, OperandLocs))
6812 Out.emitInstruction(Inst, getSTI());
6815 case Match_MissingFeature: {
6816 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6819 std::string
Msg =
"instruction requires:";
6820 for (
unsigned Feature : MissingFeatures) {
6826 case Match_MnemonicFail:
6827 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6828 case Match_InvalidOperand: {
6829 SMLoc ErrorLoc = IDLoc;
6831 if (ErrorInfo != ~0ULL) {
6833 return Error(IDLoc,
"too few operands for instruction",
6834 SMRange(IDLoc, getTok().getLoc()));
6836 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6837 if (ErrorLoc == SMLoc())
6842 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6843 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6844 MatchResult = Match_InvalidSuffix;
6846 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6848 case Match_InvalidTiedOperand:
6849 case Match_InvalidMemoryIndexed1:
6850 case Match_InvalidMemoryIndexed2:
6851 case Match_InvalidMemoryIndexed4:
6852 case Match_InvalidMemoryIndexed8:
6853 case Match_InvalidMemoryIndexed16:
6854 case Match_InvalidCondCode:
6855 case Match_AddSubLSLImm3ShiftLarge:
6856 case Match_AddSubRegExtendSmall:
6857 case Match_AddSubRegExtendLarge:
6858 case Match_AddSubSecondSource:
6859 case Match_LogicalSecondSource:
6860 case Match_AddSubRegShift32:
6861 case Match_AddSubRegShift64:
6862 case Match_InvalidMovImm32Shift:
6863 case Match_InvalidMovImm64Shift:
6864 case Match_InvalidFPImm:
6865 case Match_InvalidMemoryWExtend8:
6866 case Match_InvalidMemoryWExtend16:
6867 case Match_InvalidMemoryWExtend32:
6868 case Match_InvalidMemoryWExtend64:
6869 case Match_InvalidMemoryWExtend128:
6870 case Match_InvalidMemoryXExtend8:
6871 case Match_InvalidMemoryXExtend16:
6872 case Match_InvalidMemoryXExtend32:
6873 case Match_InvalidMemoryXExtend64:
6874 case Match_InvalidMemoryXExtend128:
6875 case Match_InvalidMemoryIndexed1SImm4:
6876 case Match_InvalidMemoryIndexed2SImm4:
6877 case Match_InvalidMemoryIndexed3SImm4:
6878 case Match_InvalidMemoryIndexed4SImm4:
6879 case Match_InvalidMemoryIndexed1SImm6:
6880 case Match_InvalidMemoryIndexed16SImm4:
6881 case Match_InvalidMemoryIndexed32SImm4:
6882 case Match_InvalidMemoryIndexed4SImm7:
6883 case Match_InvalidMemoryIndexed8SImm7:
6884 case Match_InvalidMemoryIndexed16SImm7:
6885 case Match_InvalidMemoryIndexed8UImm5:
6886 case Match_InvalidMemoryIndexed8UImm3:
6887 case Match_InvalidMemoryIndexed4UImm5:
6888 case Match_InvalidMemoryIndexed2UImm5:
6889 case Match_InvalidMemoryIndexed1UImm6:
6890 case Match_InvalidMemoryIndexed2UImm6:
6891 case Match_InvalidMemoryIndexed4UImm6:
6892 case Match_InvalidMemoryIndexed8UImm6:
6893 case Match_InvalidMemoryIndexed16UImm6:
6894 case Match_InvalidMemoryIndexed32UImm8:
6895 case Match_InvalidMemoryIndexedSImm6:
6896 case Match_InvalidMemoryIndexedSImm5:
6897 case Match_InvalidMemoryIndexedSImm8:
6898 case Match_InvalidMemoryIndexedSImm9:
6899 case Match_InvalidMemoryIndexed16SImm9:
6900 case Match_InvalidMemoryIndexed8SImm10:
6901 case Match_InvalidImm0_0:
6902 case Match_InvalidImm0_1:
6903 case Match_InvalidImm0_3:
6904 case Match_InvalidImm0_7:
6905 case Match_InvalidImm0_15:
6906 case Match_InvalidImm0_31:
6907 case Match_InvalidImm0_63:
6908 case Match_InvalidImm0_127:
6909 case Match_InvalidImm0_255:
6910 case Match_InvalidImm0_511:
6911 case Match_InvalidImm0_65535:
6912 case Match_InvalidHinteUImm16:
6913 case Match_InvalidImm1_8:
6914 case Match_InvalidImm1_16:
6915 case Match_InvalidImm1_32:
6916 case Match_InvalidImm1_64:
6917 case Match_InvalidImm1_512:
6918 case Match_InvalidImmM1_62:
6919 case Match_InvalidImmM1_510:
6920 case Match_InvalidImmM255_256:
6921 case Match_InvalidImmM257_254:
6922 case Match_InvalidMemoryIndexedRange2UImm0:
6923 case Match_InvalidMemoryIndexedRange2UImm1:
6924 case Match_InvalidMemoryIndexedRange2UImm2:
6925 case Match_InvalidMemoryIndexedRange2UImm3:
6926 case Match_InvalidMemoryIndexedRange4UImm0:
6927 case Match_InvalidMemoryIndexedRange4UImm1:
6928 case Match_InvalidMemoryIndexedRange4UImm2:
6929 case Match_InvalidSVEAddSubImm8:
6930 case Match_InvalidSVEAddSubImm16:
6931 case Match_InvalidSVEAddSubImm32:
6932 case Match_InvalidSVEAddSubImm64:
6933 case Match_InvalidSVECpyImm8:
6934 case Match_InvalidSVECpyImm16:
6935 case Match_InvalidSVECpyImm32:
6936 case Match_InvalidSVECpyImm64:
6937 case Match_InvalidIndexRange0_0:
6938 case Match_InvalidIndexRange1_1:
6939 case Match_InvalidIndexRange0_15:
6940 case Match_InvalidIndexRange0_7:
6941 case Match_InvalidIndexRange0_3:
6942 case Match_InvalidIndexRange0_1:
6943 case Match_InvalidSVEIndexRange0_63:
6944 case Match_InvalidSVEIndexRange0_31:
6945 case Match_InvalidSVEIndexRange0_15:
6946 case Match_InvalidSVEIndexRange0_7:
6947 case Match_InvalidSVEIndexRange0_3:
6948 case Match_InvalidLabel:
6949 case Match_InvalidComplexRotationEven:
6950 case Match_InvalidComplexRotationOdd:
6951 case Match_InvalidGPR64shifted8:
6952 case Match_InvalidGPR64shifted16:
6953 case Match_InvalidGPR64shifted32:
6954 case Match_InvalidGPR64shifted64:
6955 case Match_InvalidGPR64shifted128:
6956 case Match_InvalidGPR64NoXZRshifted8:
6957 case Match_InvalidGPR64NoXZRshifted16:
6958 case Match_InvalidGPR64NoXZRshifted32:
6959 case Match_InvalidGPR64NoXZRshifted64:
6960 case Match_InvalidGPR64NoXZRshifted128:
6961 case Match_InvalidZPR32UXTW8:
6962 case Match_InvalidZPR32UXTW16:
6963 case Match_InvalidZPR32UXTW32:
6964 case Match_InvalidZPR32UXTW64:
6965 case Match_InvalidZPR32SXTW8:
6966 case Match_InvalidZPR32SXTW16:
6967 case Match_InvalidZPR32SXTW32:
6968 case Match_InvalidZPR32SXTW64:
6969 case Match_InvalidZPR64UXTW8:
6970 case Match_InvalidZPR64SXTW8:
6971 case Match_InvalidZPR64UXTW16:
6972 case Match_InvalidZPR64SXTW16:
6973 case Match_InvalidZPR64UXTW32:
6974 case Match_InvalidZPR64SXTW32:
6975 case Match_InvalidZPR64UXTW64:
6976 case Match_InvalidZPR64SXTW64:
6977 case Match_InvalidZPR32LSL8:
6978 case Match_InvalidZPR32LSL16:
6979 case Match_InvalidZPR32LSL32:
6980 case Match_InvalidZPR32LSL64:
6981 case Match_InvalidZPR64LSL8:
6982 case Match_InvalidZPR64LSL16:
6983 case Match_InvalidZPR64LSL32:
6984 case Match_InvalidZPR64LSL64:
6985 case Match_InvalidZPR0:
6986 case Match_InvalidZPR8:
6987 case Match_InvalidZPR16:
6988 case Match_InvalidZPR32:
6989 case Match_InvalidZPR64:
6990 case Match_InvalidZPR128:
6991 case Match_InvalidZPR_3b8:
6992 case Match_InvalidZPR_3b16:
6993 case Match_InvalidZPR_3b32:
6994 case Match_InvalidZPR_4b8:
6995 case Match_InvalidZPR_4b16:
6996 case Match_InvalidZPR_4b32:
6997 case Match_InvalidZPR_4b64:
6998 case Match_InvalidSVEPPRorPNRAnyReg:
6999 case Match_InvalidSVEPPRorPNRBReg:
7000 case Match_InvalidSVEPredicateAnyReg:
7001 case Match_InvalidSVEPattern:
7002 case Match_InvalidSVEVecLenSpecifier:
7003 case Match_InvalidSVEPredicateBReg:
7004 case Match_InvalidSVEPredicateHReg:
7005 case Match_InvalidSVEPredicateSReg:
7006 case Match_InvalidSVEPredicateDReg:
7007 case Match_InvalidSVEPredicate3bAnyReg:
7008 case Match_InvalidSVEPNPredicateB_p8to15Reg:
7009 case Match_InvalidSVEPNPredicateH_p8to15Reg:
7010 case Match_InvalidSVEPNPredicateS_p8to15Reg:
7011 case Match_InvalidSVEPNPredicateD_p8to15Reg:
7012 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
7013 case Match_InvalidSVEPNPredicateBReg:
7014 case Match_InvalidSVEPNPredicateHReg:
7015 case Match_InvalidSVEPNPredicateSReg:
7016 case Match_InvalidSVEPNPredicateDReg:
7017 case Match_InvalidSVEPredicateListMul2x8:
7018 case Match_InvalidSVEPredicateListMul2x16:
7019 case Match_InvalidSVEPredicateListMul2x32:
7020 case Match_InvalidSVEPredicateListMul2x64:
7021 case Match_InvalidSVEExactFPImmOperandHalfOne:
7022 case Match_InvalidSVEExactFPImmOperandHalfTwo:
7023 case Match_InvalidSVEExactFPImmOperandZeroOne:
7024 case Match_InvalidMatrixTile16:
7025 case Match_InvalidMatrixTile32:
7026 case Match_InvalidMatrixTile64:
7027 case Match_InvalidMatrix:
7028 case Match_InvalidMatrix8:
7029 case Match_InvalidMatrix16:
7030 case Match_InvalidMatrix32:
7031 case Match_InvalidMatrix64:
7032 case Match_InvalidMatrixTileVectorH8:
7033 case Match_InvalidMatrixTileVectorH16:
7034 case Match_InvalidMatrixTileVectorH32:
7035 case Match_InvalidMatrixTileVectorH64:
7036 case Match_InvalidMatrixTileVectorH128:
7037 case Match_InvalidMatrixTileVectorV8:
7038 case Match_InvalidMatrixTileVectorV16:
7039 case Match_InvalidMatrixTileVectorV32:
7040 case Match_InvalidMatrixTileVectorV64:
7041 case Match_InvalidMatrixTileVectorV128:
7042 case Match_InvalidSVCR:
7043 case Match_InvalidMatrixIndexGPR32_12_15:
7044 case Match_InvalidMatrixIndexGPR32_8_11:
7045 case Match_InvalidLookupTable:
7046 case Match_InvalidZPRMul2_Lo8:
7047 case Match_InvalidZPRMul2_Hi8:
7048 case Match_InvalidZPRMul2_Lo16:
7049 case Match_InvalidZPRMul2_Hi16:
7050 case Match_InvalidZPRMul2_Lo32:
7051 case Match_InvalidZPRMul2_Hi32:
7052 case Match_InvalidZPRMul2_Lo64:
7053 case Match_InvalidZPRMul2_Hi64:
7054 case Match_InvalidZPR_K0:
7055 case Match_InvalidSVEVectorList2x8Mul2:
7056 case Match_InvalidSVEVectorList2x16Mul2:
7057 case Match_InvalidSVEVectorList2x32Mul2:
7058 case Match_InvalidSVEVectorList2x64Mul2:
7059 case Match_InvalidSVEVectorList2x128Mul2:
7060 case Match_InvalidSVEVectorList4x8Mul4:
7061 case Match_InvalidSVEVectorList4x16Mul4:
7062 case Match_InvalidSVEVectorList4x32Mul4:
7063 case Match_InvalidSVEVectorList4x64Mul4:
7064 case Match_InvalidSVEVectorList4x128Mul4:
7065 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7066 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7067 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7068 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7069 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7070 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7071 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7072 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7073 case Match_InvalidSVEVectorList3x0_3b:
7074 case Match_InvalidSVEVectorListStrided2x8:
7075 case Match_InvalidSVEVectorListStrided2x16:
7076 case Match_InvalidSVEVectorListStrided2x32:
7077 case Match_InvalidSVEVectorListStrided2x64:
7078 case Match_InvalidSVEVectorListStrided4x8:
7079 case Match_InvalidSVEVectorListStrided4x16:
7080 case Match_InvalidSVEVectorListStrided4x32:
7081 case Match_InvalidSVEVectorListStrided4x64:
7085 return Error(IDLoc,
"too few operands for instruction",
7086 SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
7089 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
7090 if (ErrorLoc == SMLoc())
7092 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7100bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7107 SMLoc Loc = DirectiveID.
getLoc();
7108 if (IDVal ==
".arch")
7109 parseDirectiveArch(Loc);
7110 else if (IDVal ==
".cpu")
7111 parseDirectiveCPU(Loc);
7112 else if (IDVal ==
".tlsdesccall")
7113 parseDirectiveTLSDescCall(Loc,
false);
7114 else if (IDVal ==
".tlsauthdesccall")
7115 parseDirectiveTLSDescCall(Loc,
true);
7116 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7117 parseDirectiveLtorg(Loc);
7118 else if (IDVal ==
".unreq")
7119 parseDirectiveUnreq(Loc);
7120 else if (IDVal ==
".inst")
7121 parseDirectiveInst(Loc);
7122 else if (IDVal ==
".cfi_negate_ra_state")
7123 parseDirectiveCFINegateRAState();
7124 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7125 parseDirectiveCFINegateRAStateWithPC();
7126 else if (IDVal ==
".cfi_set_ra_state")
7127 parseDirectiveCFILLVMSetRAState();
7128 else if (IDVal ==
".cfi_b_key_frame")
7129 parseDirectiveCFIBKeyFrame();
7130 else if (IDVal ==
".cfi_mte_tagged_frame")
7131 parseDirectiveCFIMTETaggedFrame();
7132 else if (IDVal ==
".arch_extension")
7133 parseDirectiveArchExtension(Loc);
7134 else if (IDVal ==
".variant_pcs")
7135 parseDirectiveVariantPCS(Loc);
7138 parseDirectiveLOH(IDVal, Loc);
7141 }
else if (IsCOFF) {
7142 if (IDVal ==
".seh_stackalloc")
7143 parseDirectiveSEHAllocStack(Loc);
7144 else if (IDVal ==
".seh_endprologue")
7145 parseDirectiveSEHPrologEnd(Loc);
7146 else if (IDVal ==
".seh_end_c")
7147 parseDirectiveSEHEndC(Loc);
7148 else if (IDVal ==
".seh_save_r19r20_x")
7149 parseDirectiveSEHSaveR19R20X(Loc);
7150 else if (IDVal ==
".seh_save_fplr")
7151 parseDirectiveSEHSaveFPLR(Loc);
7152 else if (IDVal ==
".seh_save_fplr_x")
7153 parseDirectiveSEHSaveFPLRX(Loc);
7154 else if (IDVal ==
".seh_save_reg")
7155 parseDirectiveSEHSaveReg(Loc);
7156 else if (IDVal ==
".seh_save_reg_x")
7157 parseDirectiveSEHSaveRegX(Loc);
7158 else if (IDVal ==
".seh_save_regp")
7159 parseDirectiveSEHSaveRegP(Loc);
7160 else if (IDVal ==
".seh_save_regp_x")
7161 parseDirectiveSEHSaveRegPX(Loc);
7162 else if (IDVal ==
".seh_save_lrpair")
7163 parseDirectiveSEHSaveLRPair(Loc);
7164 else if (IDVal ==
".seh_save_freg")
7165 parseDirectiveSEHSaveFReg(Loc);
7166 else if (IDVal ==
".seh_save_freg_x")
7167 parseDirectiveSEHSaveFRegX(Loc);
7168 else if (IDVal ==
".seh_save_fregp")
7169 parseDirectiveSEHSaveFRegP(Loc);
7170 else if (IDVal ==
".seh_save_fregp_x")
7171 parseDirectiveSEHSaveFRegPX(Loc);
7172 else if (IDVal ==
".seh_set_fp")
7173 parseDirectiveSEHSetFP(Loc);
7174 else if (IDVal ==
".seh_add_fp")
7175 parseDirectiveSEHAddFP(Loc);
7176 else if (IDVal ==
".seh_nop")
7177 parseDirectiveSEHNop(Loc);
7178 else if (IDVal ==
".seh_save_next")
7179 parseDirectiveSEHSaveNext(Loc);
7180 else if (IDVal ==
".seh_startepilogue")
7181 parseDirectiveSEHEpilogStart(Loc);
7182 else if (IDVal ==
".seh_endepilogue")
7183 parseDirectiveSEHEpilogEnd(Loc);
7184 else if (IDVal ==
".seh_trap_frame")
7185 parseDirectiveSEHTrapFrame(Loc);
7186 else if (IDVal ==
".seh_pushframe")
7187 parseDirectiveSEHMachineFrame(Loc);
7188 else if (IDVal ==
".seh_context")
7189 parseDirectiveSEHContext(Loc);
7190 else if (IDVal ==
".seh_ec_context")
7191 parseDirectiveSEHECContext(Loc);
7192 else if (IDVal ==
".seh_clear_unwound_to_call")
7193 parseDirectiveSEHClearUnwoundToCall(Loc);
7194 else if (IDVal ==
".seh_pac_sign_lr")
7195 parseDirectiveSEHPACSignLR(Loc);
7196 else if (IDVal ==
".seh_save_any_reg")
7197 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7198 else if (IDVal ==
".seh_save_any_reg_p")
7199 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7200 else if (IDVal ==
".seh_save_any_reg_x")
7201 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7202 else if (IDVal ==
".seh_save_any_reg_px")
7203 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7204 else if (IDVal ==
".seh_allocz")
7205 parseDirectiveSEHAllocZ(Loc);
7206 else if (IDVal ==
".seh_save_zreg")
7207 parseDirectiveSEHSaveZReg(Loc);
7208 else if (IDVal ==
".seh_save_preg")
7209 parseDirectiveSEHSavePReg(Loc);
7213 if (IDVal ==
".aeabi_subsection")
7214 parseDirectiveAeabiSubSectionHeader(Loc);
7215 else if (IDVal ==
".aeabi_attribute")
7216 parseDirectiveAeabiAArch64Attr(Loc);
7229 if (!NoCrypto && Crypto) {
7232 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7233 ArchInfo == AArch64::ARMV8_3A) {
7237 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7238 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7239 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7240 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7241 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7242 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7248 }
else if (NoCrypto) {
7251 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7252 ArchInfo == AArch64::ARMV8_3A) {
7253 RequestedExtensions.
push_back(
"nosha2");
7256 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7257 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7258 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7259 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7260 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7261 ArchInfo == AArch64::ARMV9_4A) {
7263 RequestedExtensions.
push_back(
"nosha3");
7264 RequestedExtensions.
push_back(
"nosha2");
7276bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7277 SMLoc CurLoc = getLoc();
7279 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7280 StringRef Arch, ExtensionString;
7281 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7285 return Error(CurLoc,
"unknown arch name");
7291 std::vector<StringRef> AArch64Features;
7292 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7295 MCSubtargetInfo &STI = copySTI();
7296 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7298 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7301 if (!ExtensionString.
empty())
7302 ExtensionString.
split(RequestedExtensions,
'+');
7307 for (
auto Name : RequestedExtensions) {
7311 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7318 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7326 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7327 setAvailableFeatures(Features);
7329 getTargetStreamer().emitDirectiveArch(Name);
7335bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7336 SMLoc ExtLoc = getLoc();
7338 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7343 bool EnableFeature =
true;
7344 StringRef
Name = FullName;
7345 if (
Name.starts_with_insensitive(
"no")) {
7346 EnableFeature =
false;
7355 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7357 MCSubtargetInfo &STI = copySTI();
7362 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7363 setAvailableFeatures(Features);
7365 getTargetStreamer().emitDirectiveArchExtension(FullName);
7371bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7372 SMLoc CurLoc = getLoc();
7374 StringRef CPU, ExtensionString;
7375 std::tie(CPU, ExtensionString) =
7376 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7382 if (!ExtensionString.
empty())
7383 ExtensionString.
split(RequestedExtensions,
'+');
7387 Error(CurLoc,
"unknown CPU name");
7392 MCSubtargetInfo &STI = copySTI();
7396 for (
auto Name : RequestedExtensions) {
7400 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7407 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7415 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7416 setAvailableFeatures(Features);
7422bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7424 return Error(Loc,
"expected expression following '.inst' directive");
7426 auto parseOp = [&]() ->
bool {
7428 const MCExpr *Expr =
nullptr;
7429 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7432 if (check(!
Value, L,
"expected constant expression"))
7434 getTargetStreamer().emitInst(
Value->getValue());
7438 return parseMany(parseOp);
7444bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L,
bool IsAuth) {
7446 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7457 Inst.
setOpcode(IsAuth ? AArch64::TLSAUTHDESCCALL : AArch64::TLSDESCCALL);
7460 getParser().getStreamer().emitInstruction(Inst, getSTI());
7466bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7470 return TokError(
"expected an identifier or a number in directive");
7473 int64_t
Id = getTok().getIntVal();
7475 return TokError(
"invalid numeric identifier in directive");
7478 StringRef
Name = getTok().getIdentifier();
7484 return TokError(
"invalid identifier in directive");
7492 assert(NbArgs != -1 &&
"Invalid number of arguments");
7495 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7497 if (getParser().parseIdentifier(Name))
7498 return TokError(
"expected identifier in directive");
7501 if (Idx + 1 == NbArgs)
7509 getStreamer().emitLOHDirective(Kind, Args);
7515bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7518 getTargetStreamer().emitCurrentConstantPool();
7524bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7526 SMLoc SRegLoc = getLoc();
7527 RegKind RegisterKind = RegKind::Scalar;
7529 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7533 RegisterKind = RegKind::NeonVector;
7534 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7540 return Error(SRegLoc,
"vector register without type specifier expected");
7545 RegisterKind = RegKind::SVEDataVector;
7547 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7553 return Error(SRegLoc,
7554 "sve vector register without type specifier expected");
7559 RegisterKind = RegKind::SVEPredicateVector;
7560 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7566 return Error(SRegLoc,
7567 "sve predicate register without type specifier expected");
7571 return Error(SRegLoc,
"register name or alias expected");
7577 auto pair = std::make_pair(RegisterKind, RegNum);
7578 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7579 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7586bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7588 return TokError(
"unexpected input in .unreq directive.");
7589 RegisterReqs.
erase(getTok().getIdentifier().lower());
7594bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7597 getStreamer().emitCFINegateRAState();
7601bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7604 getStreamer().emitCFINegateRAStateWithPC();
7611bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7613 if (getParser().parseAbsoluteExpression(State))
7618 SMLoc ExprLoc = getLoc();
7619 if (getParser().parseExpression(Expr))
7624 getStreamer().emitCFILLVMSetRAState(
7625 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7627 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7631 "expected an integer offset or a symbol for .cfi_set_ra_state");
7638bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7641 getStreamer().emitCFIBKeyFrame();
7647bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7650 getStreamer().emitCFIMTETaggedFrame();
7656bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7658 if (getParser().parseIdentifier(Name))
7659 return TokError(
"expected symbol name");
7662 getTargetStreamer().emitDirectiveVariantPCS(
7669bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7671 if (parseImmExpr(
Size))
7673 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7679bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7680 getTargetStreamer().emitARM64WinCFIPrologEnd();
7684bool AArch64AsmParser::parseDirectiveSEHEndC(SMLoc L) {
7685 getTargetStreamer().emitARM64WinCFIEndC();
7691bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7693 if (parseImmExpr(
Offset))
7695 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7701bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7703 if (parseImmExpr(
Offset))
7705 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7711bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7713 if (parseImmExpr(
Offset))
7715 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7721bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7724 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7725 parseComma() || parseImmExpr(
Offset))
7727 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7733bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7736 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7737 parseComma() || parseImmExpr(
Offset))
7739 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7745bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7748 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7749 parseComma() || parseImmExpr(
Offset))
7751 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7757bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7760 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7761 parseComma() || parseImmExpr(
Offset))
7763 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7769bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7773 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7774 parseComma() || parseImmExpr(
Offset))
7776 if (check(((
Reg - 19) % 2 != 0), L,
7777 "expected register with even offset from x19"))
7779 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7785bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7788 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7789 parseComma() || parseImmExpr(
Offset))
7791 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7797bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7800 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7801 parseComma() || parseImmExpr(
Offset))
7803 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7809bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7812 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7813 parseComma() || parseImmExpr(
Offset))
7815 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7821bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7824 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7825 parseComma() || parseImmExpr(
Offset))
7827 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7833bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7834 getTargetStreamer().emitARM64WinCFISetFP();
7840bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7842 if (parseImmExpr(
Size))
7844 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7850bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7851 getTargetStreamer().emitARM64WinCFINop();
7857bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7858 getTargetStreamer().emitARM64WinCFISaveNext();
7864bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7865 getTargetStreamer().emitARM64WinCFIEpilogStart();
7871bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7872 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7878bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7879 getTargetStreamer().emitARM64WinCFITrapFrame();
7885bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7886 getTargetStreamer().emitARM64WinCFIMachineFrame();
7892bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7893 getTargetStreamer().emitARM64WinCFIContext();
7899bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7900 getTargetStreamer().emitARM64WinCFIECContext();
7906bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7907 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7913bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7914 getTargetStreamer().emitARM64WinCFIPACSignLR();
7923bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7928 if (check(parseRegister(
Reg, Start,
End), getLoc(),
"expected register") ||
7929 parseComma() || parseImmExpr(
Offset))
7932 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7933 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7934 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7935 return Error(L,
"invalid save_any_reg offset");
7936 unsigned EncodedReg;
7937 if (
Reg == AArch64::FP)
7939 else if (
Reg == AArch64::LR)
7942 EncodedReg =
Reg - AArch64::X0;
7944 if (
Reg == AArch64::LR)
7945 return Error(Start,
"lr cannot be paired with another register");
7947 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7949 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7952 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7954 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7956 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7957 unsigned EncodedReg =
Reg - AArch64::D0;
7958 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7959 return Error(L,
"invalid save_any_reg offset");
7961 if (
Reg == AArch64::D31)
7962 return Error(Start,
"d31 cannot be paired with another register");
7964 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7966 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7969 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7971 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7973 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7974 unsigned EncodedReg =
Reg - AArch64::Q0;
7976 return Error(L,
"invalid save_any_reg offset");
7978 if (
Reg == AArch64::Q31)
7979 return Error(Start,
"q31 cannot be paired with another register");
7981 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7983 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7986 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7988 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7991 return Error(Start,
"save_any_reg register must be x, q or d register");
7998bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
8000 if (parseImmExpr(
Offset))
8002 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
8008bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
8013 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8016 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
8017 "expected register in range z8 to z23"))
8019 if (parseComma() || parseImmExpr(
Offset))
8021 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
8027bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
8032 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
8035 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
8036 "expected register in range p4 to p15"))
8038 if (parseComma() || parseImmExpr(
Offset))
8040 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
8044bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8050 MCAsmParser &Parser = getParser();
8053 StringRef SubsectionName;
8064 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8065 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8070 if (SubsectionExists) {
8071 getTargetStreamer().emitAttributesSubsection(
8074 SubsectionExists->IsOptional),
8076 SubsectionExists->ParameterType));
8082 "Could not switch to subsection '" + SubsectionName +
8083 "' using subsection name, subsection has not been defined");
8106 if (SubsectionExists) {
8107 if (IsOptional != SubsectionExists->IsOptional) {
8109 "optionality mismatch! subsection '" + SubsectionName +
8110 "' already exists with optionality defined as '" +
8112 SubsectionExists->IsOptional) +
8120 "optionality parameter not found, expected required|optional");
8127 "aeabi_feature_and_bits must be marked as optional");
8134 "aeabi_pauthabi must be marked as required");
8154 if (SubsectionExists) {
8155 if (
Type != SubsectionExists->ParameterType) {
8157 "type mismatch! subsection '" + SubsectionName +
8158 "' already exists with type defined as '" +
8160 SubsectionExists->ParameterType) +
8168 "type parameter not found, expected uleb128|ntbs");
8176 SubsectionName +
" must be marked as ULEB128");
8185 "attributes subsection header directive");
8189 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8194bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8198 MCAsmParser &Parser = getParser();
8200 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8201 getTargetStreamer().getActiveAttributesSubsection();
8202 if (
nullptr == ActiveSubsection) {
8204 "no active subsection, build attribute can not be added");
8207 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8208 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8216 ActiveSubsectionName)
8219 StringRef TagStr =
"";
8222 Tag = getTok().getIntVal();
8225 switch (ActiveSubsectionID) {
8230 "' \nExcept for public subsections, "
8231 "tags have to be an unsigned int.");
8238 TagStr +
"' for subsection '" +
8239 ActiveSubsectionName +
"'");
8247 TagStr +
"' for subsection '" +
8248 ActiveSubsectionName +
"'");
8266 unsigned ValueInt = unsigned(-1);
8267 std::string ValueStr =
"";
8272 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8275 ValueInt = getTok().getIntVal();
8280 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8288 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8299 if (0 != ValueInt && 1 != ValueInt) {
8301 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8302 "' options are 0|1");
8311 "unexpected token for AArch64 build attributes tag and value "
8312 "attribute directive");
8316 if (
unsigned(-1) != ValueInt) {
8317 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8319 if (
"" != ValueStr) {
8320 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8326bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8327 SMLoc Loc = getLoc();
8329 return TokError(
"expected '%' relocation specifier");
8330 StringRef
Identifier = getParser().getTok().getIdentifier();
8333 return TokError(
"invalid relocation specifier");
8339 const MCExpr *SubExpr;
8340 if (getParser().parseParenExpression(SubExpr,
E))
8347bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8350 return parseExprWithSpecifier(Res, EndLoc);
8352 if (getParser().parseExpression(Res))
8354 MCAsmParser &Parser = getParser();
8358 return Error(getLoc(),
"expected relocation specifier");
8361 SMLoc Loc = getLoc();
8363 if (Identifier ==
"auth")
8364 return parseAuthExpr(Res, EndLoc);
8368 if (Identifier ==
"got")
8372 return Error(Loc,
"invalid relocation specifier");
8377 return Error(Loc,
"@ specifier only allowed after a symbol");
8380 std::optional<MCBinaryExpr::Opcode> Opcode;
8388 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8399bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8400 MCAsmParser &Parser = getParser();
8402 AsmToken Tok = Parser.
getTok();
8409 return TokError(
"expected key name");
8414 return TokError(
"invalid key '" + KeyStr +
"'");
8421 return TokError(
"expected integer discriminator");
8425 return TokError(
"integer discriminator " + Twine(Discriminator) +
8426 " out of range [0, 0xFFFF]");
8429 bool UseAddressDiversity =
false;
8434 return TokError(
"expected 'addr'");
8435 UseAddressDiversity =
true;
8444 UseAddressDiversity, Ctx, Res->
getLoc());
8448bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8457 ELFSpec = AE->getSpecifier();
8458 Expr = AE->getSubExpr();
8498#define GET_REGISTER_MATCHER
8499#define GET_SUBTARGET_FEATURE_NAME
8500#define GET_MATCHER_IMPLEMENTATION
8501#define GET_MNEMONIC_SPELL_CHECKER
8502#include "AArch64GenAsmMatcher.inc"
8508 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8510 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8512 return Match_InvalidOperand;
8515 return Match_InvalidOperand;
8516 if (CE->getValue() == ExpectedVal)
8517 return Match_Success;
8518 return Match_InvalidOperand;
8523 return Match_InvalidOperand;
8529 if (
Op.isTokenEqual(
"za"))
8530 return Match_Success;
8531 return Match_InvalidOperand;
8537#define MATCH_HASH(N) \
8538 case MCK__HASH_##N: \
8539 return MatchesOpImmediate(N);
8565#define MATCH_HASH_MINUS(N) \
8566 case MCK__HASH__MINUS_##N: \
8567 return MatchesOpImmediate(-N);
8571#undef MATCH_HASH_MINUS
8580 return Error(S,
"expected register");
8582 MCRegister FirstReg;
8583 ParseStatus Res = tryParseScalarRegister(FirstReg);
8585 return Error(S,
"expected first even register of a consecutive same-size "
8586 "even/odd register pair");
8588 const MCRegisterClass &WRegClass =
8589 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8590 const MCRegisterClass &XRegClass =
8591 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8593 bool isXReg = XRegClass.
contains(FirstReg),
8594 isWReg = WRegClass.
contains(FirstReg);
8595 if (!isXReg && !isWReg)
8596 return Error(S,
"expected first even register of a consecutive same-size "
8597 "even/odd register pair");
8599 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8602 if (FirstEncoding & 0x1)
8603 return Error(S,
"expected first even register of a consecutive same-size "
8604 "even/odd register pair");
8607 return Error(getLoc(),
"expected comma");
8612 MCRegister SecondReg;
8613 Res = tryParseScalarRegister(SecondReg);
8615 return Error(
E,
"expected second odd register of a consecutive same-size "
8616 "even/odd register pair");
8619 (isXReg && !XRegClass.
contains(SecondReg)) ||
8620 (isWReg && !WRegClass.
contains(SecondReg)))
8621 return Error(
E,
"expected second odd register of a consecutive same-size "
8622 "even/odd register pair");
8627 FirstReg, AArch64::sube64,
8628 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8631 FirstReg, AArch64::sube32,
8632 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8635 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8641template <
bool ParseShiftExtend,
bool ParseSuffix>
8643 const SMLoc S = getLoc();
8649 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8654 if (ParseSuffix &&
Kind.empty())
8661 unsigned ElementWidth = KindRes->second;
8665 Operands.push_back(AArch64Operand::CreateVectorReg(
8666 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8668 ParseStatus Res = tryParseVectorIndex(
Operands);
8679 Res = tryParseOptionalShiftExtend(ExtOpnd);
8683 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8684 Operands.push_back(AArch64Operand::CreateVectorReg(
8685 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8686 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8687 Ext->hasShiftExtendAmount()));
8693 SMLoc
SS = getLoc();
8694 const AsmToken &TokE = getTok();
8699 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8704 int64_t Pattern = Pat->Encoding;
8705 assert(Pattern >= 0 && Pattern < 32);
8717 SMLoc
SS = getLoc();
8718 const AsmToken &TokE = getTok();
8720 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8726 Pattern = Pat->Encoding;
8727 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8737 SMLoc
SS = getLoc();
8740 if (!tryParseScalarRegister(XReg).isSuccess())
8746 XReg, AArch64::x8sub_0,
8747 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8750 "expected an even-numbered x-register in the range [x0,x22]");
8753 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8767 if (getParser().parseExpression(ImmF))
8777 SMLoc
E = getTok().getLoc();
8779 if (getParser().parseExpression(ImmL))
8786 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