73 SVEPredicateAsCounter,
79enum class MatrixKind { Array, Tile, Row, Col };
81enum RegConstraintEqualityTy {
92 StringMap<std::pair<RegKind, MCRegister>> RegisterReqs;
96 static PrefixInfo CreateFromInst(
const MCInst &Inst, uint64_t TSFlags) {
99 case AArch64::MOVPRFX_ZZ:
103 case AArch64::MOVPRFX_ZPmZ_B:
104 case AArch64::MOVPRFX_ZPmZ_H:
105 case AArch64::MOVPRFX_ZPmZ_S:
106 case AArch64::MOVPRFX_ZPmZ_D:
111 "No destructive element size set for movprfx");
115 case AArch64::MOVPRFX_ZPzZ_B:
116 case AArch64::MOVPRFX_ZPzZ_H:
117 case AArch64::MOVPRFX_ZPzZ_S:
118 case AArch64::MOVPRFX_ZPzZ_D:
123 "No destructive element size set for movprfx");
134 PrefixInfo() =
default;
135 bool isActive()
const {
return Active; }
137 unsigned getElementSize()
const {
141 MCRegister getDstReg()
const {
return Dst; }
142 MCRegister getPgReg()
const {
149 bool Predicated =
false;
150 unsigned ElementSize;
155 AArch64TargetStreamer &getTargetStreamer() {
156 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
157 return static_cast<AArch64TargetStreamer &
>(TS);
160 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
162 bool parseSysAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
163 bool parseSyslAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
164 bool parseSyspAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
165 void createSysAlias(uint16_t Encoding,
OperandVector &Operands, SMLoc S);
167 std::string &Suggestion);
169 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
171 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
174 bool parseOptionalVGOperand(
OperandVector &Operands, StringRef &VecGroup);
177 bool invertCondCode);
178 bool parseImmExpr(int64_t &Out);
180 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool showMatchError(SMLoc Loc,
unsigned ErrCode, uint64_t ErrorInfo,
186 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
187 bool parseDataExpr(
const MCExpr *&Res)
override;
188 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
190 bool parseDirectiveArch(SMLoc L);
191 bool parseDirectiveArchExtension(SMLoc L);
192 bool parseDirectiveCPU(SMLoc L);
193 bool parseDirectiveInst(SMLoc L);
195 bool parseDirectiveTLSDescCall(SMLoc L);
197 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
198 bool parseDirectiveLtorg(SMLoc L);
200 bool parseDirectiveReq(StringRef Name, SMLoc L);
201 bool parseDirectiveUnreq(SMLoc L);
202 bool parseDirectiveCFINegateRAState();
203 bool parseDirectiveCFINegateRAStateWithPC();
204 bool parseDirectiveCFILLVMSetRAState();
205 bool parseDirectiveCFIBKeyFrame();
206 bool parseDirectiveCFIMTETaggedFrame();
208 bool parseDirectiveVariantPCS(SMLoc L);
210 bool parseDirectiveSEHAllocStack(SMLoc L);
211 bool parseDirectiveSEHPrologEnd(SMLoc L);
212 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
213 bool parseDirectiveSEHSaveFPLR(SMLoc L);
214 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
215 bool parseDirectiveSEHSaveReg(SMLoc L);
216 bool parseDirectiveSEHSaveRegX(SMLoc L);
217 bool parseDirectiveSEHSaveRegP(SMLoc L);
218 bool parseDirectiveSEHSaveRegPX(SMLoc L);
219 bool parseDirectiveSEHSaveLRPair(SMLoc L);
220 bool parseDirectiveSEHSaveFReg(SMLoc L);
221 bool parseDirectiveSEHSaveFRegX(SMLoc L);
222 bool parseDirectiveSEHSaveFRegP(SMLoc L);
223 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
224 bool parseDirectiveSEHSetFP(SMLoc L);
225 bool parseDirectiveSEHAddFP(SMLoc L);
226 bool parseDirectiveSEHNop(SMLoc L);
227 bool parseDirectiveSEHSaveNext(SMLoc L);
228 bool parseDirectiveSEHEpilogStart(SMLoc L);
229 bool parseDirectiveSEHEpilogEnd(SMLoc L);
230 bool parseDirectiveSEHTrapFrame(SMLoc L);
231 bool parseDirectiveSEHMachineFrame(SMLoc L);
232 bool parseDirectiveSEHContext(SMLoc L);
233 bool parseDirectiveSEHECContext(SMLoc L);
234 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
235 bool parseDirectiveSEHPACSignLR(SMLoc L);
236 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
237 bool parseDirectiveSEHAllocZ(SMLoc L);
238 bool parseDirectiveSEHSaveZReg(SMLoc L);
239 bool parseDirectiveSEHSavePReg(SMLoc L);
240 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
241 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
243 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
244 SmallVectorImpl<SMLoc> &Loc);
245 unsigned getNumRegsForRegKind(RegKind K);
246 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
249 bool MatchingInlineAsm)
override;
253#define GET_ASSEMBLER_HEADER
254#include "AArch64GenAsmMatcher.inc"
268 template <
bool IsSVEPrefetch = false>
274 template <
bool AddFPZeroAsLiteral>
282 template <
bool ParseShiftExtend,
283 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
286 template <
bool ParseShiftExtend,
bool ParseSuffix>
288 template <RegKind RK>
291 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
292 template <RegKind VectorKind>
294 bool ExpectMatch =
false);
303 enum AArch64MatchResultTy {
304 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
305#define GET_OPERAND_DIAGNOSTIC_TYPES
306#include "AArch64GenAsmMatcher.inc"
309 bool IsWindowsArm64EC;
311 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
312 const MCInstrInfo &MII)
313 : MCTargetAsmParser(STI, MII) {
317 MCStreamer &S = getParser().getStreamer();
319 new AArch64TargetStreamer(S);
331 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
334 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
335 const MCParsedAsmOperand &Op2)
const override;
336 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
338 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
339 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
340 SMLoc &EndLoc)
override;
341 bool ParseDirective(AsmToken DirectiveID)
override;
342 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
343 unsigned Kind)
override;
375 SMLoc StartLoc, EndLoc;
384 struct ShiftExtendOp {
387 bool HasExplicitAmount;
397 RegConstraintEqualityTy EqualityTy;
413 ShiftExtendOp ShiftExtend;
418 unsigned ElementWidth;
422 struct MatrixTileListOp {
423 unsigned RegMask = 0;
426 struct VectorListOp {
430 unsigned NumElements;
431 unsigned ElementWidth;
432 RegKind RegisterKind;
435 struct VectorIndexOp {
443 struct ShiftedImmOp {
445 unsigned ShiftAmount;
474 uint32_t PStateField;
487 struct TIndexHintOp {
496 unsigned PStateField;
502 struct MatrixRegOp MatrixReg;
503 struct MatrixTileListOp MatrixTileList;
504 struct VectorListOp VectorList;
505 struct VectorIndexOp VectorIndex;
507 struct ShiftedImmOp ShiftedImm;
508 struct ImmRangeOp ImmRange;
510 struct FPImmOp FPImm;
512 struct SysRegOp SysReg;
513 struct SysCRImmOp SysCRImm;
515 struct TIndexHintOp TIndexHint;
516 struct ShiftExtendOp ShiftExtend;
525 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
527 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
529 StartLoc =
o.StartLoc;
539 ShiftedImm =
o.ShiftedImm;
542 ImmRange =
o.ImmRange;
556 case k_MatrixRegister:
557 MatrixReg =
o.MatrixReg;
559 case k_MatrixTileList:
560 MatrixTileList =
o.MatrixTileList;
563 VectorList =
o.VectorList;
566 VectorIndex =
o.VectorIndex;
572 SysCRImm =
o.SysCRImm;
578 TIndexHint =
o.TIndexHint;
581 ShiftExtend =
o.ShiftExtend;
590 SMLoc getStartLoc()
const override {
return StartLoc; }
592 SMLoc getEndLoc()
const override {
return EndLoc; }
595 assert(Kind == k_Token &&
"Invalid access!");
596 return StringRef(Tok.Data, Tok.Length);
599 bool isTokenSuffix()
const {
600 assert(Kind == k_Token &&
"Invalid access!");
604 const MCExpr *
getImm()
const {
605 assert(Kind == k_Immediate &&
"Invalid access!");
609 const MCExpr *getShiftedImmVal()
const {
610 assert(Kind == k_ShiftedImm &&
"Invalid access!");
611 return ShiftedImm.Val;
614 unsigned getShiftedImmShift()
const {
615 assert(Kind == k_ShiftedImm &&
"Invalid access!");
616 return ShiftedImm.ShiftAmount;
619 unsigned getFirstImmVal()
const {
620 assert(Kind == k_ImmRange &&
"Invalid access!");
621 return ImmRange.First;
624 unsigned getLastImmVal()
const {
625 assert(Kind == k_ImmRange &&
"Invalid access!");
626 return ImmRange.Last;
630 assert(Kind == k_CondCode &&
"Invalid access!");
635 assert (Kind == k_FPImm &&
"Invalid access!");
636 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
639 bool getFPImmIsExact()
const {
640 assert (Kind == k_FPImm &&
"Invalid access!");
641 return FPImm.IsExact;
644 unsigned getBarrier()
const {
645 assert(Kind == k_Barrier &&
"Invalid access!");
649 StringRef getBarrierName()
const {
650 assert(Kind == k_Barrier &&
"Invalid access!");
654 bool getBarriernXSModifier()
const {
655 assert(Kind == k_Barrier &&
"Invalid access!");
659 MCRegister
getReg()
const override {
660 assert(Kind == k_Register &&
"Invalid access!");
664 MCRegister getMatrixReg()
const {
665 assert(Kind == k_MatrixRegister &&
"Invalid access!");
666 return MatrixReg.Reg;
669 unsigned getMatrixElementWidth()
const {
670 assert(Kind == k_MatrixRegister &&
"Invalid access!");
671 return MatrixReg.ElementWidth;
674 MatrixKind getMatrixKind()
const {
675 assert(Kind == k_MatrixRegister &&
"Invalid access!");
676 return MatrixReg.Kind;
679 unsigned getMatrixTileListRegMask()
const {
680 assert(isMatrixTileList() &&
"Invalid access!");
681 return MatrixTileList.RegMask;
684 RegConstraintEqualityTy getRegEqualityTy()
const {
685 assert(Kind == k_Register &&
"Invalid access!");
686 return Reg.EqualityTy;
689 MCRegister getVectorListStart()
const {
690 assert(Kind == k_VectorList &&
"Invalid access!");
691 return VectorList.Reg;
694 unsigned getVectorListCount()
const {
695 assert(Kind == k_VectorList &&
"Invalid access!");
696 return VectorList.Count;
699 unsigned getVectorListStride()
const {
700 assert(Kind == k_VectorList &&
"Invalid access!");
701 return VectorList.Stride;
704 int getVectorIndex()
const {
705 assert(Kind == k_VectorIndex &&
"Invalid access!");
706 return VectorIndex.Val;
709 StringRef getSysReg()
const {
710 assert(Kind == k_SysReg &&
"Invalid access!");
711 return StringRef(SysReg.Data, SysReg.Length);
714 unsigned getSysCR()
const {
715 assert(Kind == k_SysCR &&
"Invalid access!");
719 unsigned getPrefetch()
const {
720 assert(Kind == k_Prefetch &&
"Invalid access!");
724 unsigned getTIndexHint()
const {
725 assert(Kind == k_TIndexHint &&
"Invalid access!");
726 return TIndexHint.Val;
729 StringRef getTIndexHintName()
const {
730 assert(Kind == k_TIndexHint &&
"Invalid access!");
731 return StringRef(TIndexHint.Data, TIndexHint.Length);
734 StringRef getSVCR()
const {
735 assert(Kind == k_SVCR &&
"Invalid access!");
736 return StringRef(SVCR.Data, SVCR.Length);
739 StringRef getPrefetchName()
const {
740 assert(Kind == k_Prefetch &&
"Invalid access!");
745 if (Kind == k_ShiftExtend)
746 return ShiftExtend.Type;
747 if (Kind == k_Register)
748 return Reg.ShiftExtend.Type;
752 unsigned getShiftExtendAmount()
const {
753 if (Kind == k_ShiftExtend)
754 return ShiftExtend.Amount;
755 if (Kind == k_Register)
756 return Reg.ShiftExtend.Amount;
760 bool hasShiftExtendAmount()
const {
761 if (Kind == k_ShiftExtend)
762 return ShiftExtend.HasExplicitAmount;
763 if (Kind == k_Register)
764 return Reg.ShiftExtend.HasExplicitAmount;
768 bool isImm()
const override {
return Kind == k_Immediate; }
769 bool isMem()
const override {
return false; }
771 bool isUImm6()
const {
778 return (Val >= 0 && Val < 64);
781 template <
int W
idth>
bool isSImm()
const {
782 return bool(isSImmScaled<Width, 1>());
785 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
786 return isImmScaled<Bits, Scale>(
true);
789 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
790 DiagnosticPredicate isUImmScaled()
const {
791 if (IsRange && isImmRange() &&
792 (getLastImmVal() != getFirstImmVal() +
Offset))
795 return isImmScaled<Bits, Scale, IsRange>(
false);
798 template <
int Bits,
int Scale,
bool IsRange = false>
799 DiagnosticPredicate isImmScaled(
bool Signed)
const {
800 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
801 (isImmRange() && !IsRange))
806 Val = getFirstImmVal();
814 int64_t MinVal, MaxVal;
816 int64_t Shift =
Bits - 1;
817 MinVal = (int64_t(1) << Shift) * -Scale;
818 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
821 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
824 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
830 DiagnosticPredicate isSVEPattern()
const {
837 if (Val >= 0 && Val < 32)
842 DiagnosticPredicate isSVEVecLenSpecifier()
const {
849 if (Val >= 0 && Val <= 1)
854 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
858 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
887 template <
int Scale>
bool isUImm12Offset()
const {
893 return isSymbolicUImm12Offset(
getImm());
896 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
899 template <
int N,
int M>
900 bool isImmInRange()
const {
907 return (Val >=
N && Val <= M);
910 bool isHinteUImm16()
const {
917 return Val >= 0 && Val <= 65535 &&
918 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
923 template <
typename T>
924 bool isLogicalImm()
const {
933 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
941 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
943 bool isImmRange()
const {
return Kind == k_ImmRange; }
948 template <
unsigned W
idth>
949 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
950 if (isShiftedImm() && Width == getShiftedImmShift())
952 return std::make_pair(
CE->getValue(), Width);
956 int64_t Val =
CE->getValue();
957 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
958 return std::make_pair(Val >> Width, Width);
960 return std::make_pair(Val, 0u);
966 bool isAddSubImm()
const {
967 if (!isShiftedImm() && !isImm())
973 if (isShiftedImm()) {
974 unsigned Shift = ShiftedImm.ShiftAmount;
975 Expr = ShiftedImm.Val;
976 if (Shift != 0 && Shift != 12)
985 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1001 if (
auto ShiftedVal = getShiftedVal<12>())
1002 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1009 bool isAddSubImmNeg()
const {
1010 if (!isShiftedImm() && !isImm())
1014 if (
auto ShiftedVal = getShiftedVal<12>())
1015 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1025 template <
typename T>
1026 DiagnosticPredicate isSVECpyImm()
const {
1030 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1031 std::is_same<int8_t, T>::value;
1032 if (
auto ShiftedImm = getShiftedVal<8>())
1033 if (!(IsByte && ShiftedImm->second) &&
1035 << ShiftedImm->second))
1044 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1048 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1049 std::is_same<int8_t, T>::value;
1050 if (
auto ShiftedImm = getShiftedVal<8>())
1051 if (!(IsByte && ShiftedImm->second) &&
1053 << ShiftedImm->second))
1059 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1060 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1067 bool isSIMDImmType10()
const {
1077 bool isBranchTarget()
const {
1086 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1087 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1097 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1107 bool isMovWSymbolG3()
const {
1111 bool isMovWSymbolG2()
const {
1118 bool isMovWSymbolG1()
const {
1126 bool isMovWSymbolG0()
const {
1134 template<
int RegW
idth,
int Shift>
1135 bool isMOVZMovAlias()
const {
1136 if (!isImm())
return false;
1140 uint64_t
Value =
CE->getValue();
1149 template<
int RegW
idth,
int Shift>
1150 bool isMOVNMovAlias()
const {
1151 if (!isImm())
return false;
1154 if (!CE)
return false;
1155 uint64_t
Value =
CE->getValue();
1160 bool isFPImm()
const {
1161 return Kind == k_FPImm &&
1165 bool isBarrier()
const {
1166 return Kind == k_Barrier && !getBarriernXSModifier();
1168 bool isBarriernXS()
const {
1169 return Kind == k_Barrier && getBarriernXSModifier();
1171 bool isSysReg()
const {
return Kind == k_SysReg; }
1173 bool isMRSSystemRegister()
const {
1174 if (!isSysReg())
return false;
1176 return SysReg.MRSReg != -1U;
1179 bool isMSRSystemRegister()
const {
1180 if (!isSysReg())
return false;
1181 return SysReg.MSRReg != -1U;
1184 bool isSystemPStateFieldWithImm0_1()
const {
1185 if (!isSysReg())
return false;
1186 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1189 bool isSystemPStateFieldWithImm0_15()
const {
1192 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1195 bool isSVCR()
const {
1198 return SVCR.PStateField != -1U;
1201 bool isReg()
const override {
1202 return Kind == k_Register;
1205 bool isVectorList()
const {
return Kind == k_VectorList; }
1207 bool isScalarReg()
const {
1208 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1211 bool isNeonVectorReg()
const {
1212 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1215 bool isNeonVectorRegLo()
const {
1216 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1217 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1218 .contains(
Reg.Reg) ||
1219 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1220 .contains(
Reg.Reg));
1223 bool isNeonVectorReg0to7()
const {
1224 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1225 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1226 .contains(
Reg.Reg));
1229 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1230 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1232 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1235 case AArch64::PPRRegClassID:
1236 case AArch64::PPR_3bRegClassID:
1237 case AArch64::PPR_p8to15RegClassID:
1238 case AArch64::PNRRegClassID:
1239 case AArch64::PNR_p8to15RegClassID:
1240 case AArch64::PPRorPNRRegClassID:
1241 RK = RegKind::SVEPredicateAsCounter;
1247 return (Kind == k_Register &&
Reg.Kind == RK) &&
1248 getAArch64MCRegisterClass(Class).contains(
getReg());
1251 template <
unsigned Class>
bool isSVEVectorReg()
const {
1254 case AArch64::ZPRRegClassID:
1255 case AArch64::ZPR_3bRegClassID:
1256 case AArch64::ZPR_4bRegClassID:
1257 case AArch64::ZPRMul2_LoRegClassID:
1258 case AArch64::ZPRMul2_HiRegClassID:
1259 case AArch64::ZPR_KRegClassID:
1260 RK = RegKind::SVEDataVector;
1262 case AArch64::PPRRegClassID:
1263 case AArch64::PPR_3bRegClassID:
1264 case AArch64::PPR_p8to15RegClassID:
1265 case AArch64::PNRRegClassID:
1266 case AArch64::PNR_p8to15RegClassID:
1267 case AArch64::PPRorPNRRegClassID:
1268 RK = RegKind::SVEPredicateVector;
1274 return (Kind == k_Register &&
Reg.Kind == RK) &&
1275 getAArch64MCRegisterClass(Class).contains(
getReg());
1278 template <
unsigned Class>
bool isFPRasZPR()
const {
1279 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1280 getAArch64MCRegisterClass(Class).contains(
getReg());
1283 template <
int ElementW
idth,
unsigned Class>
1284 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1285 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1288 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1294 template <
int ElementW
idth,
unsigned Class>
1295 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1296 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1297 Reg.Kind != RegKind::SVEPredicateVector))
1300 if ((isSVEPredicateAsCounterReg<Class>() ||
1301 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1302 Reg.ElementWidth == ElementWidth)
1308 template <
int ElementW
idth,
unsigned Class>
1309 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1310 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1313 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1319 template <
int ElementW
idth,
unsigned Class>
1320 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1321 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1324 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1330 template <
int ElementWidth,
unsigned Class,
1332 bool ShiftWidthAlwaysSame>
1333 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1334 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1335 if (!VectorMatch.isMatch())
1341 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1344 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1347 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1353 bool isGPR32as64()
const {
1354 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1355 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1359 bool isGPR64as32()
const {
1360 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1361 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1365 bool isGPR64x8()
const {
1366 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1367 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1371 bool isWSeqPair()
const {
1372 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1373 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1377 bool isXSeqPair()
const {
1378 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1379 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1383 bool isSyspXzrPair()
const {
1387 template<
int64_t Angle,
int64_t Remainder>
1388 DiagnosticPredicate isComplexRotation()
const {
1395 uint64_t
Value =
CE->getValue();
1397 if (
Value % Angle == Remainder &&
Value <= 270)
1402 template <
unsigned RegClassID>
bool isGPR64()
const {
1403 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1404 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1407 template <
unsigned RegClassID,
int ExtW
idth>
1408 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1409 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1413 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1420 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1421 bool isImplicitlyTypedVectorList()
const {
1422 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1423 VectorList.NumElements == 0 &&
1424 VectorList.RegisterKind == VectorKind &&
1425 (!IsConsecutive || (VectorList.Stride == 1));
1428 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1429 unsigned ElementWidth,
unsigned Stride = 1>
1430 bool isTypedVectorList()
const {
1431 if (Kind != k_VectorList)
1433 if (VectorList.Count != NumRegs)
1435 if (VectorList.RegisterKind != VectorKind)
1437 if (VectorList.ElementWidth != ElementWidth)
1439 if (VectorList.Stride != Stride)
1441 return VectorList.NumElements == NumElements;
1444 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1445 unsigned ElementWidth,
unsigned RegClass>
1446 DiagnosticPredicate isTypedVectorListInRegClass()
const {
1448 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1451 if (!getAArch64MCRegisterClass(RegClass).
contains(VectorList.Reg))
1456 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1457 unsigned ElementWidth>
1458 DiagnosticPredicate isTypedVectorListStrided()
const {
1459 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1460 ElementWidth, Stride>();
1463 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1464 ((VectorList.Reg >= AArch64::Z16) &&
1465 (VectorList.Reg < (AArch64::Z16 + Stride))))
1470 template <
int Min,
int Max>
1471 DiagnosticPredicate isVectorIndex()
const {
1472 if (Kind != k_VectorIndex)
1474 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1479 bool isToken()
const override {
return Kind == k_Token; }
1481 bool isTokenEqual(StringRef Str)
const {
1482 return Kind == k_Token &&
getToken() == Str;
1484 bool isSysCR()
const {
return Kind == k_SysCR; }
1485 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1486 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1487 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1488 bool isShifter()
const {
1489 if (!isShiftExtend())
1498 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1499 if (Kind != k_FPImm)
1502 if (getFPImmIsExact()) {
1504 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1506 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1509 APFloat RealVal(APFloat::IEEEdouble());
1511 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1512 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1515 if (
getFPImm().bitwiseIsEqual(RealVal))
1522 template <
unsigned ImmA,
unsigned ImmB>
1523 DiagnosticPredicate isExactFPImm()
const {
1525 if ((Res = isExactFPImm<ImmA>()))
1527 if ((Res = isExactFPImm<ImmB>()))
1532 bool isExtend()
const {
1533 if (!isShiftExtend())
1542 getShiftExtendAmount() <= 4;
1545 bool isExtend64()
const {
1555 bool isExtendLSL64()
const {
1561 getShiftExtendAmount() <= 4;
1564 bool isLSLImm3Shift()
const {
1565 if (!isShiftExtend())
1571 template<
int W
idth>
bool isMemXExtend()
const {
1576 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1577 getShiftExtendAmount() == 0);
1580 template<
int W
idth>
bool isMemWExtend()
const {
1585 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1586 getShiftExtendAmount() == 0);
1589 template <
unsigned w
idth>
1590 bool isArithmeticShifter()
const {
1600 template <
unsigned w
idth>
1601 bool isLogicalShifter()
const {
1609 getShiftExtendAmount() < width;
1612 bool isMovImm32Shifter()
const {
1620 uint64_t Val = getShiftExtendAmount();
1621 return (Val == 0 || Val == 16);
1624 bool isMovImm64Shifter()
const {
1632 uint64_t Val = getShiftExtendAmount();
1633 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1636 bool isLogicalVecShifter()
const {
1641 unsigned Shift = getShiftExtendAmount();
1643 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1646 bool isLogicalVecHalfWordShifter()
const {
1647 if (!isLogicalVecShifter())
1651 unsigned Shift = getShiftExtendAmount();
1653 (Shift == 0 || Shift == 8);
1656 bool isMoveVecShifter()
const {
1657 if (!isShiftExtend())
1661 unsigned Shift = getShiftExtendAmount();
1663 (Shift == 8 || Shift == 16);
1672 bool isSImm9OffsetFB()
const {
1673 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1676 bool isAdrpLabel()
const {
1683 int64_t Val =
CE->getValue();
1684 int64_t Min = - (4096 * (1LL << (21 - 1)));
1685 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1686 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1692 bool isAdrLabel()
const {
1699 int64_t Val =
CE->getValue();
1700 int64_t Min = - (1LL << (21 - 1));
1701 int64_t
Max = ((1LL << (21 - 1)) - 1);
1702 return Val >= Min && Val <=
Max;
1708 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1709 DiagnosticPredicate isMatrixRegOperand()
const {
1712 if (getMatrixKind() != Kind ||
1713 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1714 EltSize != getMatrixElementWidth())
1719 bool isPAuthPCRelLabel16Operand()
const {
1731 return (Val <= 0) && (Val > -(1 << 18));
1734 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1744 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1745 assert(
N == 1 &&
"Invalid number of operands!");
1749 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1750 assert(
N == 1 &&
"Invalid number of operands!");
1754 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1755 assert(
N == 1 &&
"Invalid number of operands!");
1757 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1759 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1766 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1767 assert(
N == 1 &&
"Invalid number of operands!");
1769 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1771 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1778 template <
int W
idth>
1779 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1782 case 8:
Base = AArch64::B0;
break;
1783 case 16:
Base = AArch64::H0;
break;
1784 case 32:
Base = AArch64::S0;
break;
1785 case 64:
Base = AArch64::D0;
break;
1786 case 128:
Base = AArch64::Q0;
break;
1793 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1794 assert(
N == 1 &&
"Invalid number of operands!");
1797 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1798 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1802 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1803 assert(
N == 1 &&
"Invalid number of operands!");
1808 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1809 assert(
N == 1 &&
"Invalid number of operands!");
1810 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1815 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1816 assert(
N == 1 &&
"Invalid number of operands!");
1817 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1822 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1823 assert(
N == 1 &&
"Invalid number of operands!");
1827 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1828 assert(
N == 1 &&
"Invalid number of operands!");
1832 enum VecListIndexType {
1833 VecListIdx_DReg = 0,
1834 VecListIdx_QReg = 1,
1835 VecListIdx_ZReg = 2,
1836 VecListIdx_PReg = 3,
1839 template <VecListIndexType RegTy,
unsigned NumRegs,
1840 bool IsConsecutive =
false>
1841 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1842 assert(
N == 1 &&
"Invalid number of operands!");
1843 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1844 "Expected consecutive registers");
1845 static const unsigned FirstRegs[][5] = {
1847 AArch64::D0, AArch64::D0_D1,
1848 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1850 AArch64::Q0, AArch64::Q0_Q1,
1851 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1853 AArch64::Z0, AArch64::Z0_Z1,
1854 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1856 AArch64::P0, AArch64::P0_P1 }
1859 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1860 " NumRegs must be <= 4 for ZRegs");
1862 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1863 " NumRegs must be <= 2 for PRegs");
1865 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1867 FirstRegs[(
unsigned)RegTy][0]));
1870 template <
unsigned NumRegs>
1871 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1872 assert(
N == 1 &&
"Invalid number of operands!");
1873 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1877 if (getVectorListStart() < AArch64::Z16) {
1878 assert((getVectorListStart() < AArch64::Z8) &&
1879 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1881 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1883 assert((getVectorListStart() < AArch64::Z24) &&
1884 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1886 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1890 if (getVectorListStart() < AArch64::Z16) {
1891 assert((getVectorListStart() < AArch64::Z4) &&
1892 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1894 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1896 assert((getVectorListStart() < AArch64::Z20) &&
1897 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1899 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1907 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1908 assert(
N == 1 &&
"Invalid number of operands!");
1909 unsigned RegMask = getMatrixTileListRegMask();
1910 assert(RegMask <= 0xFF &&
"Invalid mask!");
1914 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1915 assert(
N == 1 &&
"Invalid number of operands!");
1919 template <
unsigned ImmIs0,
unsigned ImmIs1>
1920 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1921 assert(
N == 1 &&
"Invalid number of operands!");
1922 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1926 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1927 assert(
N == 1 &&
"Invalid number of operands!");
1934 template <
int Shift>
1935 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1936 assert(
N == 2 &&
"Invalid number of operands!");
1937 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1940 }
else if (isShiftedImm()) {
1941 addExpr(Inst, getShiftedImmVal());
1949 template <
int Shift>
1950 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1951 assert(
N == 2 &&
"Invalid number of operands!");
1952 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1959 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1960 assert(
N == 1 &&
"Invalid number of operands!");
1964 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1965 assert(
N == 1 &&
"Invalid number of operands!");
1973 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1974 addImmOperands(Inst,
N);
1978 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1979 assert(
N == 1 &&
"Invalid number of operands!");
1989 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1990 assert(
N == 1 &&
"Invalid number of operands!");
1995 template <
int Scale>
1996 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
1997 assert(
N == 1 &&
"Invalid number of operands!");
2002 template <
int Scale>
2003 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2004 assert(
N == 1 &&
"Invalid number of operands!");
2008 template <
typename T>
2009 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2010 assert(
N == 1 &&
"Invalid number of operands!");
2012 std::make_unsigned_t<T> Val = MCE->
getValue();
2017 template <
typename T>
2018 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2019 assert(
N == 1 &&
"Invalid number of operands!");
2021 std::make_unsigned_t<T> Val = ~MCE->getValue();
2026 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2027 assert(
N == 1 &&
"Invalid number of operands!");
2033 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2037 assert(
N == 1 &&
"Invalid number of operands!");
2043 assert(MCE &&
"Invalid constant immediate operand!");
2047 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2051 assert(
N == 1 &&
"Invalid number of operands!");
2060 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2064 assert(
N == 1 &&
"Invalid number of operands!");
2070 assert(MCE &&
"Invalid constant immediate operand!");
2074 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2078 assert(
N == 1 &&
"Invalid number of operands!");
2084 assert(MCE &&
"Invalid constant immediate operand!");
2088 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2092 assert(
N == 1 &&
"Invalid number of operands!");
2098 assert(MCE &&
"Invalid constant immediate operand!");
2102 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2103 assert(
N == 1 &&
"Invalid number of operands!");
2108 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2109 assert(
N == 1 &&
"Invalid number of operands!");
2113 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2114 assert(
N == 1 &&
"Invalid number of operands!");
2118 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2119 assert(
N == 1 &&
"Invalid number of operands!");
2124 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2125 assert(
N == 1 &&
"Invalid number of operands!");
2130 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2131 assert(
N == 1 &&
"Invalid number of operands!");
2136 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2137 assert(
N == 1 &&
"Invalid number of operands!");
2142 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2143 assert(
N == 1 &&
"Invalid number of operands!");
2148 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2149 assert(
N == 1 &&
"Invalid number of operands!");
2153 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2154 assert(
N == 1 &&
"Invalid number of operands!");
2158 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2159 assert(
N == 1 &&
"Invalid number of operands!");
2163 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2164 assert(
N == 1 &&
"Invalid number of operands!");
2170 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2171 assert(
N == 1 &&
"Invalid number of operands!");
2172 unsigned Imm = getShiftExtendAmount();
2176 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2177 assert(
N == 1 &&
"Invalid number of operands!");
2182 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2185 if (
Reg != AArch64::XZR)
2191 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2192 assert(
N == 1 &&
"Invalid number of operands!");
2199 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2200 assert(
N == 1 &&
"Invalid number of operands!");
2207 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2208 assert(
N == 2 &&
"Invalid number of operands!");
2219 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2220 assert(
N == 2 &&
"Invalid number of operands!");
2228 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2229 assert(
N == 1 &&
"Invalid number of operands!");
2233 uint64_t
Value =
CE->getValue();
2241 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2242 assert(
N == 1 &&
"Invalid number of operands!");
2245 uint64_t
Value =
CE->getValue();
2249 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2250 assert(
N == 1 &&
"Invalid number of operands!");
2255 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2256 assert(
N == 1 &&
"Invalid number of operands!");
2261 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2263 static std::unique_ptr<AArch64Operand>
2264 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2265 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2266 Op->Tok.Data = Str.data();
2267 Op->Tok.Length = Str.size();
2268 Op->Tok.IsSuffix = IsSuffix;
2274 static std::unique_ptr<AArch64Operand>
2275 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2276 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2278 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2279 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2281 Op->Reg.Kind = Kind;
2282 Op->Reg.ElementWidth = 0;
2283 Op->Reg.EqualityTy = EqTy;
2284 Op->Reg.ShiftExtend.Type = ExtTy;
2285 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2286 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2292 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2293 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2295 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2296 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2297 Kind == RegKind::SVEPredicateVector ||
2298 Kind == RegKind::SVEPredicateAsCounter) &&
2299 "Invalid vector kind");
2300 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2302 Op->Reg.ElementWidth = ElementWidth;
2306 static std::unique_ptr<AArch64Operand>
2307 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2308 unsigned NumElements,
unsigned ElementWidth,
2309 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2310 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2311 Op->VectorList.Reg =
Reg;
2313 Op->VectorList.Stride = Stride;
2314 Op->VectorList.NumElements = NumElements;
2315 Op->VectorList.ElementWidth = ElementWidth;
2316 Op->VectorList.RegisterKind = RegisterKind;
2322 static std::unique_ptr<AArch64Operand>
2323 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2324 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2325 Op->VectorIndex.Val = Idx;
2331 static std::unique_ptr<AArch64Operand>
2332 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2333 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2334 Op->MatrixTileList.RegMask = RegMask;
2340 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2341 const unsigned ElementWidth) {
2342 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2344 {{0, AArch64::ZAB0},
2345 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2346 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2347 {{8, AArch64::ZAB0},
2348 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2349 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2350 {{16, AArch64::ZAH0},
2351 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2352 {{16, AArch64::ZAH1},
2353 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2354 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2355 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2356 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2357 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2360 if (ElementWidth == 64)
2363 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2364 assert(!Regs.empty() &&
"Invalid tile or element width!");
2369 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2370 SMLoc
E, MCContext &Ctx) {
2371 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2378 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2379 unsigned ShiftAmount,
2382 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2383 Op->ShiftedImm .Val = Val;
2384 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2390 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2391 unsigned Last, SMLoc S,
2394 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2396 Op->ImmRange.Last =
Last;
2401 static std::unique_ptr<AArch64Operand>
2403 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2404 Op->CondCode.Code =
Code;
2410 static std::unique_ptr<AArch64Operand>
2411 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2412 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2414 Op->FPImm.IsExact = IsExact;
2420 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2424 bool HasnXSModifier) {
2425 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2426 Op->Barrier.Val = Val;
2427 Op->Barrier.Data = Str.data();
2428 Op->Barrier.Length = Str.size();
2429 Op->Barrier.HasnXSModifier = HasnXSModifier;
2435 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2438 uint32_t PStateField,
2440 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2441 Op->SysReg.Data = Str.data();
2442 Op->SysReg.Length = Str.size();
2443 Op->SysReg.MRSReg = MRSReg;
2444 Op->SysReg.MSRReg = MSRReg;
2445 Op->SysReg.PStateField = PStateField;
2451 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2452 SMLoc
E, MCContext &Ctx) {
2453 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2454 Op->SysCRImm.Val = Val;
2460 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2464 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2465 Op->Prefetch.Val = Val;
2466 Op->Barrier.Data = Str.data();
2467 Op->Barrier.Length = Str.size();
2473 static std::unique_ptr<AArch64Operand>
2474 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2475 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2476 Op->TIndexHint.Val = Val;
2477 Op->TIndexHint.Data = Str.data();
2478 Op->TIndexHint.Length = Str.size();
2484 static std::unique_ptr<AArch64Operand>
2485 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2486 SMLoc S, SMLoc
E, MCContext &Ctx) {
2487 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2488 Op->MatrixReg.Reg =
Reg;
2489 Op->MatrixReg.ElementWidth = ElementWidth;
2490 Op->MatrixReg.Kind = Kind;
2496 static std::unique_ptr<AArch64Operand>
2497 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2498 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2499 Op->SVCR.PStateField = PStateField;
2500 Op->SVCR.Data = Str.data();
2501 Op->SVCR.Length = Str.size();
2507 static std::unique_ptr<AArch64Operand>
2509 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2510 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2511 Op->ShiftExtend.Type = ShOp;
2512 Op->ShiftExtend.Amount = Val;
2513 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2525 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2526 if (!getFPImmIsExact())
2531 StringRef
Name = getBarrierName();
2533 OS <<
"<barrier " <<
Name <<
">";
2535 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2541 case k_ShiftedImm: {
2542 unsigned Shift = getShiftedImmShift();
2543 OS <<
"<shiftedimm ";
2550 OS << getFirstImmVal();
2551 OS <<
":" << getLastImmVal() <<
">";
2557 case k_VectorList: {
2558 OS <<
"<vectorlist ";
2559 MCRegister
Reg = getVectorListStart();
2560 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2561 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2566 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2569 OS <<
"<sysreg: " << getSysReg() <<
'>';
2575 OS <<
"c" << getSysCR();
2578 StringRef
Name = getPrefetchName();
2580 OS <<
"<prfop " <<
Name <<
">";
2582 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2586 OS << getTIndexHintName();
2588 case k_MatrixRegister:
2589 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2591 case k_MatrixTileList: {
2592 OS <<
"<matrixlist ";
2593 unsigned RegMask = getMatrixTileListRegMask();
2594 unsigned MaxBits = 8;
2595 for (
unsigned I = MaxBits;
I > 0; --
I)
2596 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2605 OS <<
"<register " <<
getReg().
id() <<
">";
2606 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2611 << getShiftExtendAmount();
2612 if (!hasShiftExtendAmount())
2628 .
Case(
"v0", AArch64::Q0)
2629 .
Case(
"v1", AArch64::Q1)
2630 .
Case(
"v2", AArch64::Q2)
2631 .
Case(
"v3", AArch64::Q3)
2632 .
Case(
"v4", AArch64::Q4)
2633 .
Case(
"v5", AArch64::Q5)
2634 .
Case(
"v6", AArch64::Q6)
2635 .
Case(
"v7", AArch64::Q7)
2636 .
Case(
"v8", AArch64::Q8)
2637 .
Case(
"v9", AArch64::Q9)
2638 .
Case(
"v10", AArch64::Q10)
2639 .
Case(
"v11", AArch64::Q11)
2640 .
Case(
"v12", AArch64::Q12)
2641 .
Case(
"v13", AArch64::Q13)
2642 .
Case(
"v14", AArch64::Q14)
2643 .
Case(
"v15", AArch64::Q15)
2644 .
Case(
"v16", AArch64::Q16)
2645 .
Case(
"v17", AArch64::Q17)
2646 .
Case(
"v18", AArch64::Q18)
2647 .
Case(
"v19", AArch64::Q19)
2648 .
Case(
"v20", AArch64::Q20)
2649 .
Case(
"v21", AArch64::Q21)
2650 .
Case(
"v22", AArch64::Q22)
2651 .
Case(
"v23", AArch64::Q23)
2652 .
Case(
"v24", AArch64::Q24)
2653 .
Case(
"v25", AArch64::Q25)
2654 .
Case(
"v26", AArch64::Q26)
2655 .
Case(
"v27", AArch64::Q27)
2656 .
Case(
"v28", AArch64::Q28)
2657 .
Case(
"v29", AArch64::Q29)
2658 .
Case(
"v30", AArch64::Q30)
2659 .
Case(
"v31", AArch64::Q31)
2668 RegKind VectorKind) {
2669 std::pair<int, int> Res = {-1, -1};
2671 switch (VectorKind) {
2672 case RegKind::NeonVector:
2675 .Case(
".1d", {1, 64})
2676 .Case(
".1q", {1, 128})
2678 .Case(
".2h", {2, 16})
2679 .Case(
".2b", {2, 8})
2680 .Case(
".2s", {2, 32})
2681 .Case(
".2d", {2, 64})
2684 .Case(
".4b", {4, 8})
2685 .Case(
".4h", {4, 16})
2686 .Case(
".4s", {4, 32})
2687 .Case(
".8b", {8, 8})
2688 .Case(
".8h", {8, 16})
2689 .Case(
".16b", {16, 8})
2694 .Case(
".h", {0, 16})
2695 .Case(
".s", {0, 32})
2696 .Case(
".d", {0, 64})
2699 case RegKind::SVEPredicateAsCounter:
2700 case RegKind::SVEPredicateVector:
2701 case RegKind::SVEDataVector:
2702 case RegKind::Matrix:
2706 .Case(
".h", {0, 16})
2707 .Case(
".s", {0, 32})
2708 .Case(
".d", {0, 64})
2709 .Case(
".q", {0, 128})
2716 if (Res == std::make_pair(-1, -1))
2717 return std::nullopt;
2719 return std::optional<std::pair<int, int>>(Res);
2728 .
Case(
"z0", AArch64::Z0)
2729 .
Case(
"z1", AArch64::Z1)
2730 .
Case(
"z2", AArch64::Z2)
2731 .
Case(
"z3", AArch64::Z3)
2732 .
Case(
"z4", AArch64::Z4)
2733 .
Case(
"z5", AArch64::Z5)
2734 .
Case(
"z6", AArch64::Z6)
2735 .
Case(
"z7", AArch64::Z7)
2736 .
Case(
"z8", AArch64::Z8)
2737 .
Case(
"z9", AArch64::Z9)
2738 .
Case(
"z10", AArch64::Z10)
2739 .
Case(
"z11", AArch64::Z11)
2740 .
Case(
"z12", AArch64::Z12)
2741 .
Case(
"z13", AArch64::Z13)
2742 .
Case(
"z14", AArch64::Z14)
2743 .
Case(
"z15", AArch64::Z15)
2744 .
Case(
"z16", AArch64::Z16)
2745 .
Case(
"z17", AArch64::Z17)
2746 .
Case(
"z18", AArch64::Z18)
2747 .
Case(
"z19", AArch64::Z19)
2748 .
Case(
"z20", AArch64::Z20)
2749 .
Case(
"z21", AArch64::Z21)
2750 .
Case(
"z22", AArch64::Z22)
2751 .
Case(
"z23", AArch64::Z23)
2752 .
Case(
"z24", AArch64::Z24)
2753 .
Case(
"z25", AArch64::Z25)
2754 .
Case(
"z26", AArch64::Z26)
2755 .
Case(
"z27", AArch64::Z27)
2756 .
Case(
"z28", AArch64::Z28)
2757 .
Case(
"z29", AArch64::Z29)
2758 .
Case(
"z30", AArch64::Z30)
2759 .
Case(
"z31", AArch64::Z31)
2765 .
Case(
"p0", AArch64::P0)
2766 .
Case(
"p1", AArch64::P1)
2767 .
Case(
"p2", AArch64::P2)
2768 .
Case(
"p3", AArch64::P3)
2769 .
Case(
"p4", AArch64::P4)
2770 .
Case(
"p5", AArch64::P5)
2771 .
Case(
"p6", AArch64::P6)
2772 .
Case(
"p7", AArch64::P7)
2773 .
Case(
"p8", AArch64::P8)
2774 .
Case(
"p9", AArch64::P9)
2775 .
Case(
"p10", AArch64::P10)
2776 .
Case(
"p11", AArch64::P11)
2777 .
Case(
"p12", AArch64::P12)
2778 .
Case(
"p13", AArch64::P13)
2779 .
Case(
"p14", AArch64::P14)
2780 .
Case(
"p15", AArch64::P15)
2786 .
Case(
"pn0", AArch64::PN0)
2787 .
Case(
"pn1", AArch64::PN1)
2788 .
Case(
"pn2", AArch64::PN2)
2789 .
Case(
"pn3", AArch64::PN3)
2790 .
Case(
"pn4", AArch64::PN4)
2791 .
Case(
"pn5", AArch64::PN5)
2792 .
Case(
"pn6", AArch64::PN6)
2793 .
Case(
"pn7", AArch64::PN7)
2794 .
Case(
"pn8", AArch64::PN8)
2795 .
Case(
"pn9", AArch64::PN9)
2796 .
Case(
"pn10", AArch64::PN10)
2797 .
Case(
"pn11", AArch64::PN11)
2798 .
Case(
"pn12", AArch64::PN12)
2799 .
Case(
"pn13", AArch64::PN13)
2800 .
Case(
"pn14", AArch64::PN14)
2801 .
Case(
"pn15", AArch64::PN15)
2807 .
Case(
"za0.d", AArch64::ZAD0)
2808 .
Case(
"za1.d", AArch64::ZAD1)
2809 .
Case(
"za2.d", AArch64::ZAD2)
2810 .
Case(
"za3.d", AArch64::ZAD3)
2811 .
Case(
"za4.d", AArch64::ZAD4)
2812 .
Case(
"za5.d", AArch64::ZAD5)
2813 .
Case(
"za6.d", AArch64::ZAD6)
2814 .
Case(
"za7.d", AArch64::ZAD7)
2815 .
Case(
"za0.s", AArch64::ZAS0)
2816 .
Case(
"za1.s", AArch64::ZAS1)
2817 .
Case(
"za2.s", AArch64::ZAS2)
2818 .
Case(
"za3.s", AArch64::ZAS3)
2819 .
Case(
"za0.h", AArch64::ZAH0)
2820 .
Case(
"za1.h", AArch64::ZAH1)
2821 .
Case(
"za0.b", AArch64::ZAB0)
2827 .
Case(
"za", AArch64::ZA)
2828 .
Case(
"za0.q", AArch64::ZAQ0)
2829 .
Case(
"za1.q", AArch64::ZAQ1)
2830 .
Case(
"za2.q", AArch64::ZAQ2)
2831 .
Case(
"za3.q", AArch64::ZAQ3)
2832 .
Case(
"za4.q", AArch64::ZAQ4)
2833 .
Case(
"za5.q", AArch64::ZAQ5)
2834 .
Case(
"za6.q", AArch64::ZAQ6)
2835 .
Case(
"za7.q", AArch64::ZAQ7)
2836 .
Case(
"za8.q", AArch64::ZAQ8)
2837 .
Case(
"za9.q", AArch64::ZAQ9)
2838 .
Case(
"za10.q", AArch64::ZAQ10)
2839 .
Case(
"za11.q", AArch64::ZAQ11)
2840 .
Case(
"za12.q", AArch64::ZAQ12)
2841 .
Case(
"za13.q", AArch64::ZAQ13)
2842 .
Case(
"za14.q", AArch64::ZAQ14)
2843 .
Case(
"za15.q", AArch64::ZAQ15)
2844 .
Case(
"za0.d", AArch64::ZAD0)
2845 .
Case(
"za1.d", AArch64::ZAD1)
2846 .
Case(
"za2.d", AArch64::ZAD2)
2847 .
Case(
"za3.d", AArch64::ZAD3)
2848 .
Case(
"za4.d", AArch64::ZAD4)
2849 .
Case(
"za5.d", AArch64::ZAD5)
2850 .
Case(
"za6.d", AArch64::ZAD6)
2851 .
Case(
"za7.d", AArch64::ZAD7)
2852 .
Case(
"za0.s", AArch64::ZAS0)
2853 .
Case(
"za1.s", AArch64::ZAS1)
2854 .
Case(
"za2.s", AArch64::ZAS2)
2855 .
Case(
"za3.s", AArch64::ZAS3)
2856 .
Case(
"za0.h", AArch64::ZAH0)
2857 .
Case(
"za1.h", AArch64::ZAH1)
2858 .
Case(
"za0.b", AArch64::ZAB0)
2859 .
Case(
"za0h.q", AArch64::ZAQ0)
2860 .
Case(
"za1h.q", AArch64::ZAQ1)
2861 .
Case(
"za2h.q", AArch64::ZAQ2)
2862 .
Case(
"za3h.q", AArch64::ZAQ3)
2863 .
Case(
"za4h.q", AArch64::ZAQ4)
2864 .
Case(
"za5h.q", AArch64::ZAQ5)
2865 .
Case(
"za6h.q", AArch64::ZAQ6)
2866 .
Case(
"za7h.q", AArch64::ZAQ7)
2867 .
Case(
"za8h.q", AArch64::ZAQ8)
2868 .
Case(
"za9h.q", AArch64::ZAQ9)
2869 .
Case(
"za10h.q", AArch64::ZAQ10)
2870 .
Case(
"za11h.q", AArch64::ZAQ11)
2871 .
Case(
"za12h.q", AArch64::ZAQ12)
2872 .
Case(
"za13h.q", AArch64::ZAQ13)
2873 .
Case(
"za14h.q", AArch64::ZAQ14)
2874 .
Case(
"za15h.q", AArch64::ZAQ15)
2875 .
Case(
"za0h.d", AArch64::ZAD0)
2876 .
Case(
"za1h.d", AArch64::ZAD1)
2877 .
Case(
"za2h.d", AArch64::ZAD2)
2878 .
Case(
"za3h.d", AArch64::ZAD3)
2879 .
Case(
"za4h.d", AArch64::ZAD4)
2880 .
Case(
"za5h.d", AArch64::ZAD5)
2881 .
Case(
"za6h.d", AArch64::ZAD6)
2882 .
Case(
"za7h.d", AArch64::ZAD7)
2883 .
Case(
"za0h.s", AArch64::ZAS0)
2884 .
Case(
"za1h.s", AArch64::ZAS1)
2885 .
Case(
"za2h.s", AArch64::ZAS2)
2886 .
Case(
"za3h.s", AArch64::ZAS3)
2887 .
Case(
"za0h.h", AArch64::ZAH0)
2888 .
Case(
"za1h.h", AArch64::ZAH1)
2889 .
Case(
"za0h.b", AArch64::ZAB0)
2890 .
Case(
"za0v.q", AArch64::ZAQ0)
2891 .
Case(
"za1v.q", AArch64::ZAQ1)
2892 .
Case(
"za2v.q", AArch64::ZAQ2)
2893 .
Case(
"za3v.q", AArch64::ZAQ3)
2894 .
Case(
"za4v.q", AArch64::ZAQ4)
2895 .
Case(
"za5v.q", AArch64::ZAQ5)
2896 .
Case(
"za6v.q", AArch64::ZAQ6)
2897 .
Case(
"za7v.q", AArch64::ZAQ7)
2898 .
Case(
"za8v.q", AArch64::ZAQ8)
2899 .
Case(
"za9v.q", AArch64::ZAQ9)
2900 .
Case(
"za10v.q", AArch64::ZAQ10)
2901 .
Case(
"za11v.q", AArch64::ZAQ11)
2902 .
Case(
"za12v.q", AArch64::ZAQ12)
2903 .
Case(
"za13v.q", AArch64::ZAQ13)
2904 .
Case(
"za14v.q", AArch64::ZAQ14)
2905 .
Case(
"za15v.q", AArch64::ZAQ15)
2906 .
Case(
"za0v.d", AArch64::ZAD0)
2907 .
Case(
"za1v.d", AArch64::ZAD1)
2908 .
Case(
"za2v.d", AArch64::ZAD2)
2909 .
Case(
"za3v.d", AArch64::ZAD3)
2910 .
Case(
"za4v.d", AArch64::ZAD4)
2911 .
Case(
"za5v.d", AArch64::ZAD5)
2912 .
Case(
"za6v.d", AArch64::ZAD6)
2913 .
Case(
"za7v.d", AArch64::ZAD7)
2914 .
Case(
"za0v.s", AArch64::ZAS0)
2915 .
Case(
"za1v.s", AArch64::ZAS1)
2916 .
Case(
"za2v.s", AArch64::ZAS2)
2917 .
Case(
"za3v.s", AArch64::ZAS3)
2918 .
Case(
"za0v.h", AArch64::ZAH0)
2919 .
Case(
"za1v.h", AArch64::ZAH1)
2920 .
Case(
"za0v.b", AArch64::ZAB0)
2924bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2926 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2929ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2931 StartLoc = getLoc();
2932 ParseStatus Res = tryParseScalarRegister(
Reg);
2938MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2940 MCRegister
Reg = MCRegister();
2942 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2945 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2948 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2951 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2954 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2956 if (
Name.equals_insensitive(
"zt0"))
2957 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2961 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2965 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2966 .Case(
"fp", AArch64::FP)
2967 .Case(
"lr", AArch64::LR)
2968 .Case(
"x31", AArch64::XZR)
2969 .Case(
"w31", AArch64::WZR)
2971 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2977 if (Entry == RegisterReqs.
end())
2978 return MCRegister();
2981 if (Kind ==
Entry->getValue().first)
2987unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2989 case RegKind::Scalar:
2990 case RegKind::NeonVector:
2991 case RegKind::SVEDataVector:
2993 case RegKind::Matrix:
2994 case RegKind::SVEPredicateVector:
2995 case RegKind::SVEPredicateAsCounter:
2997 case RegKind::LookupTable:
3006ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3007 const AsmToken &Tok = getTok();
3012 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3022ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3026 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3029 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3030 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3034 if (BadNum || CRNum > 15)
3035 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3039 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3044ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3046 const AsmToken &Tok = getTok();
3048 unsigned MaxVal = 63;
3053 const MCExpr *ImmVal;
3054 if (getParser().parseExpression(ImmVal))
3059 return TokError(
"immediate value expected for prefetch operand");
3062 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3065 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3066 Operands.
push_back(AArch64Operand::CreatePrefetch(
3067 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3073 return TokError(
"prefetch hint expected");
3075 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3077 return TokError(
"prefetch hint expected");
3079 Operands.
push_back(AArch64Operand::CreatePrefetch(
3086template <
bool IsSVEPrefetch>
3087ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3089 const AsmToken &Tok = getTok();
3091 auto LookupByName = [](StringRef
N) {
3092 if (IsSVEPrefetch) {
3093 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3094 return std::optional<unsigned>(Res->Encoding);
3095 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3096 return std::optional<unsigned>(Res->Encoding);
3097 return std::optional<unsigned>();
3100 auto LookupByEncoding = [](
unsigned E) {
3101 if (IsSVEPrefetch) {
3102 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3103 return std::optional<StringRef>(
3104 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3105 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3106 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3107 return std::optional<StringRef>();
3109 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3115 const MCExpr *ImmVal;
3116 if (getParser().parseExpression(ImmVal))
3121 return TokError(
"immediate value expected for prefetch operand");
3124 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3127 auto PRFM = LookupByEncoding(MCE->
getValue());
3128 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3134 return TokError(
"prefetch hint expected");
3136 auto PRFM = LookupByName(Tok.
getString());
3138 return TokError(
"prefetch hint expected");
3140 Operands.
push_back(AArch64Operand::CreatePrefetch(
3146ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3147 SMLoc StartLoc = getLoc();
3153 auto RegTok = getTok();
3154 if (!tryParseScalarRegister(RegNum).isSuccess())
3157 if (RegNum != AArch64::XZR) {
3158 getLexer().UnLex(RegTok);
3165 if (!tryParseScalarRegister(RegNum).isSuccess())
3166 return TokError(
"expected register operand");
3168 if (RegNum != AArch64::XZR)
3169 return TokError(
"xzr must be followed by xzr");
3173 Operands.
push_back(AArch64Operand::CreateReg(
3174 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3180ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3182 const AsmToken &Tok = getTok();
3184 return TokError(
"invalid operand for instruction");
3186 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3188 return TokError(
"invalid operand for instruction");
3190 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3198ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3200 const MCExpr *Expr =
nullptr;
3206 if (parseSymbolicImmVal(Expr))
3212 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3221 return Error(S,
"gotpage label reference not allowed an addend");
3233 return Error(S,
"page or gotpage label reference expected");
3248ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3250 const MCExpr *Expr =
nullptr;
3259 if (parseSymbolicImmVal(Expr))
3265 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3277 return Error(S,
"unexpected adr label");
3287template <
bool AddFPZeroAsLiteral>
3288ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3296 const AsmToken &Tok = getTok();
3300 return TokError(
"invalid floating point immediate");
3305 if (Tok.
getIntVal() > 255 || isNegative)
3306 return TokError(
"encoded floating point value out of range");
3310 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3313 APFloat RealVal(APFloat::IEEEdouble());
3315 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3317 return TokError(
"invalid floating point representation");
3320 RealVal.changeSign();
3322 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3326 Operands.
push_back(AArch64Operand::CreateFPImm(
3327 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3338AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3349 return tryParseImmRange(Operands);
3351 const MCExpr *
Imm =
nullptr;
3352 if (parseSymbolicImmVal(Imm))
3356 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3363 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3365 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3367 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3373 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3374 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3382 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3384 int64_t ShiftAmount = getTok().getIntVal();
3386 if (ShiftAmount < 0)
3387 return Error(getLoc(),
"positive shift amount required");
3391 if (ShiftAmount == 0 && Imm !=
nullptr) {
3393 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3397 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3405AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3439 Suggestion =
"nfrst";
3445bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3446 bool invertCondCode) {
3448 const AsmToken &Tok = getTok();
3452 std::string Suggestion;
3455 std::string
Msg =
"invalid condition code";
3456 if (!Suggestion.empty())
3457 Msg +=
", did you mean " + Suggestion +
"?";
3458 return TokError(
Msg);
3462 if (invertCondCode) {
3464 return TokError(
"condition codes AL and NV are invalid for this instruction");
3469 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3473ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3474 const AsmToken &Tok = getTok();
3478 return TokError(
"invalid operand for instruction");
3480 unsigned PStateImm = -1;
3481 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3484 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3485 PStateImm = SVCR->Encoding;
3493ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3494 const AsmToken &Tok = getTok();
3499 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3501 unsigned ElementWidth = 0;
3502 auto DotPosition =
Name.find(
'.');
3504 const auto &KindRes =
3508 "Expected the register to be followed by element width suffix");
3509 ElementWidth = KindRes->second;
3511 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3512 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3517 if (parseOperand(Operands,
false,
false))
3524 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3528 size_t DotPosition =
Name.find(
'.');
3531 StringRef Head =
Name.take_front(DotPosition);
3532 StringRef
Tail =
Name.drop_front(DotPosition);
3533 StringRef RowOrColumn = Head.
take_back();
3535 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3536 .Case(
"h", MatrixKind::Row)
3537 .Case(
"v", MatrixKind::Col)
3538 .Default(MatrixKind::Tile);
3544 "Expected the register to be followed by element width suffix");
3545 unsigned ElementWidth = KindRes->second;
3549 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3555 if (parseOperand(Operands,
false,
false))
3564AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3565 const AsmToken &Tok = getTok();
3568 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3597 return TokError(
"expected #imm after shift specifier");
3603 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3612 return Error(
E,
"expected integer shift amount");
3614 const MCExpr *ImmVal;
3615 if (getParser().parseExpression(ImmVal))
3620 return Error(
E,
"expected constant '#imm' after shift specifier");
3623 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3629 {{
"crc"}, {AArch64::FeatureCRC}},
3630 {{
"sm4"}, {AArch64::FeatureSM4}},
3631 {{
"sha3"}, {AArch64::FeatureSHA3}},
3632 {{
"sha2"}, {AArch64::FeatureSHA2}},
3633 {{
"aes"}, {AArch64::FeatureAES}},
3634 {{
"crypto"}, {AArch64::FeatureCrypto}},
3635 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3636 {{
"simd"}, {AArch64::FeatureNEON}},
3637 {{
"ras"}, {AArch64::FeatureRAS}},
3638 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3639 {{
"lse"}, {AArch64::FeatureLSE}},
3640 {{
"predres"}, {AArch64::FeaturePredRes}},
3641 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3642 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3643 {{
"mte"}, {AArch64::FeatureMTE}},
3644 {{
"memtag"}, {AArch64::FeatureMTE}},
3645 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3646 {{
"pan"}, {AArch64::FeaturePAN}},
3647 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3648 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3649 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3650 {{
"rng"}, {AArch64::FeatureRandGen}},
3651 {{
"sve"}, {AArch64::FeatureSVE}},
3652 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3653 {{
"sve2"}, {AArch64::FeatureSVE2}},
3654 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3655 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3656 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3657 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3658 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3659 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3660 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3662 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3663 AArch64::FeatureSVE2}},
3664 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3665 {{
"ls64"}, {AArch64::FeatureLS64}},
3666 {{
"xs"}, {AArch64::FeatureXS}},
3667 {{
"pauth"}, {AArch64::FeaturePAuth}},
3668 {{
"flagm"}, {AArch64::FeatureFlagM}},
3669 {{
"rme"}, {AArch64::FeatureRME}},
3670 {{
"sme"}, {AArch64::FeatureSME}},
3671 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3672 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3673 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3674 {{
"sme2"}, {AArch64::FeatureSME2}},
3675 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3676 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3677 {{
"hbc"}, {AArch64::FeatureHBC}},
3678 {{
"mops"}, {AArch64::FeatureMOPS}},
3679 {{
"mec"}, {AArch64::FeatureMEC}},
3680 {{
"the"}, {AArch64::FeatureTHE}},
3681 {{
"d128"}, {AArch64::FeatureD128}},
3682 {{
"lse128"}, {AArch64::FeatureLSE128}},
3683 {{
"ite"}, {AArch64::FeatureITE}},
3684 {{
"cssc"}, {AArch64::FeatureCSSC}},
3685 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3686 {{
"gcs"}, {AArch64::FeatureGCS}},
3687 {{
"bf16"}, {AArch64::FeatureBF16}},
3688 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3689 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3690 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3691 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3692 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3693 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3694 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3695 {{
"lor"}, {AArch64::FeatureLOR}},
3696 {{
"profile"}, {AArch64::FeatureSPE}},
3700 {{
"rdm"}, {AArch64::FeatureRDM}},
3701 {{
"rdma"}, {AArch64::FeatureRDM}},
3702 {{
"sb"}, {AArch64::FeatureSB}},
3703 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3704 {{
"fp8"}, {AArch64::FeatureFP8}},
3705 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3706 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3707 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3708 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3709 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3710 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3711 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3712 {{
"lut"}, {AArch64::FeatureLUT}},
3713 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3714 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3715 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3716 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3717 {{
"cpa"}, {AArch64::FeatureCPA}},
3718 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3719 {{
"pops"}, {AArch64::FeaturePoPS}},
3720 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3721 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3722 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3723 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3724 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3725 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3726 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3727 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3728 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3729 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3730 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3731 {{
"lsui"}, {AArch64::FeatureLSUI}},
3732 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3733 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3734 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3735 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3736 {{
"lscp"}, {AArch64::FeatureLSCP}},
3737 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3738 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3739 {{
"gcie"}, {AArch64::FeatureGCIE}},
3740 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3741 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3742 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3743 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3744 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3745 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3746 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3747 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3748 {{
"tev"}, {AArch64::FeatureTEV}},
3749 {{
"btie"}, {AArch64::FeatureBTIE}},
3750 {{
"hinte"}, {AArch64::FeatureHINTE}},
3751 {{
"dit"}, {AArch64::FeatureDIT}},
3752 {{
"brbe"}, {AArch64::FeatureBRBE}},
3753 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3754 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3755 {{
"jscvt"}, {AArch64::FeatureJS}},
3756 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3757 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3758 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3763 if (FBS[AArch64::HasV8_0aOps])
3765 if (FBS[AArch64::HasV8_1aOps])
3767 else if (FBS[AArch64::HasV8_2aOps])
3769 else if (FBS[AArch64::HasV8_3aOps])
3771 else if (FBS[AArch64::HasV8_4aOps])
3773 else if (FBS[AArch64::HasV8_5aOps])
3775 else if (FBS[AArch64::HasV8_6aOps])
3777 else if (FBS[AArch64::HasV8_7aOps])
3779 else if (FBS[AArch64::HasV8_8aOps])
3781 else if (FBS[AArch64::HasV8_9aOps])
3783 else if (FBS[AArch64::HasV9_0aOps])
3785 else if (FBS[AArch64::HasV9_1aOps])
3787 else if (FBS[AArch64::HasV9_2aOps])
3789 else if (FBS[AArch64::HasV9_3aOps])
3791 else if (FBS[AArch64::HasV9_4aOps])
3793 else if (FBS[AArch64::HasV9_5aOps])
3795 else if (FBS[AArch64::HasV9_6aOps])
3797 else if (FBS[AArch64::HasV9_7aOps])
3799 else if (FBS[AArch64::HasV8_0rOps])
3808 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3812void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
3814 const uint16_t Op2 = Encoding & 7;
3815 const uint16_t Cm = (Encoding & 0x78) >> 3;
3816 const uint16_t Cn = (Encoding & 0x780) >> 7;
3817 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3822 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3824 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3826 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3829 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3835bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3837 if (
Name.contains(
'.'))
3838 return TokError(
"invalid operand");
3843 const AsmToken &Tok = getTok();
3846 bool ExpectRegister =
true;
3847 bool OptionalRegister =
false;
3848 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3849 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3851 if (Mnemonic ==
"ic") {
3852 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3854 return TokError(
"invalid operand for IC instruction");
3855 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3856 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3859 return TokError(Str);
3862 createSysAlias(IC->
Encoding, Operands, S);
3863 }
else if (Mnemonic ==
"dc") {
3864 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3866 return TokError(
"invalid operand for DC instruction");
3867 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3868 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3871 return TokError(Str);
3873 createSysAlias(DC->
Encoding, Operands, S);
3874 }
else if (Mnemonic ==
"at") {
3875 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3877 return TokError(
"invalid operand for AT instruction");
3878 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3879 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3882 return TokError(Str);
3884 createSysAlias(AT->
Encoding, Operands, S);
3885 }
else if (Mnemonic ==
"tlbi") {
3886 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3888 return TokError(
"invalid operand for TLBI instruction");
3889 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3890 std::string Str(
"TLBI " +
3891 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3894 return TokError(Str);
3896 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3897 if (hasAll || hasTLBID)
3898 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3899 createSysAlias(TLBI->
Encoding, Operands, S);
3900 }
else if (Mnemonic ==
"gic") {
3901 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3903 return TokError(
"invalid operand for GIC instruction");
3904 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3905 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3908 return TokError(Str);
3911 createSysAlias(GIC->
Encoding, Operands, S);
3912 }
else if (Mnemonic ==
"gsb") {
3913 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3915 return TokError(
"invalid operand for GSB instruction");
3916 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3917 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3920 return TokError(Str);
3922 ExpectRegister =
false;
3923 createSysAlias(GSB->
Encoding, Operands, S);
3924 }
else if (Mnemonic ==
"plbi") {
3925 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3927 return TokError(
"invalid operand for PLBI instruction");
3928 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3929 std::string Str(
"PLBI " +
3930 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3933 return TokError(Str);
3935 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3936 if (hasAll || hasTLBID)
3937 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3938 createSysAlias(PLBI->
Encoding, Operands, S);
3939 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3940 Mnemonic ==
"cosp") {
3942 if (
Op.lower() !=
"rctx")
3943 return TokError(
"invalid operand for prediction restriction instruction");
3945 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3946 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3948 if (Mnemonic ==
"cosp" && !hasSpecres2)
3949 return TokError(
"COSP requires: predres2");
3951 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3953 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3954 : Mnemonic ==
"dvp" ? 0b101
3955 : Mnemonic ==
"cosp" ? 0b110
3956 : Mnemonic ==
"cpp" ? 0b111
3959 "Invalid mnemonic for prediction restriction instruction");
3960 const auto SYS_3_7_3 = 0b01101110011;
3961 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3963 createSysAlias(Encoding, Operands, S);
3968 bool HasRegister =
false;
3973 return TokError(
"expected register operand");
3977 if (!OptionalRegister) {
3978 if (ExpectRegister && !HasRegister)
3979 return TokError(
"specified " + Mnemonic +
" op requires a register");
3980 else if (!ExpectRegister && HasRegister)
3981 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3993bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
3998 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4001 SMLoc startLoc = getLoc();
4002 const AsmToken ®Tok = getTok();
4004 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4006 return TokError(
"expected register operand");
4008 Operands.
push_back(AArch64Operand::CreateReg(
4009 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4016 const AsmToken &operandTok = getTok();
4018 SMLoc S2 = operandTok.
getLoc();
4021 if (Mnemonic ==
"gicr") {
4022 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4024 return Error(S2,
"invalid operand for GICR instruction");
4025 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4026 std::string Str(
"GICR " +
4027 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4030 return Error(S2, Str);
4032 createSysAlias(GICR->
Encoding, Operands, S2);
4043bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4045 if (
Name.contains(
'.'))
4046 return TokError(
"invalid operand");
4050 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4052 const AsmToken &Tok = getTok();
4056 if (Mnemonic ==
"tlbip") {
4057 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4059 return TokError(
"invalid operand for TLBIP instruction");
4062 std::string Str(
"instruction requires: ");
4064 return TokError(Str);
4066 createSysAlias(TLBIP->
Encoding, Operands, S);
4075 return TokError(
"expected register identifier");
4076 auto Result = tryParseSyspXzrPair(Operands);
4078 Result = tryParseGPRSeqPair(Operands);
4080 return TokError(
"specified " + Mnemonic +
4081 " op requires a pair of registers");
4089ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4090 MCAsmParser &Parser = getParser();
4091 const AsmToken &Tok = getTok();
4095 const MCExpr *ImmVal;
4096 SMLoc ExprLoc = getLoc();
4097 AsmToken IntTok = Tok;
4098 if (getParser().parseExpression(ImmVal))
4102 return Error(ExprLoc,
"immediate value expected for barrier operand");
4104 if (Mnemonic ==
"dsb" &&
Value > 15) {
4112 return Error(ExprLoc,
"barrier operand out of range");
4113 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4114 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4115 Operands.
push_back(AArch64Operand::CreateBarrier(
4121 return TokError(
"invalid operand for instruction");
4124 auto DB = AArch64DB::lookupDBByName(Operand);
4126 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4127 return TokError(
"'sy' or #imm operand expected");
4129 if (Mnemonic ==
"dsb") {
4134 return TokError(
"invalid barrier option name");
4138 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4146AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4147 const AsmToken &Tok = getTok();
4149 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4150 if (Mnemonic !=
"dsb")
4155 const MCExpr *ImmVal;
4156 SMLoc ExprLoc = getLoc();
4157 if (getParser().parseExpression(ImmVal))
4161 return Error(ExprLoc,
"immediate value expected for barrier operand");
4166 return Error(ExprLoc,
"barrier operand out of range");
4167 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4168 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4169 Operands.
push_back(AArch64Operand::CreateBarrier(
4175 return TokError(
"invalid operand for instruction");
4178 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4181 return TokError(
"invalid barrier option name");
4184 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4191ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4192 const AsmToken &Tok = getTok();
4197 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4201 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4202 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4203 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4204 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4208 unsigned PStateImm = -1;
4209 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4210 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4211 PStateImm = PState15->Encoding;
4213 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4214 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4215 PStateImm = PState1->Encoding;
4219 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4227bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4235 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4243 unsigned ElementWidth = KindRes->second;
4245 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4253 return tryParseVectorIndex(Operands).isFailure();
4256ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4257 SMLoc SIdx = getLoc();
4259 const MCExpr *ImmVal;
4260 if (getParser().parseExpression(ImmVal))
4264 return TokError(
"immediate value expected for vector index");
4282ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4284 RegKind MatchKind) {
4285 const AsmToken &Tok = getTok();
4294 StringRef Head =
Name.slice(Start,
Next);
4295 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4301 return TokError(
"invalid vector kind qualifier");
4312ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4314 ParseStatus Status =
4315 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4317 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4322template <RegKind RK>
4324AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4326 const SMLoc S = getLoc();
4329 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4337 unsigned ElementWidth = KindRes->second;
4338 Operands.
push_back(AArch64Operand::CreateVectorReg(
4339 RegNum, RK, ElementWidth, S,
4343 if (RK == RegKind::SVEPredicateAsCounter) {
4344 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4350 if (parseOperand(Operands,
false,
false))
4361 return Error(S,
"not expecting size suffix");
4369 auto Pred = getTok().getString().lower();
4370 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4371 return Error(getLoc(),
"expecting 'z' predication");
4373 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4374 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4377 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4385bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4387 if (!tryParseNeonVectorRegister(Operands))
4390 if (tryParseZTOperand(Operands).isSuccess())
4394 if (tryParseGPROperand<false>(Operands).isSuccess())
4400bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4401 bool HasELFModifier =
false;
4403 SMLoc Loc = getLexer().getLoc();
4405 HasELFModifier =
true;
4408 return TokError(
"expect relocation specifier in operand after ':'");
4410 std::string LowerCase = getTok().getIdentifier().lower();
4411 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4466 return TokError(
"expect relocation specifier in operand after ':'");
4470 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4474 if (getParser().parseExpression(ImmVal))
4481 if (
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4482 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4492 if (getParser().parsePrimaryExpr(Term, EndLoc))
4500ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4504 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4505 unsigned &ElementWidth) -> ParseStatus {
4506 StringRef
Name = getTok().getString();
4507 size_t DotPosition =
Name.find(
'.');
4515 StringRef
Tail =
Name.drop_front(DotPosition);
4516 const std::optional<std::pair<int, int>> &KindRes =
4520 "Expected the register to be followed by element width suffix");
4521 ElementWidth = KindRes->second;
4528 auto LCurly = getTok();
4533 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4539 if (getTok().getString().equals_insensitive(
"za")) {
4545 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4550 SMLoc TileLoc = getLoc();
4552 unsigned FirstReg, ElementWidth;
4553 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4554 if (!ParseRes.isSuccess()) {
4555 getLexer().UnLex(LCurly);
4559 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4561 unsigned PrevReg = FirstReg;
4563 SmallSet<unsigned, 8> DRegs;
4564 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4566 SmallSet<unsigned, 8> SeenRegs;
4567 SeenRegs.
insert(FirstReg);
4571 unsigned Reg, NextElementWidth;
4572 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4573 if (!ParseRes.isSuccess())
4577 if (ElementWidth != NextElementWidth)
4578 return Error(TileLoc,
"mismatched register size suffix");
4581 Warning(TileLoc,
"tile list not in ascending order");
4584 Warning(TileLoc,
"duplicate tile in list");
4587 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4596 unsigned RegMask = 0;
4597 for (
auto Reg : DRegs)
4601 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4606template <RegKind VectorKind>
4607ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4609 MCAsmParser &Parser = getParser();
4614 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4615 bool NoMatchIsError) -> ParseStatus {
4616 auto RegTok = getTok();
4617 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4618 if (ParseRes.isSuccess()) {
4625 RegTok.getString().equals_insensitive(
"zt0"))
4629 (ParseRes.isNoMatch() && NoMatchIsError &&
4630 !RegTok.getString().starts_with_insensitive(
"za")))
4631 return Error(Loc,
"vector register expected");
4636 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4638 auto LCurly = getTok();
4642 MCRegister FirstReg;
4643 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4647 if (ParseRes.isNoMatch())
4650 if (!ParseRes.isSuccess())
4653 MCRegister PrevReg = FirstReg;
4656 unsigned Stride = 1;
4658 SMLoc Loc = getLoc();
4662 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4663 if (!ParseRes.isSuccess())
4667 if (Kind != NextKind)
4668 return Error(Loc,
"mismatched register size suffix");
4671 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4673 if (Space == 0 || Space > 3)
4674 return Error(Loc,
"invalid number of vectors");
4679 bool HasCalculatedStride =
false;
4681 SMLoc Loc = getLoc();
4684 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4685 if (!ParseRes.isSuccess())
4689 if (Kind != NextKind)
4690 return Error(Loc,
"mismatched register size suffix");
4692 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4693 unsigned PrevRegVal =
4694 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4695 if (!HasCalculatedStride) {
4696 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4697 : (NumRegs - (PrevRegVal - RegVal));
4698 HasCalculatedStride =
true;
4702 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4703 return Error(Loc,
"registers must have the same sequential stride");
4714 return Error(S,
"invalid number of vectors");
4716 unsigned NumElements = 0;
4717 unsigned ElementWidth = 0;
4718 if (!
Kind.empty()) {
4720 std::tie(NumElements, ElementWidth) = *VK;
4723 Operands.
push_back(AArch64Operand::CreateVectorList(
4724 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4728 ParseStatus Res = tryParseVectorIndex(Operands);
4738bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4739 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4740 if (!ParseRes.isSuccess())
4743 return tryParseVectorIndex(Operands).isFailure();
4746ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4747 SMLoc StartLoc = getLoc();
4750 ParseStatus Res = tryParseScalarRegister(RegNum);
4755 Operands.
push_back(AArch64Operand::CreateReg(
4756 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4763 return Error(getLoc(),
"index must be absent or #0");
4765 const MCExpr *ImmVal;
4768 return Error(getLoc(),
"index must be absent or #0");
4770 Operands.
push_back(AArch64Operand::CreateReg(
4771 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4775ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
4776 SMLoc StartLoc = getLoc();
4777 const AsmToken &Tok = getTok();
4780 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4785 Operands.
push_back(AArch64Operand::CreateReg(
4786 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4792 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4793 const MCExpr *ImmVal;
4794 if (getParser().parseExpression(ImmVal))
4798 return TokError(
"immediate value expected for vector index");
4799 Operands.
push_back(AArch64Operand::CreateImm(
4803 if (parseOptionalMulOperand(Operands))
4808 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4813template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4814ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
4815 SMLoc StartLoc = getLoc();
4818 ParseStatus Res = tryParseScalarRegister(RegNum);
4824 Operands.
push_back(AArch64Operand::CreateReg(
4825 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4834 Res = tryParseOptionalShiftExtend(ExtOpnd);
4838 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4839 Operands.
push_back(AArch64Operand::CreateReg(
4840 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4841 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4842 Ext->hasShiftExtendAmount()));
4847bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
4848 MCAsmParser &Parser = getParser();
4856 if (!getTok().getString().equals_insensitive(
"mul") ||
4857 !(NextIsVL || NextIsHash))
4861 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4866 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4876 const MCExpr *ImmVal;
4879 Operands.
push_back(AArch64Operand::CreateImm(
4886 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4889bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
4890 StringRef &VecGroup) {
4891 MCAsmParser &Parser = getParser();
4892 auto Tok = Parser.
getTok();
4897 .Case(
"vgx2",
"vgx2")
4898 .Case(
"vgx4",
"vgx4")
4909bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
4910 auto Tok = getTok();
4917 .Case(
"csync",
"csync")
4920 .Case(
"keep",
"keep")
4924 .Case(
"strm",
"strm")
4936bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
4937 bool invertCondCode) {
4938 MCAsmParser &Parser = getParser();
4941 MatchOperandParserImpl(Operands, Mnemonic,
true);
4955 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4957 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
4960 getLexer().UnLex(SavedTok);
4964 switch (getLexer().getKind()) {
4968 if (parseSymbolicImmVal(Expr))
4969 return Error(S,
"invalid operand");
4973 return parseOptionalShiftExtend(getTok());
4977 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4982 return parseOperand(Operands,
false,
false);
4985 if (!parseNeonVectorList(Operands))
4989 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
4994 return parseOperand(Operands,
false,
false);
4999 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5001 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5009 if (!parseRegister(Operands)) {
5011 AsmToken SavedTok = getTok();
5016 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5020 Res = tryParseOptionalShiftExtend(Operands);
5023 getLexer().UnLex(SavedTok);
5030 if (!parseOptionalMulOperand(Operands))
5035 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5036 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5037 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh")
5038 return parseKeywordOperand(Operands);
5042 const MCExpr *IdVal, *
Term;
5044 if (getParser().parseExpression(IdVal))
5046 if (getParser().parseAtSpecifier(IdVal,
E))
5048 std::optional<MCBinaryExpr::Opcode> Opcode;
5054 if (getParser().parsePrimaryExpr(Term,
E))
5061 return parseOptionalShiftExtend(getTok());
5072 bool isNegative =
false;
5084 const AsmToken &Tok = getTok();
5087 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5088 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5089 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5090 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5091 return TokError(
"unexpected floating point literal");
5092 else if (IntVal != 0 || isNegative)
5093 return TokError(
"expected floating-point constant #0.0");
5101 const MCExpr *ImmVal;
5102 if (parseSymbolicImmVal(ImmVal))
5109 return parseOptionalShiftExtend(Tok);
5112 SMLoc Loc = getLoc();
5113 if (Mnemonic !=
"ldr")
5114 return TokError(
"unexpected token in operand");
5116 const MCExpr *SubExprVal;
5117 if (getParser().parseExpression(SubExprVal))
5120 if (Operands.
size() < 2 ||
5121 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5122 return Error(Loc,
"Only valid when first operand is register");
5124 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5125 .contains(Operands[1]->
getReg());
5132 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5137 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5138 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5139 Operands.
push_back(AArch64Operand::CreateImm(
5143 ShiftAmt,
true, S,
E, Ctx));
5146 APInt Simm = APInt(64, Imm << ShiftAmt);
5149 return Error(Loc,
"Immediate too large for register");
5152 const MCExpr *CPLoc =
5153 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5154 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5160bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5161 const MCExpr *Expr =
nullptr;
5163 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5166 if (check(!
Value, L,
"expected constant expression"))
5168 Out =
Value->getValue();
5172bool AArch64AsmParser::parseComma() {
5180bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5184 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5189 unsigned RangeEnd =
Last;
5190 if (
Base == AArch64::X0) {
5191 if (
Last == AArch64::FP) {
5192 RangeEnd = AArch64::X28;
5193 if (
Reg == AArch64::FP) {
5198 if (
Last == AArch64::LR) {
5199 RangeEnd = AArch64::X28;
5200 if (
Reg == AArch64::FP) {
5203 }
else if (
Reg == AArch64::LR) {
5211 Twine(
"expected register in range ") +
5219bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5220 const MCParsedAsmOperand &Op2)
const {
5221 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5222 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5224 if (AOp1.isVectorList() && AOp2.isVectorList())
5225 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5226 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5227 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5229 if (!AOp1.isReg() || !AOp2.isReg())
5232 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5233 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5236 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5237 "Testing equality of non-scalar registers not supported");
5240 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5242 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5244 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5246 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5253bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5254 StringRef Name, SMLoc NameLoc,
5256 Name = StringSwitch<StringRef>(
Name.lower())
5257 .Case(
"beq",
"b.eq")
5258 .Case(
"bne",
"b.ne")
5259 .Case(
"bhs",
"b.hs")
5260 .Case(
"bcs",
"b.cs")
5261 .Case(
"blo",
"b.lo")
5262 .Case(
"bcc",
"b.cc")
5263 .Case(
"bmi",
"b.mi")
5264 .Case(
"bpl",
"b.pl")
5265 .Case(
"bvs",
"b.vs")
5266 .Case(
"bvc",
"b.vc")
5267 .Case(
"bhi",
"b.hi")
5268 .Case(
"bls",
"b.ls")
5269 .Case(
"bge",
"b.ge")
5270 .Case(
"blt",
"b.lt")
5271 .Case(
"bgt",
"b.gt")
5272 .Case(
"ble",
"b.le")
5273 .Case(
"bal",
"b.al")
5274 .Case(
"bnv",
"b.nv")
5279 getTok().getIdentifier().lower() ==
".req") {
5280 parseDirectiveReq(Name, NameLoc);
5288 StringRef Head =
Name.slice(Start,
Next);
5292 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5293 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5294 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5295 return parseSysAlias(Head, NameLoc, Operands);
5299 return parseSyslAlias(Head, NameLoc, Operands);
5302 if (Head ==
"tlbip")
5303 return parseSyspAlias(Head, NameLoc, Operands);
5312 Head =
Name.slice(Start + 1,
Next);
5316 std::string Suggestion;
5319 std::string
Msg =
"invalid condition code";
5320 if (!Suggestion.empty())
5321 Msg +=
", did you mean " + Suggestion +
"?";
5327 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5337 Operands.
push_back(AArch64Operand::CreateToken(
5343 bool condCodeFourthOperand =
5344 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5345 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5346 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5354 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5355 bool condCodeThirdOperand =
5356 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5364 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5365 (
N == 3 && condCodeThirdOperand) ||
5366 (
N == 2 && condCodeSecondOperand),
5367 condCodeSecondOperand || condCodeThirdOperand)) {
5387 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5390 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5393 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5406 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5407 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5408 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5409 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5410 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5411 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5412 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5424bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5425 SmallVectorImpl<SMLoc> &Loc) {
5426 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5433 PrefixInfo
Prefix = NextPrefix;
5434 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5445 return Error(IDLoc,
"instruction is unpredictable when following a"
5446 " movprfx, suggest replacing movprfx with mov");
5450 return Error(Loc[0],
"instruction is unpredictable when following a"
5451 " movprfx writing to a different destination");
5458 return Error(Loc[0],
"instruction is unpredictable when following a"
5459 " movprfx and destination also used as non-destructive"
5463 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5464 if (
Prefix.isPredicated()) {
5478 return Error(IDLoc,
"instruction is unpredictable when following a"
5479 " predicated movprfx, suggest using unpredicated movprfx");
5483 return Error(IDLoc,
"instruction is unpredictable when following a"
5484 " predicated movprfx using a different general predicate");
5488 return Error(IDLoc,
"instruction is unpredictable when following a"
5489 " predicated movprfx with a different element size");
5495 if (IsWindowsArm64EC) {
5501 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5502 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5503 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5504 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5505 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5506 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5507 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5508 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5509 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5510 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5512 " is disallowed on ARM64EC.");
5522 case AArch64::LDPSWpre:
5523 case AArch64::LDPWpost:
5524 case AArch64::LDPWpre:
5525 case AArch64::LDPXpost:
5526 case AArch64::LDPXpre: {
5531 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5532 "is also a destination");
5534 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5535 "is also a destination");
5538 case AArch64::LDR_ZA:
5539 case AArch64::STR_ZA: {
5542 return Error(Loc[1],
5543 "unpredictable instruction, immediate and offset mismatch.");
5546 case AArch64::LDPDi:
5547 case AArch64::LDPQi:
5548 case AArch64::LDPSi:
5549 case AArch64::LDPSWi:
5550 case AArch64::LDPWi:
5551 case AArch64::LDPXi: {
5555 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5558 case AArch64::LDPDpost:
5559 case AArch64::LDPDpre:
5560 case AArch64::LDPQpost:
5561 case AArch64::LDPQpre:
5562 case AArch64::LDPSpost:
5563 case AArch64::LDPSpre:
5564 case AArch64::LDPSWpost: {
5568 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5571 case AArch64::STPDpost:
5572 case AArch64::STPDpre:
5573 case AArch64::STPQpost:
5574 case AArch64::STPQpre:
5575 case AArch64::STPSpost:
5576 case AArch64::STPSpre:
5577 case AArch64::STPWpost:
5578 case AArch64::STPWpre:
5579 case AArch64::STPXpost:
5580 case AArch64::STPXpre: {
5585 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5586 "is also a source");
5588 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5589 "is also a source");
5592 case AArch64::LDRBBpre:
5593 case AArch64::LDRBpre:
5594 case AArch64::LDRHHpre:
5595 case AArch64::LDRHpre:
5596 case AArch64::LDRSBWpre:
5597 case AArch64::LDRSBXpre:
5598 case AArch64::LDRSHWpre:
5599 case AArch64::LDRSHXpre:
5600 case AArch64::LDRSWpre:
5601 case AArch64::LDRWpre:
5602 case AArch64::LDRXpre:
5603 case AArch64::LDRBBpost:
5604 case AArch64::LDRBpost:
5605 case AArch64::LDRHHpost:
5606 case AArch64::LDRHpost:
5607 case AArch64::LDRSBWpost:
5608 case AArch64::LDRSBXpost:
5609 case AArch64::LDRSHWpost:
5610 case AArch64::LDRSHXpost:
5611 case AArch64::LDRSWpost:
5612 case AArch64::LDRWpost:
5613 case AArch64::LDRXpost: {
5617 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5618 "is also a source");
5621 case AArch64::STRBBpost:
5622 case AArch64::STRBpost:
5623 case AArch64::STRHHpost:
5624 case AArch64::STRHpost:
5625 case AArch64::STRWpost:
5626 case AArch64::STRXpost:
5627 case AArch64::STRBBpre:
5628 case AArch64::STRBpre:
5629 case AArch64::STRHHpre:
5630 case AArch64::STRHpre:
5631 case AArch64::STRWpre:
5632 case AArch64::STRXpre: {
5636 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5637 "is also a source");
5640 case AArch64::STXRB:
5641 case AArch64::STXRH:
5642 case AArch64::STXRW:
5643 case AArch64::STXRX:
5644 case AArch64::STLXRB:
5645 case AArch64::STLXRH:
5646 case AArch64::STLXRW:
5647 case AArch64::STLXRX: {
5653 return Error(Loc[0],
5654 "unpredictable STXR instruction, status is also a source");
5657 case AArch64::STXPW:
5658 case AArch64::STXPX:
5659 case AArch64::STLXPW:
5660 case AArch64::STLXPX: {
5667 return Error(Loc[0],
5668 "unpredictable STXP instruction, status is also a source");
5671 case AArch64::LDRABwriteback:
5672 case AArch64::LDRAAwriteback: {
5676 return Error(Loc[0],
5677 "unpredictable LDRA instruction, writeback base"
5678 " is also a destination");
5685 case AArch64::CPYFP:
5686 case AArch64::CPYFPWN:
5687 case AArch64::CPYFPRN:
5688 case AArch64::CPYFPN:
5689 case AArch64::CPYFPWT:
5690 case AArch64::CPYFPWTWN:
5691 case AArch64::CPYFPWTRN:
5692 case AArch64::CPYFPWTN:
5693 case AArch64::CPYFPRT:
5694 case AArch64::CPYFPRTWN:
5695 case AArch64::CPYFPRTRN:
5696 case AArch64::CPYFPRTN:
5697 case AArch64::CPYFPT:
5698 case AArch64::CPYFPTWN:
5699 case AArch64::CPYFPTRN:
5700 case AArch64::CPYFPTN:
5701 case AArch64::CPYFM:
5702 case AArch64::CPYFMWN:
5703 case AArch64::CPYFMRN:
5704 case AArch64::CPYFMN:
5705 case AArch64::CPYFMWT:
5706 case AArch64::CPYFMWTWN:
5707 case AArch64::CPYFMWTRN:
5708 case AArch64::CPYFMWTN:
5709 case AArch64::CPYFMRT:
5710 case AArch64::CPYFMRTWN:
5711 case AArch64::CPYFMRTRN:
5712 case AArch64::CPYFMRTN:
5713 case AArch64::CPYFMT:
5714 case AArch64::CPYFMTWN:
5715 case AArch64::CPYFMTRN:
5716 case AArch64::CPYFMTN:
5717 case AArch64::CPYFE:
5718 case AArch64::CPYFEWN:
5719 case AArch64::CPYFERN:
5720 case AArch64::CPYFEN:
5721 case AArch64::CPYFEWT:
5722 case AArch64::CPYFEWTWN:
5723 case AArch64::CPYFEWTRN:
5724 case AArch64::CPYFEWTN:
5725 case AArch64::CPYFERT:
5726 case AArch64::CPYFERTWN:
5727 case AArch64::CPYFERTRN:
5728 case AArch64::CPYFERTN:
5729 case AArch64::CPYFET:
5730 case AArch64::CPYFETWN:
5731 case AArch64::CPYFETRN:
5732 case AArch64::CPYFETN:
5734 case AArch64::CPYPWN:
5735 case AArch64::CPYPRN:
5736 case AArch64::CPYPN:
5737 case AArch64::CPYPWT:
5738 case AArch64::CPYPWTWN:
5739 case AArch64::CPYPWTRN:
5740 case AArch64::CPYPWTN:
5741 case AArch64::CPYPRT:
5742 case AArch64::CPYPRTWN:
5743 case AArch64::CPYPRTRN:
5744 case AArch64::CPYPRTN:
5745 case AArch64::CPYPT:
5746 case AArch64::CPYPTWN:
5747 case AArch64::CPYPTRN:
5748 case AArch64::CPYPTN:
5750 case AArch64::CPYMWN:
5751 case AArch64::CPYMRN:
5752 case AArch64::CPYMN:
5753 case AArch64::CPYMWT:
5754 case AArch64::CPYMWTWN:
5755 case AArch64::CPYMWTRN:
5756 case AArch64::CPYMWTN:
5757 case AArch64::CPYMRT:
5758 case AArch64::CPYMRTWN:
5759 case AArch64::CPYMRTRN:
5760 case AArch64::CPYMRTN:
5761 case AArch64::CPYMT:
5762 case AArch64::CPYMTWN:
5763 case AArch64::CPYMTRN:
5764 case AArch64::CPYMTN:
5766 case AArch64::CPYEWN:
5767 case AArch64::CPYERN:
5768 case AArch64::CPYEN:
5769 case AArch64::CPYEWT:
5770 case AArch64::CPYEWTWN:
5771 case AArch64::CPYEWTRN:
5772 case AArch64::CPYEWTN:
5773 case AArch64::CPYERT:
5774 case AArch64::CPYERTWN:
5775 case AArch64::CPYERTRN:
5776 case AArch64::CPYERTN:
5777 case AArch64::CPYET:
5778 case AArch64::CPYETWN:
5779 case AArch64::CPYETRN:
5780 case AArch64::CPYETN: {
5791 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5792 " registers are the same");
5794 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5795 " registers are the same");
5797 return Error(Loc[0],
"invalid CPY instruction, source and size"
5798 " registers are the same");
5802 case AArch64::SETPT:
5803 case AArch64::SETPN:
5804 case AArch64::SETPTN:
5806 case AArch64::SETMT:
5807 case AArch64::SETMN:
5808 case AArch64::SETMTN:
5810 case AArch64::SETET:
5811 case AArch64::SETEN:
5812 case AArch64::SETETN:
5813 case AArch64::SETGP:
5814 case AArch64::SETGPT:
5815 case AArch64::SETGPN:
5816 case AArch64::SETGPTN:
5817 case AArch64::SETGM:
5818 case AArch64::SETGMT:
5819 case AArch64::SETGMN:
5820 case AArch64::SETGMTN:
5821 case AArch64::MOPSSETGE:
5822 case AArch64::MOPSSETGET:
5823 case AArch64::MOPSSETGEN:
5824 case AArch64::MOPSSETGETN: {
5834 return Error(Loc[0],
"invalid SET instruction, destination and size"
5835 " registers are the same");
5837 return Error(Loc[0],
"invalid SET instruction, destination and source"
5838 " registers are the same");
5840 return Error(Loc[0],
"invalid SET instruction, source and size"
5841 " registers are the same");
5844 case AArch64::SETGOP:
5845 case AArch64::SETGOPT:
5846 case AArch64::SETGOPN:
5847 case AArch64::SETGOPTN:
5848 case AArch64::SETGOM:
5849 case AArch64::SETGOMT:
5850 case AArch64::SETGOMN:
5851 case AArch64::SETGOMTN:
5852 case AArch64::SETGOE:
5853 case AArch64::SETGOET:
5854 case AArch64::SETGOEN:
5855 case AArch64::SETGOETN: {
5864 return Error(Loc[0],
"invalid SET instruction, destination and size"
5865 " registers are the same");
5874 case AArch64::ADDSWri:
5875 case AArch64::ADDSXri:
5876 case AArch64::ADDWri:
5877 case AArch64::ADDXri:
5878 case AArch64::SUBSWri:
5879 case AArch64::SUBSXri:
5880 case AArch64::SUBWri:
5881 case AArch64::SUBXri: {
5889 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5914 return Error(Loc.
back(),
"invalid immediate expression");
5927 unsigned VariantID = 0);
5929bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5933 case Match_InvalidTiedOperand: {
5934 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
5935 if (
Op.isVectorList())
5936 return Error(
Loc,
"operand must match destination register list");
5938 assert(
Op.isReg() &&
"Unexpected operand type");
5939 switch (
Op.getRegEqualityTy()) {
5940 case RegConstraintEqualityTy::EqualsSubReg:
5941 return Error(
Loc,
"operand must be 64-bit form of destination register");
5942 case RegConstraintEqualityTy::EqualsSuperReg:
5943 return Error(
Loc,
"operand must be 32-bit form of destination register");
5944 case RegConstraintEqualityTy::EqualsReg:
5945 return Error(
Loc,
"operand must match destination register");
5949 case Match_MissingFeature:
5951 "instruction requires a CPU feature not currently enabled");
5952 case Match_InvalidOperand:
5953 return Error(Loc,
"invalid operand for instruction");
5954 case Match_InvalidSuffix:
5955 return Error(Loc,
"invalid type suffix for instruction");
5956 case Match_InvalidCondCode:
5957 return Error(Loc,
"expected AArch64 condition code");
5958 case Match_AddSubRegExtendSmall:
5960 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5961 case Match_AddSubRegExtendLarge:
5963 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5964 case Match_AddSubSecondSource:
5966 "expected compatible register, symbol or integer in range [0, 4095]");
5967 case Match_LogicalSecondSource:
5968 return Error(Loc,
"expected compatible register or logical immediate");
5969 case Match_InvalidMovImm32Shift:
5970 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5971 case Match_InvalidMovImm64Shift:
5972 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5973 case Match_AddSubRegShift32:
5975 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5976 case Match_AddSubRegShift64:
5978 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5979 case Match_InvalidFPImm:
5981 "expected compatible register or floating-point constant");
5982 case Match_InvalidMemoryIndexedSImm6:
5983 return Error(Loc,
"index must be an integer in range [-32, 31].");
5984 case Match_InvalidMemoryIndexedSImm5:
5985 return Error(Loc,
"index must be an integer in range [-16, 15].");
5986 case Match_InvalidMemoryIndexed1SImm4:
5987 return Error(Loc,
"index must be an integer in range [-8, 7].");
5988 case Match_InvalidMemoryIndexed2SImm4:
5989 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5990 case Match_InvalidMemoryIndexed3SImm4:
5991 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5992 case Match_InvalidMemoryIndexed4SImm4:
5993 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5994 case Match_InvalidMemoryIndexed16SImm4:
5995 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5996 case Match_InvalidMemoryIndexed32SImm4:
5997 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5998 case Match_InvalidMemoryIndexed1SImm6:
5999 return Error(Loc,
"index must be an integer in range [-32, 31].");
6000 case Match_InvalidMemoryIndexedSImm8:
6001 return Error(Loc,
"index must be an integer in range [-128, 127].");
6002 case Match_InvalidMemoryIndexedSImm9:
6003 return Error(Loc,
"index must be an integer in range [-256, 255].");
6004 case Match_InvalidMemoryIndexed16SImm9:
6005 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6006 case Match_InvalidMemoryIndexed8SImm10:
6007 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6008 case Match_InvalidMemoryIndexed4SImm7:
6009 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6010 case Match_InvalidMemoryIndexed8SImm7:
6011 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6012 case Match_InvalidMemoryIndexed16SImm7:
6013 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6014 case Match_InvalidMemoryIndexed8UImm5:
6015 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6016 case Match_InvalidMemoryIndexed8UImm3:
6017 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6018 case Match_InvalidMemoryIndexed4UImm5:
6019 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6020 case Match_InvalidMemoryIndexed2UImm5:
6021 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6022 case Match_InvalidMemoryIndexed8UImm6:
6023 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6024 case Match_InvalidMemoryIndexed16UImm6:
6025 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6026 case Match_InvalidMemoryIndexed4UImm6:
6027 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6028 case Match_InvalidMemoryIndexed2UImm6:
6029 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6030 case Match_InvalidMemoryIndexed1UImm6:
6031 return Error(Loc,
"index must be in range [0, 63].");
6032 case Match_InvalidMemoryWExtend8:
6034 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6035 case Match_InvalidMemoryWExtend16:
6037 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6038 case Match_InvalidMemoryWExtend32:
6040 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6041 case Match_InvalidMemoryWExtend64:
6043 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6044 case Match_InvalidMemoryWExtend128:
6046 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6047 case Match_InvalidMemoryXExtend8:
6049 "expected 'lsl' or 'sxtx' with optional shift of #0");
6050 case Match_InvalidMemoryXExtend16:
6052 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6053 case Match_InvalidMemoryXExtend32:
6055 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6056 case Match_InvalidMemoryXExtend64:
6058 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6059 case Match_InvalidMemoryXExtend128:
6061 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6062 case Match_InvalidMemoryIndexed1:
6063 return Error(Loc,
"index must be an integer in range [0, 4095].");
6064 case Match_InvalidMemoryIndexed2:
6065 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6066 case Match_InvalidMemoryIndexed4:
6067 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6068 case Match_InvalidMemoryIndexed8:
6069 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6070 case Match_InvalidMemoryIndexed16:
6071 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6072 case Match_InvalidImm0_0:
6073 return Error(Loc,
"immediate must be 0.");
6074 case Match_InvalidImm0_1:
6075 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6076 case Match_InvalidImm0_3:
6077 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6078 case Match_InvalidImm0_7:
6079 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6080 case Match_InvalidImm0_15:
6081 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6082 case Match_InvalidImm0_31:
6083 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6084 case Match_InvalidImm0_63:
6085 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6086 case Match_InvalidImm0_127:
6087 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6088 case Match_InvalidImm0_255:
6089 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6090 case Match_InvalidImm0_65535:
6091 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6092 case Match_InvalidHinteUImm16:
6094 "immediate must be an integer in range [0, 65535], excluding "
6095 "values in range [12319, 16383] where (value - 12319) is a "
6097 case Match_InvalidImm1_8:
6098 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6099 case Match_InvalidImm1_16:
6100 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6101 case Match_InvalidImm1_32:
6102 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6103 case Match_InvalidImm1_64:
6104 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6105 case Match_InvalidImmM1_62:
6106 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6107 case Match_InvalidMemoryIndexedRange2UImm0:
6108 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6109 case Match_InvalidMemoryIndexedRange2UImm1:
6110 return Error(Loc,
"vector select offset must be an immediate range of the "
6111 "form <immf>:<imml>, where the first "
6112 "immediate is a multiple of 2 in the range [0, 2], and "
6113 "the second immediate is immf + 1.");
6114 case Match_InvalidMemoryIndexedRange2UImm2:
6115 case Match_InvalidMemoryIndexedRange2UImm3:
6118 "vector select offset must be an immediate range of the form "
6120 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6122 "depending on the instruction, and the second immediate is immf + 1.");
6123 case Match_InvalidMemoryIndexedRange4UImm0:
6124 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6125 case Match_InvalidMemoryIndexedRange4UImm1:
6126 case Match_InvalidMemoryIndexedRange4UImm2:
6129 "vector select offset must be an immediate range of the form "
6131 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6133 "depending on the instruction, and the second immediate is immf + 3.");
6134 case Match_InvalidSVEAddSubImm8:
6135 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6136 " with a shift amount of 0");
6137 case Match_InvalidSVEAddSubImm16:
6138 case Match_InvalidSVEAddSubImm32:
6139 case Match_InvalidSVEAddSubImm64:
6140 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6141 "multiple of 256 in range [256, 65280]");
6142 case Match_InvalidSVECpyImm8:
6143 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6144 " with a shift amount of 0");
6145 case Match_InvalidSVECpyImm16:
6146 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6147 "multiple of 256 in range [-32768, 65280]");
6148 case Match_InvalidSVECpyImm32:
6149 case Match_InvalidSVECpyImm64:
6150 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6151 "multiple of 256 in range [-32768, 32512]");
6152 case Match_InvalidIndexRange0_0:
6153 return Error(Loc,
"expected lane specifier '[0]'");
6154 case Match_InvalidIndexRange1_1:
6155 return Error(Loc,
"expected lane specifier '[1]'");
6156 case Match_InvalidIndexRange0_15:
6157 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6158 case Match_InvalidIndexRange0_7:
6159 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6160 case Match_InvalidIndexRange0_3:
6161 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6162 case Match_InvalidIndexRange0_1:
6163 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6164 case Match_InvalidSVEIndexRange0_63:
6165 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6166 case Match_InvalidSVEIndexRange0_31:
6167 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6168 case Match_InvalidSVEIndexRange0_15:
6169 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6170 case Match_InvalidSVEIndexRange0_7:
6171 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6172 case Match_InvalidSVEIndexRange0_3:
6173 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6174 case Match_InvalidLabel:
6175 return Error(Loc,
"expected label or encodable integer pc offset");
6177 return Error(Loc,
"expected readable system register");
6179 case Match_InvalidSVCR:
6180 return Error(Loc,
"expected writable system register or pstate");
6181 case Match_InvalidComplexRotationEven:
6182 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6183 case Match_InvalidComplexRotationOdd:
6184 return Error(Loc,
"complex rotation must be 90 or 270.");
6185 case Match_MnemonicFail: {
6187 ((AArch64Operand &)*Operands[0]).
getToken(),
6188 ComputeAvailableFeatures(STI->getFeatureBits()));
6189 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6191 case Match_InvalidGPR64shifted8:
6192 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6193 case Match_InvalidGPR64shifted16:
6194 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6195 case Match_InvalidGPR64shifted32:
6196 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6197 case Match_InvalidGPR64shifted64:
6198 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6199 case Match_InvalidGPR64shifted128:
6201 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6202 case Match_InvalidGPR64NoXZRshifted8:
6203 return Error(Loc,
"register must be x0..x30 without shift");
6204 case Match_InvalidGPR64NoXZRshifted16:
6205 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6206 case Match_InvalidGPR64NoXZRshifted32:
6207 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6208 case Match_InvalidGPR64NoXZRshifted64:
6209 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6210 case Match_InvalidGPR64NoXZRshifted128:
6211 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6212 case Match_InvalidZPR32UXTW8:
6213 case Match_InvalidZPR32SXTW8:
6214 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6215 case Match_InvalidZPR32UXTW16:
6216 case Match_InvalidZPR32SXTW16:
6217 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6218 case Match_InvalidZPR32UXTW32:
6219 case Match_InvalidZPR32SXTW32:
6220 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6221 case Match_InvalidZPR32UXTW64:
6222 case Match_InvalidZPR32SXTW64:
6223 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6224 case Match_InvalidZPR64UXTW8:
6225 case Match_InvalidZPR64SXTW8:
6226 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6227 case Match_InvalidZPR64UXTW16:
6228 case Match_InvalidZPR64SXTW16:
6229 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6230 case Match_InvalidZPR64UXTW32:
6231 case Match_InvalidZPR64SXTW32:
6232 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6233 case Match_InvalidZPR64UXTW64:
6234 case Match_InvalidZPR64SXTW64:
6235 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6236 case Match_InvalidZPR32LSL8:
6237 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6238 case Match_InvalidZPR32LSL16:
6239 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6240 case Match_InvalidZPR32LSL32:
6241 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6242 case Match_InvalidZPR32LSL64:
6243 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6244 case Match_InvalidZPR64LSL8:
6245 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6246 case Match_InvalidZPR64LSL16:
6247 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6248 case Match_InvalidZPR64LSL32:
6249 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6250 case Match_InvalidZPR64LSL64:
6251 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6252 case Match_InvalidZPR0:
6253 return Error(Loc,
"expected register without element width suffix");
6254 case Match_InvalidZPR8:
6255 case Match_InvalidZPR16:
6256 case Match_InvalidZPR32:
6257 case Match_InvalidZPR64:
6258 case Match_InvalidZPR128:
6259 return Error(Loc,
"invalid element width");
6260 case Match_InvalidZPR_3b8:
6261 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6262 case Match_InvalidZPR_3b16:
6263 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6264 case Match_InvalidZPR_3b32:
6265 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6266 case Match_InvalidZPR_4b8:
6268 "Invalid restricted vector register, expected z0.b..z15.b");
6269 case Match_InvalidZPR_4b16:
6270 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6271 case Match_InvalidZPR_4b32:
6272 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6273 case Match_InvalidZPR_4b64:
6274 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6275 case Match_InvalidZPRMul2_Lo8:
6276 return Error(Loc,
"Invalid restricted vector register, expected even "
6277 "register in z0.b..z14.b");
6278 case Match_InvalidZPRMul2_Hi8:
6279 return Error(Loc,
"Invalid restricted vector register, expected even "
6280 "register in z16.b..z30.b");
6281 case Match_InvalidZPRMul2_Lo16:
6282 return Error(Loc,
"Invalid restricted vector register, expected even "
6283 "register in z0.h..z14.h");
6284 case Match_InvalidZPRMul2_Hi16:
6285 return Error(Loc,
"Invalid restricted vector register, expected even "
6286 "register in z16.h..z30.h");
6287 case Match_InvalidZPRMul2_Lo32:
6288 return Error(Loc,
"Invalid restricted vector register, expected even "
6289 "register in z0.s..z14.s");
6290 case Match_InvalidZPRMul2_Hi32:
6291 return Error(Loc,
"Invalid restricted vector register, expected even "
6292 "register in z16.s..z30.s");
6293 case Match_InvalidZPRMul2_Lo64:
6294 return Error(Loc,
"Invalid restricted vector register, expected even "
6295 "register in z0.d..z14.d");
6296 case Match_InvalidZPRMul2_Hi64:
6297 return Error(Loc,
"Invalid restricted vector register, expected even "
6298 "register in z16.d..z30.d");
6299 case Match_InvalidZPR_K0:
6300 return Error(Loc,
"invalid restricted vector register, expected register "
6301 "in z20..z23 or z28..z31");
6302 case Match_InvalidSVEPattern:
6303 return Error(Loc,
"invalid predicate pattern");
6304 case Match_InvalidSVEPPRorPNRAnyReg:
6305 case Match_InvalidSVEPPRorPNRBReg:
6306 case Match_InvalidSVEPredicateAnyReg:
6307 case Match_InvalidSVEPredicateBReg:
6308 case Match_InvalidSVEPredicateHReg:
6309 case Match_InvalidSVEPredicateSReg:
6310 case Match_InvalidSVEPredicateDReg:
6311 return Error(Loc,
"invalid predicate register.");
6312 case Match_InvalidSVEPredicate3bAnyReg:
6313 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6314 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6315 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6316 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6317 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6318 return Error(Loc,
"Invalid predicate register, expected PN in range "
6319 "pn8..pn15 with element suffix.");
6320 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6321 return Error(Loc,
"invalid restricted predicate-as-counter register "
6322 "expected pn8..pn15");
6323 case Match_InvalidSVEPNPredicateBReg:
6324 case Match_InvalidSVEPNPredicateHReg:
6325 case Match_InvalidSVEPNPredicateSReg:
6326 case Match_InvalidSVEPNPredicateDReg:
6327 return Error(Loc,
"Invalid predicate register, expected PN in range "
6328 "pn0..pn15 with element suffix.");
6329 case Match_InvalidSVEVecLenSpecifier:
6330 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6331 case Match_InvalidSVEPredicateListMul2x8:
6332 case Match_InvalidSVEPredicateListMul2x16:
6333 case Match_InvalidSVEPredicateListMul2x32:
6334 case Match_InvalidSVEPredicateListMul2x64:
6335 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6336 "predicate registers, where the first vector is a multiple of 2 "
6337 "and with correct element type");
6338 case Match_InvalidSVEExactFPImmOperandHalfOne:
6339 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6340 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6341 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6342 case Match_InvalidSVEExactFPImmOperandZeroOne:
6343 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6344 case Match_InvalidMatrixTileVectorH8:
6345 case Match_InvalidMatrixTileVectorV8:
6346 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6347 case Match_InvalidMatrixTileVectorH16:
6348 case Match_InvalidMatrixTileVectorV16:
6350 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6351 case Match_InvalidMatrixTileVectorH32:
6352 case Match_InvalidMatrixTileVectorV32:
6354 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6355 case Match_InvalidMatrixTileVectorH64:
6356 case Match_InvalidMatrixTileVectorV64:
6358 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6359 case Match_InvalidMatrixTileVectorH128:
6360 case Match_InvalidMatrixTileVectorV128:
6362 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6363 case Match_InvalidMatrixTile16:
6364 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6365 case Match_InvalidMatrixTile32:
6366 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6367 case Match_InvalidMatrixTile64:
6368 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6369 case Match_InvalidMatrix:
6370 return Error(Loc,
"invalid matrix operand, expected za");
6371 case Match_InvalidMatrix8:
6372 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6373 case Match_InvalidMatrix16:
6374 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6375 case Match_InvalidMatrix32:
6376 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6377 case Match_InvalidMatrix64:
6378 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6379 case Match_InvalidMatrixIndexGPR32_12_15:
6380 return Error(Loc,
"operand must be a register in range [w12, w15]");
6381 case Match_InvalidMatrixIndexGPR32_8_11:
6382 return Error(Loc,
"operand must be a register in range [w8, w11]");
6383 case Match_InvalidSVEVectorList2x8Mul2:
6384 case Match_InvalidSVEVectorList2x16Mul2:
6385 case Match_InvalidSVEVectorList2x32Mul2:
6386 case Match_InvalidSVEVectorList2x64Mul2:
6387 case Match_InvalidSVEVectorList2x128Mul2:
6388 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6389 "SVE vectors, where the first vector is a multiple of 2 "
6390 "and with matching element types");
6391 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6392 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6393 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6394 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6395 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6396 "SVE vectors in the range z0-z14, where the first vector "
6397 "is a multiple of 2 "
6398 "and with matching element types");
6399 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6400 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6401 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6402 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6404 "Invalid vector list, expected list with 2 consecutive "
6405 "SVE vectors in the range z16-z30, where the first vector "
6406 "is a multiple of 2 "
6407 "and with matching element types");
6408 case Match_InvalidSVEVectorList4x8Mul4:
6409 case Match_InvalidSVEVectorList4x16Mul4:
6410 case Match_InvalidSVEVectorList4x32Mul4:
6411 case Match_InvalidSVEVectorList4x64Mul4:
6412 case Match_InvalidSVEVectorList4x128Mul4:
6413 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6414 "SVE vectors, where the first vector is a multiple of 4 "
6415 "and with matching element types");
6416 case Match_InvalidSVEVectorList3x0_3b:
6417 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6418 "SVE vectors starting at z0-z7");
6419 case Match_InvalidLookupTable:
6420 return Error(Loc,
"Invalid lookup table, expected zt0");
6421 case Match_InvalidSVEVectorListStrided2x8:
6422 case Match_InvalidSVEVectorListStrided2x16:
6423 case Match_InvalidSVEVectorListStrided2x32:
6424 case Match_InvalidSVEVectorListStrided2x64:
6427 "Invalid vector list, expected list with each SVE vector in the list "
6428 "8 registers apart, and the first register in the range [z0, z7] or "
6429 "[z16, z23] and with correct element type");
6430 case Match_InvalidSVEVectorListStrided4x8:
6431 case Match_InvalidSVEVectorListStrided4x16:
6432 case Match_InvalidSVEVectorListStrided4x32:
6433 case Match_InvalidSVEVectorListStrided4x64:
6436 "Invalid vector list, expected list with each SVE vector in the list "
6437 "4 registers apart, and the first register in the range [z0, z3] or "
6438 "[z16, z19] and with correct element type");
6439 case Match_AddSubLSLImm3ShiftLarge:
6441 "expected 'lsl' with optional integer in range [0, 7]");
6449bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6453 bool MatchingInlineAsm) {
6454 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6455 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6456 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6459 unsigned NumOperands = Operands.
size();
6461 if (NumOperands == 4 && Tok ==
"lsl") {
6462 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6463 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6464 if (Op2.isScalarReg() && Op3.isImm()) {
6470 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6472 NewOp3Val = (32 - Op3Val) & 0x1f;
6473 NewOp4Val = 31 - Op3Val;
6475 NewOp3Val = (64 - Op3Val) & 0x3f;
6476 NewOp4Val = 63 - Op3Val;
6483 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6484 Operands.
push_back(AArch64Operand::CreateImm(
6485 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6486 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6490 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6492 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6493 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6494 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6496 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6500 if (LSBCE && WidthCE) {
6502 uint64_t Width = WidthCE->
getValue();
6504 uint64_t RegWidth = 0;
6505 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6511 if (LSB >= RegWidth)
6512 return Error(LSBOp.getStartLoc(),
6513 "expected integer in range [0, 31]");
6514 if (Width < 1 || Width > RegWidth)
6515 return Error(WidthOp.getStartLoc(),
6516 "expected integer in range [1, 32]");
6520 ImmR = (32 - LSB) & 0x1f;
6522 ImmR = (64 - LSB) & 0x3f;
6524 uint64_t ImmS = Width - 1;
6526 if (ImmR != 0 && ImmS >= ImmR)
6527 return Error(WidthOp.getStartLoc(),
6528 "requested insert overflows register");
6533 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6534 Operands[2] = AArch64Operand::CreateReg(
6535 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6537 Operands[3] = AArch64Operand::CreateImm(
6538 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6540 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6544 }
else if (NumOperands == 5) {
6547 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6548 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6549 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6550 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6552 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6556 if (Op3CE && Op4CE) {
6557 uint64_t Op3Val = Op3CE->
getValue();
6558 uint64_t Op4Val = Op4CE->
getValue();
6560 uint64_t RegWidth = 0;
6561 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6567 if (Op3Val >= RegWidth)
6568 return Error(Op3.getStartLoc(),
6569 "expected integer in range [0, 31]");
6570 if (Op4Val < 1 || Op4Val > RegWidth)
6571 return Error(Op4.getStartLoc(),
6572 "expected integer in range [1, 32]");
6574 uint64_t NewOp3Val = 0;
6576 NewOp3Val = (32 - Op3Val) & 0x1f;
6578 NewOp3Val = (64 - Op3Val) & 0x3f;
6580 uint64_t NewOp4Val = Op4Val - 1;
6582 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6583 return Error(Op4.getStartLoc(),
6584 "requested insert overflows register");
6586 const MCExpr *NewOp3 =
6588 const MCExpr *NewOp4 =
6590 Operands[3] = AArch64Operand::CreateImm(
6591 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6592 Operands[4] = AArch64Operand::CreateImm(
6593 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6595 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6597 else if (Tok ==
"sbfiz")
6598 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6600 else if (Tok ==
"ubfiz")
6601 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6610 }
else if (NumOperands == 5 &&
6611 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6612 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6613 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6614 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6616 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6620 if (Op3CE && Op4CE) {
6621 uint64_t Op3Val = Op3CE->
getValue();
6622 uint64_t Op4Val = Op4CE->
getValue();
6624 uint64_t RegWidth = 0;
6625 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6631 if (Op3Val >= RegWidth)
6632 return Error(Op3.getStartLoc(),
6633 "expected integer in range [0, 31]");
6634 if (Op4Val < 1 || Op4Val > RegWidth)
6635 return Error(Op4.getStartLoc(),
6636 "expected integer in range [1, 32]");
6638 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6640 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6641 return Error(Op4.getStartLoc(),
6642 "requested extract overflows register");
6644 const MCExpr *NewOp4 =
6646 Operands[4] = AArch64Operand::CreateImm(
6647 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6649 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6651 else if (Tok ==
"sbfx")
6652 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6654 else if (Tok ==
"ubfx")
6655 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6668 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6669 NumOperands == 4 && Tok ==
"movi") {
6670 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6671 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6672 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6673 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6674 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6675 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6676 if (Suffix.
lower() ==
".2d" &&
6678 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6679 " correctly on this CPU, converting to equivalent movi.16b");
6681 unsigned Idx = Op1.isToken() ? 1 : 2;
6683 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6691 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6694 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6695 if (
Op.isScalarReg()) {
6697 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6698 Op.getStartLoc(),
Op.getEndLoc(),
6703 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6704 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6705 if (
Op.isScalarReg() &&
6706 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6710 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6711 if (
Op.isScalarReg()) {
6713 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6720 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6721 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6722 if (
Op.isScalarReg() &&
6723 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6727 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6728 if (
Op.isScalarReg()) {
6730 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6738 FeatureBitset MissingFeatures;
6741 unsigned MatchResult =
6742 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6743 MatchingInlineAsm, 1);
6747 if (MatchResult != Match_Success) {
6750 auto ShortFormNEONErrorInfo = ErrorInfo;
6751 auto ShortFormNEONMatchResult = MatchResult;
6752 auto ShortFormNEONMissingFeatures = MissingFeatures;
6755 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6756 MatchingInlineAsm, 0);
6761 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6762 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6763 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6764 MatchResult = ShortFormNEONMatchResult;
6765 ErrorInfo = ShortFormNEONErrorInfo;
6766 MissingFeatures = ShortFormNEONMissingFeatures;
6770 switch (MatchResult) {
6771 case Match_Success: {
6774 NumOperands = Operands.
size();
6775 for (
unsigned i = 1; i < NumOperands; ++i)
6776 OperandLocs.
push_back(Operands[i]->getStartLoc());
6777 if (validateInstruction(Inst, IDLoc, OperandLocs))
6784 case Match_MissingFeature: {
6785 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6788 std::string
Msg =
"instruction requires:";
6789 for (
unsigned Feature : MissingFeatures) {
6795 case Match_MnemonicFail:
6796 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
6797 case Match_InvalidOperand: {
6798 SMLoc ErrorLoc = IDLoc;
6800 if (ErrorInfo != ~0ULL) {
6801 if (ErrorInfo >= Operands.
size())
6802 return Error(IDLoc,
"too few operands for instruction",
6803 SMRange(IDLoc, getTok().getLoc()));
6805 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
6806 if (ErrorLoc == SMLoc())
6811 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
6812 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
6813 MatchResult = Match_InvalidSuffix;
6815 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
6817 case Match_InvalidTiedOperand:
6818 case Match_InvalidMemoryIndexed1:
6819 case Match_InvalidMemoryIndexed2:
6820 case Match_InvalidMemoryIndexed4:
6821 case Match_InvalidMemoryIndexed8:
6822 case Match_InvalidMemoryIndexed16:
6823 case Match_InvalidCondCode:
6824 case Match_AddSubLSLImm3ShiftLarge:
6825 case Match_AddSubRegExtendSmall:
6826 case Match_AddSubRegExtendLarge:
6827 case Match_AddSubSecondSource:
6828 case Match_LogicalSecondSource:
6829 case Match_AddSubRegShift32:
6830 case Match_AddSubRegShift64:
6831 case Match_InvalidMovImm32Shift:
6832 case Match_InvalidMovImm64Shift:
6833 case Match_InvalidFPImm:
6834 case Match_InvalidMemoryWExtend8:
6835 case Match_InvalidMemoryWExtend16:
6836 case Match_InvalidMemoryWExtend32:
6837 case Match_InvalidMemoryWExtend64:
6838 case Match_InvalidMemoryWExtend128:
6839 case Match_InvalidMemoryXExtend8:
6840 case Match_InvalidMemoryXExtend16:
6841 case Match_InvalidMemoryXExtend32:
6842 case Match_InvalidMemoryXExtend64:
6843 case Match_InvalidMemoryXExtend128:
6844 case Match_InvalidMemoryIndexed1SImm4:
6845 case Match_InvalidMemoryIndexed2SImm4:
6846 case Match_InvalidMemoryIndexed3SImm4:
6847 case Match_InvalidMemoryIndexed4SImm4:
6848 case Match_InvalidMemoryIndexed1SImm6:
6849 case Match_InvalidMemoryIndexed16SImm4:
6850 case Match_InvalidMemoryIndexed32SImm4:
6851 case Match_InvalidMemoryIndexed4SImm7:
6852 case Match_InvalidMemoryIndexed8SImm7:
6853 case Match_InvalidMemoryIndexed16SImm7:
6854 case Match_InvalidMemoryIndexed8UImm5:
6855 case Match_InvalidMemoryIndexed8UImm3:
6856 case Match_InvalidMemoryIndexed4UImm5:
6857 case Match_InvalidMemoryIndexed2UImm5:
6858 case Match_InvalidMemoryIndexed1UImm6:
6859 case Match_InvalidMemoryIndexed2UImm6:
6860 case Match_InvalidMemoryIndexed4UImm6:
6861 case Match_InvalidMemoryIndexed8UImm6:
6862 case Match_InvalidMemoryIndexed16UImm6:
6863 case Match_InvalidMemoryIndexedSImm6:
6864 case Match_InvalidMemoryIndexedSImm5:
6865 case Match_InvalidMemoryIndexedSImm8:
6866 case Match_InvalidMemoryIndexedSImm9:
6867 case Match_InvalidMemoryIndexed16SImm9:
6868 case Match_InvalidMemoryIndexed8SImm10:
6869 case Match_InvalidImm0_0:
6870 case Match_InvalidImm0_1:
6871 case Match_InvalidImm0_3:
6872 case Match_InvalidImm0_7:
6873 case Match_InvalidImm0_15:
6874 case Match_InvalidImm0_31:
6875 case Match_InvalidImm0_63:
6876 case Match_InvalidImm0_127:
6877 case Match_InvalidImm0_255:
6878 case Match_InvalidImm0_65535:
6879 case Match_InvalidHinteUImm16:
6880 case Match_InvalidImm1_8:
6881 case Match_InvalidImm1_16:
6882 case Match_InvalidImm1_32:
6883 case Match_InvalidImm1_64:
6884 case Match_InvalidImmM1_62:
6885 case Match_InvalidMemoryIndexedRange2UImm0:
6886 case Match_InvalidMemoryIndexedRange2UImm1:
6887 case Match_InvalidMemoryIndexedRange2UImm2:
6888 case Match_InvalidMemoryIndexedRange2UImm3:
6889 case Match_InvalidMemoryIndexedRange4UImm0:
6890 case Match_InvalidMemoryIndexedRange4UImm1:
6891 case Match_InvalidMemoryIndexedRange4UImm2:
6892 case Match_InvalidSVEAddSubImm8:
6893 case Match_InvalidSVEAddSubImm16:
6894 case Match_InvalidSVEAddSubImm32:
6895 case Match_InvalidSVEAddSubImm64:
6896 case Match_InvalidSVECpyImm8:
6897 case Match_InvalidSVECpyImm16:
6898 case Match_InvalidSVECpyImm32:
6899 case Match_InvalidSVECpyImm64:
6900 case Match_InvalidIndexRange0_0:
6901 case Match_InvalidIndexRange1_1:
6902 case Match_InvalidIndexRange0_15:
6903 case Match_InvalidIndexRange0_7:
6904 case Match_InvalidIndexRange0_3:
6905 case Match_InvalidIndexRange0_1:
6906 case Match_InvalidSVEIndexRange0_63:
6907 case Match_InvalidSVEIndexRange0_31:
6908 case Match_InvalidSVEIndexRange0_15:
6909 case Match_InvalidSVEIndexRange0_7:
6910 case Match_InvalidSVEIndexRange0_3:
6911 case Match_InvalidLabel:
6912 case Match_InvalidComplexRotationEven:
6913 case Match_InvalidComplexRotationOdd:
6914 case Match_InvalidGPR64shifted8:
6915 case Match_InvalidGPR64shifted16:
6916 case Match_InvalidGPR64shifted32:
6917 case Match_InvalidGPR64shifted64:
6918 case Match_InvalidGPR64shifted128:
6919 case Match_InvalidGPR64NoXZRshifted8:
6920 case Match_InvalidGPR64NoXZRshifted16:
6921 case Match_InvalidGPR64NoXZRshifted32:
6922 case Match_InvalidGPR64NoXZRshifted64:
6923 case Match_InvalidGPR64NoXZRshifted128:
6924 case Match_InvalidZPR32UXTW8:
6925 case Match_InvalidZPR32UXTW16:
6926 case Match_InvalidZPR32UXTW32:
6927 case Match_InvalidZPR32UXTW64:
6928 case Match_InvalidZPR32SXTW8:
6929 case Match_InvalidZPR32SXTW16:
6930 case Match_InvalidZPR32SXTW32:
6931 case Match_InvalidZPR32SXTW64:
6932 case Match_InvalidZPR64UXTW8:
6933 case Match_InvalidZPR64SXTW8:
6934 case Match_InvalidZPR64UXTW16:
6935 case Match_InvalidZPR64SXTW16:
6936 case Match_InvalidZPR64UXTW32:
6937 case Match_InvalidZPR64SXTW32:
6938 case Match_InvalidZPR64UXTW64:
6939 case Match_InvalidZPR64SXTW64:
6940 case Match_InvalidZPR32LSL8:
6941 case Match_InvalidZPR32LSL16:
6942 case Match_InvalidZPR32LSL32:
6943 case Match_InvalidZPR32LSL64:
6944 case Match_InvalidZPR64LSL8:
6945 case Match_InvalidZPR64LSL16:
6946 case Match_InvalidZPR64LSL32:
6947 case Match_InvalidZPR64LSL64:
6948 case Match_InvalidZPR0:
6949 case Match_InvalidZPR8:
6950 case Match_InvalidZPR16:
6951 case Match_InvalidZPR32:
6952 case Match_InvalidZPR64:
6953 case Match_InvalidZPR128:
6954 case Match_InvalidZPR_3b8:
6955 case Match_InvalidZPR_3b16:
6956 case Match_InvalidZPR_3b32:
6957 case Match_InvalidZPR_4b8:
6958 case Match_InvalidZPR_4b16:
6959 case Match_InvalidZPR_4b32:
6960 case Match_InvalidZPR_4b64:
6961 case Match_InvalidSVEPPRorPNRAnyReg:
6962 case Match_InvalidSVEPPRorPNRBReg:
6963 case Match_InvalidSVEPredicateAnyReg:
6964 case Match_InvalidSVEPattern:
6965 case Match_InvalidSVEVecLenSpecifier:
6966 case Match_InvalidSVEPredicateBReg:
6967 case Match_InvalidSVEPredicateHReg:
6968 case Match_InvalidSVEPredicateSReg:
6969 case Match_InvalidSVEPredicateDReg:
6970 case Match_InvalidSVEPredicate3bAnyReg:
6971 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6972 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6973 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6974 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6975 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6976 case Match_InvalidSVEPNPredicateBReg:
6977 case Match_InvalidSVEPNPredicateHReg:
6978 case Match_InvalidSVEPNPredicateSReg:
6979 case Match_InvalidSVEPNPredicateDReg:
6980 case Match_InvalidSVEPredicateListMul2x8:
6981 case Match_InvalidSVEPredicateListMul2x16:
6982 case Match_InvalidSVEPredicateListMul2x32:
6983 case Match_InvalidSVEPredicateListMul2x64:
6984 case Match_InvalidSVEExactFPImmOperandHalfOne:
6985 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6986 case Match_InvalidSVEExactFPImmOperandZeroOne:
6987 case Match_InvalidMatrixTile16:
6988 case Match_InvalidMatrixTile32:
6989 case Match_InvalidMatrixTile64:
6990 case Match_InvalidMatrix:
6991 case Match_InvalidMatrix8:
6992 case Match_InvalidMatrix16:
6993 case Match_InvalidMatrix32:
6994 case Match_InvalidMatrix64:
6995 case Match_InvalidMatrixTileVectorH8:
6996 case Match_InvalidMatrixTileVectorH16:
6997 case Match_InvalidMatrixTileVectorH32:
6998 case Match_InvalidMatrixTileVectorH64:
6999 case Match_InvalidMatrixTileVectorH128:
7000 case Match_InvalidMatrixTileVectorV8:
7001 case Match_InvalidMatrixTileVectorV16:
7002 case Match_InvalidMatrixTileVectorV32:
7003 case Match_InvalidMatrixTileVectorV64:
7004 case Match_InvalidMatrixTileVectorV128:
7005 case Match_InvalidSVCR:
7006 case Match_InvalidMatrixIndexGPR32_12_15:
7007 case Match_InvalidMatrixIndexGPR32_8_11:
7008 case Match_InvalidLookupTable:
7009 case Match_InvalidZPRMul2_Lo8:
7010 case Match_InvalidZPRMul2_Hi8:
7011 case Match_InvalidZPRMul2_Lo16:
7012 case Match_InvalidZPRMul2_Hi16:
7013 case Match_InvalidZPRMul2_Lo32:
7014 case Match_InvalidZPRMul2_Hi32:
7015 case Match_InvalidZPRMul2_Lo64:
7016 case Match_InvalidZPRMul2_Hi64:
7017 case Match_InvalidZPR_K0:
7018 case Match_InvalidSVEVectorList2x8Mul2:
7019 case Match_InvalidSVEVectorList2x16Mul2:
7020 case Match_InvalidSVEVectorList2x32Mul2:
7021 case Match_InvalidSVEVectorList2x64Mul2:
7022 case Match_InvalidSVEVectorList2x128Mul2:
7023 case Match_InvalidSVEVectorList4x8Mul4:
7024 case Match_InvalidSVEVectorList4x16Mul4:
7025 case Match_InvalidSVEVectorList4x32Mul4:
7026 case Match_InvalidSVEVectorList4x64Mul4:
7027 case Match_InvalidSVEVectorList4x128Mul4:
7028 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7029 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7030 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7031 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7032 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7033 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7034 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7035 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7036 case Match_InvalidSVEVectorList3x0_3b:
7037 case Match_InvalidSVEVectorListStrided2x8:
7038 case Match_InvalidSVEVectorListStrided2x16:
7039 case Match_InvalidSVEVectorListStrided2x32:
7040 case Match_InvalidSVEVectorListStrided2x64:
7041 case Match_InvalidSVEVectorListStrided4x8:
7042 case Match_InvalidSVEVectorListStrided4x16:
7043 case Match_InvalidSVEVectorListStrided4x32:
7044 case Match_InvalidSVEVectorListStrided4x64:
7047 if (ErrorInfo >= Operands.
size())
7048 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7051 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7052 if (ErrorLoc == SMLoc())
7054 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7062bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7069 SMLoc Loc = DirectiveID.
getLoc();
7070 if (IDVal ==
".arch")
7071 parseDirectiveArch(Loc);
7072 else if (IDVal ==
".cpu")
7073 parseDirectiveCPU(Loc);
7074 else if (IDVal ==
".tlsdesccall")
7075 parseDirectiveTLSDescCall(Loc);
7076 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7077 parseDirectiveLtorg(Loc);
7078 else if (IDVal ==
".unreq")
7079 parseDirectiveUnreq(Loc);
7080 else if (IDVal ==
".inst")
7081 parseDirectiveInst(Loc);
7082 else if (IDVal ==
".cfi_negate_ra_state")
7083 parseDirectiveCFINegateRAState();
7084 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7085 parseDirectiveCFINegateRAStateWithPC();
7086 else if (IDVal ==
".cfi_set_ra_state")
7087 parseDirectiveCFILLVMSetRAState();
7088 else if (IDVal ==
".cfi_b_key_frame")
7089 parseDirectiveCFIBKeyFrame();
7090 else if (IDVal ==
".cfi_mte_tagged_frame")
7091 parseDirectiveCFIMTETaggedFrame();
7092 else if (IDVal ==
".arch_extension")
7093 parseDirectiveArchExtension(Loc);
7094 else if (IDVal ==
".variant_pcs")
7095 parseDirectiveVariantPCS(Loc);
7098 parseDirectiveLOH(IDVal, Loc);
7101 }
else if (IsCOFF) {
7102 if (IDVal ==
".seh_stackalloc")
7103 parseDirectiveSEHAllocStack(Loc);
7104 else if (IDVal ==
".seh_endprologue")
7105 parseDirectiveSEHPrologEnd(Loc);
7106 else if (IDVal ==
".seh_save_r19r20_x")
7107 parseDirectiveSEHSaveR19R20X(Loc);
7108 else if (IDVal ==
".seh_save_fplr")
7109 parseDirectiveSEHSaveFPLR(Loc);
7110 else if (IDVal ==
".seh_save_fplr_x")
7111 parseDirectiveSEHSaveFPLRX(Loc);
7112 else if (IDVal ==
".seh_save_reg")
7113 parseDirectiveSEHSaveReg(Loc);
7114 else if (IDVal ==
".seh_save_reg_x")
7115 parseDirectiveSEHSaveRegX(Loc);
7116 else if (IDVal ==
".seh_save_regp")
7117 parseDirectiveSEHSaveRegP(Loc);
7118 else if (IDVal ==
".seh_save_regp_x")
7119 parseDirectiveSEHSaveRegPX(Loc);
7120 else if (IDVal ==
".seh_save_lrpair")
7121 parseDirectiveSEHSaveLRPair(Loc);
7122 else if (IDVal ==
".seh_save_freg")
7123 parseDirectiveSEHSaveFReg(Loc);
7124 else if (IDVal ==
".seh_save_freg_x")
7125 parseDirectiveSEHSaveFRegX(Loc);
7126 else if (IDVal ==
".seh_save_fregp")
7127 parseDirectiveSEHSaveFRegP(Loc);
7128 else if (IDVal ==
".seh_save_fregp_x")
7129 parseDirectiveSEHSaveFRegPX(Loc);
7130 else if (IDVal ==
".seh_set_fp")
7131 parseDirectiveSEHSetFP(Loc);
7132 else if (IDVal ==
".seh_add_fp")
7133 parseDirectiveSEHAddFP(Loc);
7134 else if (IDVal ==
".seh_nop")
7135 parseDirectiveSEHNop(Loc);
7136 else if (IDVal ==
".seh_save_next")
7137 parseDirectiveSEHSaveNext(Loc);
7138 else if (IDVal ==
".seh_startepilogue")
7139 parseDirectiveSEHEpilogStart(Loc);
7140 else if (IDVal ==
".seh_endepilogue")
7141 parseDirectiveSEHEpilogEnd(Loc);
7142 else if (IDVal ==
".seh_trap_frame")
7143 parseDirectiveSEHTrapFrame(Loc);
7144 else if (IDVal ==
".seh_pushframe")
7145 parseDirectiveSEHMachineFrame(Loc);
7146 else if (IDVal ==
".seh_context")
7147 parseDirectiveSEHContext(Loc);
7148 else if (IDVal ==
".seh_ec_context")
7149 parseDirectiveSEHECContext(Loc);
7150 else if (IDVal ==
".seh_clear_unwound_to_call")
7151 parseDirectiveSEHClearUnwoundToCall(Loc);
7152 else if (IDVal ==
".seh_pac_sign_lr")
7153 parseDirectiveSEHPACSignLR(Loc);
7154 else if (IDVal ==
".seh_save_any_reg")
7155 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7156 else if (IDVal ==
".seh_save_any_reg_p")
7157 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7158 else if (IDVal ==
".seh_save_any_reg_x")
7159 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7160 else if (IDVal ==
".seh_save_any_reg_px")
7161 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7162 else if (IDVal ==
".seh_allocz")
7163 parseDirectiveSEHAllocZ(Loc);
7164 else if (IDVal ==
".seh_save_zreg")
7165 parseDirectiveSEHSaveZReg(Loc);
7166 else if (IDVal ==
".seh_save_preg")
7167 parseDirectiveSEHSavePReg(Loc);
7171 if (IDVal ==
".aeabi_subsection")
7172 parseDirectiveAeabiSubSectionHeader(Loc);
7173 else if (IDVal ==
".aeabi_attribute")
7174 parseDirectiveAeabiAArch64Attr(Loc);
7187 if (!NoCrypto && Crypto) {
7190 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7191 ArchInfo == AArch64::ARMV8_3A) {
7195 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7196 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7197 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7198 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7199 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7200 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7206 }
else if (NoCrypto) {
7209 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7210 ArchInfo == AArch64::ARMV8_3A) {
7211 RequestedExtensions.
push_back(
"nosha2");
7214 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7215 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7216 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7217 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7218 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7219 ArchInfo == AArch64::ARMV9_4A) {
7221 RequestedExtensions.
push_back(
"nosha3");
7222 RequestedExtensions.
push_back(
"nosha2");
7234bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7235 SMLoc CurLoc = getLoc();
7237 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7238 StringRef Arch, ExtensionString;
7239 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7243 return Error(CurLoc,
"unknown arch name");
7249 std::vector<StringRef> AArch64Features;
7250 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7253 MCSubtargetInfo &STI = copySTI();
7254 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7256 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7259 if (!ExtensionString.
empty())
7260 ExtensionString.
split(RequestedExtensions,
'+');
7265 for (
auto Name : RequestedExtensions) {
7269 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7276 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7284 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7285 setAvailableFeatures(Features);
7287 getTargetStreamer().emitDirectiveArch(Name);
7293bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7294 SMLoc ExtLoc = getLoc();
7296 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7301 bool EnableFeature =
true;
7302 StringRef
Name = FullName;
7303 if (
Name.starts_with_insensitive(
"no")) {
7304 EnableFeature =
false;
7313 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7315 MCSubtargetInfo &STI = copySTI();
7320 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7321 setAvailableFeatures(Features);
7323 getTargetStreamer().emitDirectiveArchExtension(FullName);
7329bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7330 SMLoc CurLoc = getLoc();
7332 StringRef CPU, ExtensionString;
7333 std::tie(CPU, ExtensionString) =
7334 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7340 if (!ExtensionString.
empty())
7341 ExtensionString.
split(RequestedExtensions,
'+');
7345 Error(CurLoc,
"unknown CPU name");
7350 MCSubtargetInfo &STI = copySTI();
7354 for (
auto Name : RequestedExtensions) {
7358 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7365 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7373 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7374 setAvailableFeatures(Features);
7380bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7382 return Error(Loc,
"expected expression following '.inst' directive");
7384 auto parseOp = [&]() ->
bool {
7386 const MCExpr *Expr =
nullptr;
7387 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7390 if (check(!
Value, L,
"expected constant expression"))
7392 getTargetStreamer().emitInst(
Value->getValue());
7396 return parseMany(parseOp);
7401bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7403 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7415 getParser().getStreamer().emitInstruction(Inst, getSTI());
7421bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7425 return TokError(
"expected an identifier or a number in directive");
7428 int64_t
Id = getTok().getIntVal();
7430 return TokError(
"invalid numeric identifier in directive");
7433 StringRef
Name = getTok().getIdentifier();
7439 return TokError(
"invalid identifier in directive");
7447 assert(NbArgs != -1 &&
"Invalid number of arguments");
7450 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7452 if (getParser().parseIdentifier(Name))
7453 return TokError(
"expected identifier in directive");
7456 if (Idx + 1 == NbArgs)
7464 getStreamer().emitLOHDirective(Kind, Args);
7470bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7473 getTargetStreamer().emitCurrentConstantPool();
7479bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7481 SMLoc SRegLoc = getLoc();
7482 RegKind RegisterKind = RegKind::Scalar;
7484 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7488 RegisterKind = RegKind::NeonVector;
7489 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7495 return Error(SRegLoc,
"vector register without type specifier expected");
7500 RegisterKind = RegKind::SVEDataVector;
7502 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7508 return Error(SRegLoc,
7509 "sve vector register without type specifier expected");
7514 RegisterKind = RegKind::SVEPredicateVector;
7515 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7521 return Error(SRegLoc,
7522 "sve predicate register without type specifier expected");
7526 return Error(SRegLoc,
"register name or alias expected");
7532 auto pair = std::make_pair(RegisterKind, RegNum);
7533 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7534 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7541bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7543 return TokError(
"unexpected input in .unreq directive.");
7544 RegisterReqs.
erase(getTok().getIdentifier().lower());
7549bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7552 getStreamer().emitCFINegateRAState();
7556bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7559 getStreamer().emitCFINegateRAStateWithPC();
7566bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7568 if (getParser().parseAbsoluteExpression(State))
7573 SMLoc ExprLoc = getLoc();
7574 if (getParser().parseExpression(Expr))
7579 getStreamer().emitCFILLVMSetRAState(
7580 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7582 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7586 "expected an integer offset or a symbol for .cfi_set_ra_state");
7593bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7596 getStreamer().emitCFIBKeyFrame();
7602bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7605 getStreamer().emitCFIMTETaggedFrame();
7611bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7613 if (getParser().parseIdentifier(Name))
7614 return TokError(
"expected symbol name");
7617 getTargetStreamer().emitDirectiveVariantPCS(
7624bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7626 if (parseImmExpr(
Size))
7628 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7634bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7635 getTargetStreamer().emitARM64WinCFIPrologEnd();
7641bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7643 if (parseImmExpr(
Offset))
7645 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7651bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7653 if (parseImmExpr(
Offset))
7655 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7661bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7663 if (parseImmExpr(
Offset))
7665 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7671bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7674 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7675 parseComma() || parseImmExpr(
Offset))
7677 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7683bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7686 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7687 parseComma() || parseImmExpr(
Offset))
7689 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7695bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7698 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7699 parseComma() || parseImmExpr(
Offset))
7701 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7707bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7710 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7711 parseComma() || parseImmExpr(
Offset))
7713 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7719bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7723 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7724 parseComma() || parseImmExpr(
Offset))
7726 if (check(((
Reg - 19) % 2 != 0), L,
7727 "expected register with even offset from x19"))
7729 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7735bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7738 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7739 parseComma() || parseImmExpr(
Offset))
7741 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7747bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7750 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7751 parseComma() || parseImmExpr(
Offset))
7753 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7759bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7762 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7763 parseComma() || parseImmExpr(
Offset))
7765 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7771bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7774 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7775 parseComma() || parseImmExpr(
Offset))
7777 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7783bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7784 getTargetStreamer().emitARM64WinCFISetFP();
7790bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7792 if (parseImmExpr(
Size))
7794 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7800bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7801 getTargetStreamer().emitARM64WinCFINop();
7807bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7808 getTargetStreamer().emitARM64WinCFISaveNext();
7814bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7815 getTargetStreamer().emitARM64WinCFIEpilogStart();
7821bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7822 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7828bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7829 getTargetStreamer().emitARM64WinCFITrapFrame();
7835bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7836 getTargetStreamer().emitARM64WinCFIMachineFrame();
7842bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7843 getTargetStreamer().emitARM64WinCFIContext();
7849bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7850 getTargetStreamer().emitARM64WinCFIECContext();
7856bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7857 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7863bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7864 getTargetStreamer().emitARM64WinCFIPACSignLR();
7873bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7878 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7879 parseComma() || parseImmExpr(
Offset))
7882 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7883 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7884 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7885 return Error(L,
"invalid save_any_reg offset");
7886 unsigned EncodedReg;
7887 if (
Reg == AArch64::FP)
7889 else if (
Reg == AArch64::LR)
7892 EncodedReg =
Reg - AArch64::X0;
7894 if (
Reg == AArch64::LR)
7895 return Error(Start,
"lr cannot be paired with another register");
7897 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7899 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7902 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7904 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7906 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7907 unsigned EncodedReg =
Reg - AArch64::D0;
7908 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7909 return Error(L,
"invalid save_any_reg offset");
7911 if (
Reg == AArch64::D31)
7912 return Error(Start,
"d31 cannot be paired with another register");
7914 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7916 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7919 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7921 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7923 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7924 unsigned EncodedReg =
Reg - AArch64::Q0;
7926 return Error(L,
"invalid save_any_reg offset");
7928 if (
Reg == AArch64::Q31)
7929 return Error(Start,
"q31 cannot be paired with another register");
7931 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7933 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7936 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7938 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7941 return Error(Start,
"save_any_reg register must be x, q or d register");
7948bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7950 if (parseImmExpr(
Offset))
7952 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7958bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
7963 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7966 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
7967 "expected register in range z8 to z23"))
7969 if (parseComma() || parseImmExpr(
Offset))
7971 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
7977bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
7982 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7985 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
7986 "expected register in range p4 to p15"))
7988 if (parseComma() || parseImmExpr(
Offset))
7990 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
7994bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8000 MCAsmParser &Parser = getParser();
8003 StringRef SubsectionName;
8014 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8015 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8020 if (SubsectionExists) {
8021 getTargetStreamer().emitAttributesSubsection(
8024 SubsectionExists->IsOptional),
8026 SubsectionExists->ParameterType));
8032 "Could not switch to subsection '" + SubsectionName +
8033 "' using subsection name, subsection has not been defined");
8056 if (SubsectionExists) {
8057 if (IsOptional != SubsectionExists->IsOptional) {
8059 "optionality mismatch! subsection '" + SubsectionName +
8060 "' already exists with optionality defined as '" +
8062 SubsectionExists->IsOptional) +
8070 "optionality parameter not found, expected required|optional");
8077 "aeabi_feature_and_bits must be marked as optional");
8084 "aeabi_pauthabi must be marked as required");
8104 if (SubsectionExists) {
8105 if (
Type != SubsectionExists->ParameterType) {
8107 "type mismatch! subsection '" + SubsectionName +
8108 "' already exists with type defined as '" +
8110 SubsectionExists->ParameterType) +
8118 "type parameter not found, expected uleb128|ntbs");
8126 SubsectionName +
" must be marked as ULEB128");
8135 "attributes subsection header directive");
8139 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8144bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8148 MCAsmParser &Parser = getParser();
8150 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8151 getTargetStreamer().getActiveAttributesSubsection();
8152 if (
nullptr == ActiveSubsection) {
8154 "no active subsection, build attribute can not be added");
8157 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8158 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8166 ActiveSubsectionName)
8169 StringRef TagStr =
"";
8172 Tag = getTok().getIntVal();
8175 switch (ActiveSubsectionID) {
8180 "' \nExcept for public subsections, "
8181 "tags have to be an unsigned int.");
8188 TagStr +
"' for subsection '" +
8189 ActiveSubsectionName +
"'");
8197 TagStr +
"' for subsection '" +
8198 ActiveSubsectionName +
"'");
8216 unsigned ValueInt = unsigned(-1);
8217 std::string ValueStr =
"";
8222 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8225 ValueInt = getTok().getIntVal();
8230 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8238 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8249 if (0 != ValueInt && 1 != ValueInt) {
8251 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8252 "' options are 0|1");
8261 "unexpected token for AArch64 build attributes tag and value "
8262 "attribute directive");
8266 if (
unsigned(-1) != ValueInt) {
8267 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8269 if (
"" != ValueStr) {
8270 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8276bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8277 SMLoc Loc = getLoc();
8279 return TokError(
"expected '%' relocation specifier");
8280 StringRef
Identifier = getParser().getTok().getIdentifier();
8283 return TokError(
"invalid relocation specifier");
8289 const MCExpr *SubExpr;
8290 if (getParser().parseParenExpression(SubExpr,
E))
8297bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8300 return parseExprWithSpecifier(Res, EndLoc);
8302 if (getParser().parseExpression(Res))
8304 MCAsmParser &Parser = getParser();
8308 return Error(getLoc(),
"expected relocation specifier");
8311 SMLoc Loc = getLoc();
8313 if (Identifier ==
"auth")
8314 return parseAuthExpr(Res, EndLoc);
8318 if (Identifier ==
"got")
8322 return Error(Loc,
"invalid relocation specifier");
8327 return Error(Loc,
"@ specifier only allowed after a symbol");
8330 std::optional<MCBinaryExpr::Opcode> Opcode;
8338 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8349bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8350 MCAsmParser &Parser = getParser();
8352 AsmToken Tok = Parser.
getTok();
8359 return TokError(
"expected key name");
8364 return TokError(
"invalid key '" + KeyStr +
"'");
8371 return TokError(
"expected integer discriminator");
8375 return TokError(
"integer discriminator " + Twine(Discriminator) +
8376 " out of range [0, 0xFFFF]");
8379 bool UseAddressDiversity =
false;
8384 return TokError(
"expected 'addr'");
8385 UseAddressDiversity =
true;
8394 UseAddressDiversity, Ctx, Res->
getLoc());
8398bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8407 ELFSpec = AE->getSpecifier();
8408 Expr = AE->getSubExpr();
8448#define GET_REGISTER_MATCHER
8449#define GET_SUBTARGET_FEATURE_NAME
8450#define GET_MATCHER_IMPLEMENTATION
8451#define GET_MNEMONIC_SPELL_CHECKER
8452#include "AArch64GenAsmMatcher.inc"
8458 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8460 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8462 return Match_InvalidOperand;
8465 return Match_InvalidOperand;
8466 if (CE->getValue() == ExpectedVal)
8467 return Match_Success;
8468 return Match_InvalidOperand;
8473 return Match_InvalidOperand;
8479 if (
Op.isTokenEqual(
"za"))
8480 return Match_Success;
8481 return Match_InvalidOperand;
8487#define MATCH_HASH(N) \
8488 case MCK__HASH_##N: \
8489 return MatchesOpImmediate(N);
8515#define MATCH_HASH_MINUS(N) \
8516 case MCK__HASH__MINUS_##N: \
8517 return MatchesOpImmediate(-N);
8521#undef MATCH_HASH_MINUS
8525ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8530 return Error(S,
"expected register");
8532 MCRegister FirstReg;
8533 ParseStatus Res = tryParseScalarRegister(FirstReg);
8535 return Error(S,
"expected first even register of a consecutive same-size "
8536 "even/odd register pair");
8538 const MCRegisterClass &WRegClass =
8539 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8540 const MCRegisterClass &XRegClass =
8541 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8543 bool isXReg = XRegClass.
contains(FirstReg),
8544 isWReg = WRegClass.
contains(FirstReg);
8545 if (!isXReg && !isWReg)
8546 return Error(S,
"expected first even register of a consecutive same-size "
8547 "even/odd register pair");
8549 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8552 if (FirstEncoding & 0x1)
8553 return Error(S,
"expected first even register of a consecutive same-size "
8554 "even/odd register pair");
8557 return Error(getLoc(),
"expected comma");
8562 MCRegister SecondReg;
8563 Res = tryParseScalarRegister(SecondReg);
8565 return Error(
E,
"expected second odd register of a consecutive same-size "
8566 "even/odd register pair");
8569 (isXReg && !XRegClass.
contains(SecondReg)) ||
8570 (isWReg && !WRegClass.
contains(SecondReg)))
8571 return Error(
E,
"expected second odd register of a consecutive same-size "
8572 "even/odd register pair");
8577 FirstReg, AArch64::sube64,
8578 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8581 FirstReg, AArch64::sube32,
8582 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8585 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8591template <
bool ParseShiftExtend,
bool ParseSuffix>
8592ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8593 const SMLoc S = getLoc();
8599 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8604 if (ParseSuffix &&
Kind.empty())
8611 unsigned ElementWidth = KindRes->second;
8615 Operands.
push_back(AArch64Operand::CreateVectorReg(
8616 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8618 ParseStatus Res = tryParseVectorIndex(Operands);
8629 Res = tryParseOptionalShiftExtend(ExtOpnd);
8633 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8634 Operands.
push_back(AArch64Operand::CreateVectorReg(
8635 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8636 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8637 Ext->hasShiftExtendAmount()));
8642ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8643 MCAsmParser &Parser = getParser();
8645 SMLoc
SS = getLoc();
8646 const AsmToken &TokE = getTok();
8657 const MCExpr *ImmVal;
8664 return TokError(
"invalid operand for instruction");
8669 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8674 Pattern = Pat->Encoding;
8675 assert(Pattern >= 0 && Pattern < 32);
8686AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8688 SMLoc
SS = getLoc();
8689 const AsmToken &TokE = getTok();
8691 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8697 Pattern = Pat->Encoding;
8698 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8707ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8708 SMLoc
SS = getLoc();
8711 if (!tryParseScalarRegister(XReg).isSuccess())
8717 XReg, AArch64::x8sub_0,
8718 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8721 "expected an even-numbered x-register in the range [x0,x22]");
8724 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8728ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8738 if (getParser().parseExpression(ImmF))
8748 SMLoc
E = getTok().getLoc();
8750 if (getParser().parseExpression(ImmL))
8757 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8762ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8772 if (getParser().parseExpression(Ex))
8782 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8789 Operands.
push_back(AArch64Operand::CreateImm(
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
APInt bitcastToAPInt() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void UnLex(AsmToken const &Token)
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
const MCRegisterDesc & get(MCRegister Reg) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
LLVM_ABI std::string lower() const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI SubsectionType getTypeID(StringRef Type)
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
LLVM_ABI StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
LLVM_ABI StringRef getSubsectionTypeUnknownError()
LLVM_ABI SubsectionOptional getOptionalID(StringRef Optional)
LLVM_ABI StringRef getSubsectionOptionalUnknownError()
LLVM_ABI FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
LLVM_ABI VendorID getVendorID(StringRef const Vendor)
LLVM_ABI PauthABITags getPauthABITagsID(StringRef PauthABITag)
LLVM_ABI StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
uint32_t parseGenericRegister(StringRef Name)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool isSVEAddSubImm(int64_t Imm)
Returns true if Imm is valid for ADD/SUB.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static bool isSVECpyImm(int64_t Imm)
Returns true if Imm is valid for CPY/DUP.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static int MCLOHNameToId(StringRef Name)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
StringTable::Offset ArchFeature
AArch64::ExtensionBitset DefaultExts
Compile-time data representation of enum entries.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
bool haveFeatures(FeatureBitset ActiveFeatures) const