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 parseDirectiveCFIBKeyFrame();
205 bool parseDirectiveCFIMTETaggedFrame();
207 bool parseDirectiveVariantPCS(SMLoc L);
209 bool parseDirectiveSEHAllocStack(SMLoc L);
210 bool parseDirectiveSEHPrologEnd(SMLoc L);
211 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
212 bool parseDirectiveSEHSaveFPLR(SMLoc L);
213 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
214 bool parseDirectiveSEHSaveReg(SMLoc L);
215 bool parseDirectiveSEHSaveRegX(SMLoc L);
216 bool parseDirectiveSEHSaveRegP(SMLoc L);
217 bool parseDirectiveSEHSaveRegPX(SMLoc L);
218 bool parseDirectiveSEHSaveLRPair(SMLoc L);
219 bool parseDirectiveSEHSaveFReg(SMLoc L);
220 bool parseDirectiveSEHSaveFRegX(SMLoc L);
221 bool parseDirectiveSEHSaveFRegP(SMLoc L);
222 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
223 bool parseDirectiveSEHSetFP(SMLoc L);
224 bool parseDirectiveSEHAddFP(SMLoc L);
225 bool parseDirectiveSEHNop(SMLoc L);
226 bool parseDirectiveSEHSaveNext(SMLoc L);
227 bool parseDirectiveSEHEpilogStart(SMLoc L);
228 bool parseDirectiveSEHEpilogEnd(SMLoc L);
229 bool parseDirectiveSEHTrapFrame(SMLoc L);
230 bool parseDirectiveSEHMachineFrame(SMLoc L);
231 bool parseDirectiveSEHContext(SMLoc L);
232 bool parseDirectiveSEHECContext(SMLoc L);
233 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
234 bool parseDirectiveSEHPACSignLR(SMLoc L);
235 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
236 bool parseDirectiveSEHAllocZ(SMLoc L);
237 bool parseDirectiveSEHSaveZReg(SMLoc L);
238 bool parseDirectiveSEHSavePReg(SMLoc L);
239 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
240 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
242 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
243 SmallVectorImpl<SMLoc> &Loc);
244 unsigned getNumRegsForRegKind(RegKind K);
245 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
248 bool MatchingInlineAsm)
override;
252#define GET_ASSEMBLER_HEADER
253#include "AArch64GenAsmMatcher.inc"
267 template <
bool IsSVEPrefetch = false>
273 template <
bool AddFPZeroAsLiteral>
281 template <
bool ParseShiftExtend,
282 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
285 template <
bool ParseShiftExtend,
bool ParseSuffix>
287 template <RegKind RK>
290 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
291 template <RegKind VectorKind>
293 bool ExpectMatch =
false);
302 enum AArch64MatchResultTy {
303 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
304#define GET_OPERAND_DIAGNOSTIC_TYPES
305#include "AArch64GenAsmMatcher.inc"
308 bool IsWindowsArm64EC;
310 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
311 const MCInstrInfo &MII)
312 : MCTargetAsmParser(STI, MII) {
316 MCStreamer &S = getParser().getStreamer();
318 new AArch64TargetStreamer(S);
330 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
333 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
334 const MCParsedAsmOperand &Op2)
const override;
335 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
337 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
338 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
339 SMLoc &EndLoc)
override;
340 bool ParseDirective(AsmToken DirectiveID)
override;
341 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
342 unsigned Kind)
override;
374 SMLoc StartLoc, EndLoc;
383 struct ShiftExtendOp {
386 bool HasExplicitAmount;
396 RegConstraintEqualityTy EqualityTy;
412 ShiftExtendOp ShiftExtend;
417 unsigned ElementWidth;
421 struct MatrixTileListOp {
422 unsigned RegMask = 0;
425 struct VectorListOp {
429 unsigned NumElements;
430 unsigned ElementWidth;
431 RegKind RegisterKind;
434 struct VectorIndexOp {
442 struct ShiftedImmOp {
444 unsigned ShiftAmount;
473 uint32_t PStateField;
486 struct TIndexHintOp {
495 unsigned PStateField;
501 struct MatrixRegOp MatrixReg;
502 struct MatrixTileListOp MatrixTileList;
503 struct VectorListOp VectorList;
504 struct VectorIndexOp VectorIndex;
506 struct ShiftedImmOp ShiftedImm;
507 struct ImmRangeOp ImmRange;
509 struct FPImmOp FPImm;
511 struct SysRegOp SysReg;
512 struct SysCRImmOp SysCRImm;
514 struct TIndexHintOp TIndexHint;
515 struct ShiftExtendOp ShiftExtend;
524 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
526 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
528 StartLoc =
o.StartLoc;
538 ShiftedImm =
o.ShiftedImm;
541 ImmRange =
o.ImmRange;
555 case k_MatrixRegister:
556 MatrixReg =
o.MatrixReg;
558 case k_MatrixTileList:
559 MatrixTileList =
o.MatrixTileList;
562 VectorList =
o.VectorList;
565 VectorIndex =
o.VectorIndex;
571 SysCRImm =
o.SysCRImm;
577 TIndexHint =
o.TIndexHint;
580 ShiftExtend =
o.ShiftExtend;
589 SMLoc getStartLoc()
const override {
return StartLoc; }
591 SMLoc getEndLoc()
const override {
return EndLoc; }
594 assert(Kind == k_Token &&
"Invalid access!");
595 return StringRef(Tok.Data, Tok.Length);
598 bool isTokenSuffix()
const {
599 assert(Kind == k_Token &&
"Invalid access!");
603 const MCExpr *
getImm()
const {
604 assert(Kind == k_Immediate &&
"Invalid access!");
608 const MCExpr *getShiftedImmVal()
const {
609 assert(Kind == k_ShiftedImm &&
"Invalid access!");
610 return ShiftedImm.Val;
613 unsigned getShiftedImmShift()
const {
614 assert(Kind == k_ShiftedImm &&
"Invalid access!");
615 return ShiftedImm.ShiftAmount;
618 unsigned getFirstImmVal()
const {
619 assert(Kind == k_ImmRange &&
"Invalid access!");
620 return ImmRange.First;
623 unsigned getLastImmVal()
const {
624 assert(Kind == k_ImmRange &&
"Invalid access!");
625 return ImmRange.Last;
629 assert(Kind == k_CondCode &&
"Invalid access!");
634 assert (Kind == k_FPImm &&
"Invalid access!");
635 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
638 bool getFPImmIsExact()
const {
639 assert (Kind == k_FPImm &&
"Invalid access!");
640 return FPImm.IsExact;
643 unsigned getBarrier()
const {
644 assert(Kind == k_Barrier &&
"Invalid access!");
648 StringRef getBarrierName()
const {
649 assert(Kind == k_Barrier &&
"Invalid access!");
653 bool getBarriernXSModifier()
const {
654 assert(Kind == k_Barrier &&
"Invalid access!");
658 MCRegister
getReg()
const override {
659 assert(Kind == k_Register &&
"Invalid access!");
663 MCRegister getMatrixReg()
const {
664 assert(Kind == k_MatrixRegister &&
"Invalid access!");
665 return MatrixReg.Reg;
668 unsigned getMatrixElementWidth()
const {
669 assert(Kind == k_MatrixRegister &&
"Invalid access!");
670 return MatrixReg.ElementWidth;
673 MatrixKind getMatrixKind()
const {
674 assert(Kind == k_MatrixRegister &&
"Invalid access!");
675 return MatrixReg.Kind;
678 unsigned getMatrixTileListRegMask()
const {
679 assert(isMatrixTileList() &&
"Invalid access!");
680 return MatrixTileList.RegMask;
683 RegConstraintEqualityTy getRegEqualityTy()
const {
684 assert(Kind == k_Register &&
"Invalid access!");
685 return Reg.EqualityTy;
688 MCRegister getVectorListStart()
const {
689 assert(Kind == k_VectorList &&
"Invalid access!");
690 return VectorList.Reg;
693 unsigned getVectorListCount()
const {
694 assert(Kind == k_VectorList &&
"Invalid access!");
695 return VectorList.Count;
698 unsigned getVectorListStride()
const {
699 assert(Kind == k_VectorList &&
"Invalid access!");
700 return VectorList.Stride;
703 int getVectorIndex()
const {
704 assert(Kind == k_VectorIndex &&
"Invalid access!");
705 return VectorIndex.Val;
708 StringRef getSysReg()
const {
709 assert(Kind == k_SysReg &&
"Invalid access!");
710 return StringRef(SysReg.Data, SysReg.Length);
713 unsigned getSysCR()
const {
714 assert(Kind == k_SysCR &&
"Invalid access!");
718 unsigned getPrefetch()
const {
719 assert(Kind == k_Prefetch &&
"Invalid access!");
723 unsigned getTIndexHint()
const {
724 assert(Kind == k_TIndexHint &&
"Invalid access!");
725 return TIndexHint.Val;
728 StringRef getTIndexHintName()
const {
729 assert(Kind == k_TIndexHint &&
"Invalid access!");
730 return StringRef(TIndexHint.Data, TIndexHint.Length);
733 StringRef getSVCR()
const {
734 assert(Kind == k_SVCR &&
"Invalid access!");
735 return StringRef(SVCR.Data, SVCR.Length);
738 StringRef getPrefetchName()
const {
739 assert(Kind == k_Prefetch &&
"Invalid access!");
744 if (Kind == k_ShiftExtend)
745 return ShiftExtend.Type;
746 if (Kind == k_Register)
747 return Reg.ShiftExtend.Type;
751 unsigned getShiftExtendAmount()
const {
752 if (Kind == k_ShiftExtend)
753 return ShiftExtend.Amount;
754 if (Kind == k_Register)
755 return Reg.ShiftExtend.Amount;
759 bool hasShiftExtendAmount()
const {
760 if (Kind == k_ShiftExtend)
761 return ShiftExtend.HasExplicitAmount;
762 if (Kind == k_Register)
763 return Reg.ShiftExtend.HasExplicitAmount;
767 bool isImm()
const override {
return Kind == k_Immediate; }
768 bool isMem()
const override {
return false; }
770 bool isUImm6()
const {
777 return (Val >= 0 && Val < 64);
780 template <
int W
idth>
bool isSImm()
const {
781 return bool(isSImmScaled<Width, 1>());
784 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
785 return isImmScaled<Bits, Scale>(
true);
788 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
789 DiagnosticPredicate isUImmScaled()
const {
790 if (IsRange && isImmRange() &&
791 (getLastImmVal() != getFirstImmVal() +
Offset))
794 return isImmScaled<Bits, Scale, IsRange>(
false);
797 template <
int Bits,
int Scale,
bool IsRange = false>
798 DiagnosticPredicate isImmScaled(
bool Signed)
const {
799 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
800 (isImmRange() && !IsRange))
805 Val = getFirstImmVal();
813 int64_t MinVal, MaxVal;
815 int64_t Shift =
Bits - 1;
816 MinVal = (int64_t(1) << Shift) * -Scale;
817 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
820 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
823 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
829 DiagnosticPredicate isSVEPattern()
const {
836 if (Val >= 0 && Val < 32)
841 DiagnosticPredicate isSVEVecLenSpecifier()
const {
848 if (Val >= 0 && Val <= 1)
853 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
857 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
886 template <
int Scale>
bool isUImm12Offset()
const {
892 return isSymbolicUImm12Offset(
getImm());
895 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
898 template <
int N,
int M>
899 bool isImmInRange()
const {
906 return (Val >=
N && Val <= M);
909 bool isHinteUImm16()
const {
916 return Val >= 0 && Val <= 65535 &&
917 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
922 template <
typename T>
923 bool isLogicalImm()
const {
932 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
940 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
942 bool isImmRange()
const {
return Kind == k_ImmRange; }
947 template <
unsigned W
idth>
948 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
949 if (isShiftedImm() && Width == getShiftedImmShift())
951 return std::make_pair(
CE->getValue(), Width);
955 int64_t Val =
CE->getValue();
956 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
957 return std::make_pair(Val >> Width, Width);
959 return std::make_pair(Val, 0u);
965 bool isAddSubImm()
const {
966 if (!isShiftedImm() && !isImm())
972 if (isShiftedImm()) {
973 unsigned Shift = ShiftedImm.ShiftAmount;
974 Expr = ShiftedImm.Val;
975 if (Shift != 0 && Shift != 12)
984 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1000 if (
auto ShiftedVal = getShiftedVal<12>())
1001 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1008 bool isAddSubImmNeg()
const {
1009 if (!isShiftedImm() && !isImm())
1013 if (
auto ShiftedVal = getShiftedVal<12>())
1014 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1024 template <
typename T>
1025 DiagnosticPredicate isSVECpyImm()
const {
1029 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1030 std::is_same<int8_t, T>::value;
1031 if (
auto ShiftedImm = getShiftedVal<8>())
1032 if (!(IsByte && ShiftedImm->second) &&
1034 << ShiftedImm->second))
1043 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1047 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1048 std::is_same<int8_t, T>::value;
1049 if (
auto ShiftedImm = getShiftedVal<8>())
1050 if (!(IsByte && ShiftedImm->second) &&
1052 << ShiftedImm->second))
1058 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1059 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1064 bool isCondCode()
const {
return Kind == k_CondCode; }
1066 bool isSIMDImmType10()
const {
1076 bool isBranchTarget()
const {
1085 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1086 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1096 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1106 bool isMovWSymbolG3()
const {
1110 bool isMovWSymbolG2()
const {
1117 bool isMovWSymbolG1()
const {
1125 bool isMovWSymbolG0()
const {
1133 template<
int RegW
idth,
int Shift>
1134 bool isMOVZMovAlias()
const {
1135 if (!isImm())
return false;
1139 uint64_t
Value =
CE->getValue();
1148 template<
int RegW
idth,
int Shift>
1149 bool isMOVNMovAlias()
const {
1150 if (!isImm())
return false;
1153 if (!CE)
return false;
1154 uint64_t
Value =
CE->getValue();
1159 bool isFPImm()
const {
1160 return Kind == k_FPImm &&
1164 bool isBarrier()
const {
1165 return Kind == k_Barrier && !getBarriernXSModifier();
1167 bool isBarriernXS()
const {
1168 return Kind == k_Barrier && getBarriernXSModifier();
1170 bool isSysReg()
const {
return Kind == k_SysReg; }
1172 bool isMRSSystemRegister()
const {
1173 if (!isSysReg())
return false;
1175 return SysReg.MRSReg != -1U;
1178 bool isMSRSystemRegister()
const {
1179 if (!isSysReg())
return false;
1180 return SysReg.MSRReg != -1U;
1183 bool isSystemPStateFieldWithImm0_1()
const {
1184 if (!isSysReg())
return false;
1185 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1188 bool isSystemPStateFieldWithImm0_15()
const {
1191 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1194 bool isSVCR()
const {
1197 return SVCR.PStateField != -1U;
1200 bool isReg()
const override {
1201 return Kind == k_Register;
1204 bool isVectorList()
const {
return Kind == k_VectorList; }
1206 bool isScalarReg()
const {
1207 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1210 bool isNeonVectorReg()
const {
1211 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1214 bool isNeonVectorRegLo()
const {
1215 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1216 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1217 .contains(
Reg.Reg) ||
1218 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1219 .contains(
Reg.Reg));
1222 bool isNeonVectorReg0to7()
const {
1223 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1224 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1225 .contains(
Reg.Reg));
1228 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1229 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1231 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1234 case AArch64::PPRRegClassID:
1235 case AArch64::PPR_3bRegClassID:
1236 case AArch64::PPR_p8to15RegClassID:
1237 case AArch64::PNRRegClassID:
1238 case AArch64::PNR_p8to15RegClassID:
1239 case AArch64::PPRorPNRRegClassID:
1240 RK = RegKind::SVEPredicateAsCounter;
1246 return (Kind == k_Register &&
Reg.Kind == RK) &&
1247 getAArch64MCRegisterClass(Class).contains(
getReg());
1250 template <
unsigned Class>
bool isSVEVectorReg()
const {
1253 case AArch64::ZPRRegClassID:
1254 case AArch64::ZPR_3bRegClassID:
1255 case AArch64::ZPR_4bRegClassID:
1256 case AArch64::ZPRMul2_LoRegClassID:
1257 case AArch64::ZPRMul2_HiRegClassID:
1258 case AArch64::ZPR_KRegClassID:
1259 RK = RegKind::SVEDataVector;
1261 case AArch64::PPRRegClassID:
1262 case AArch64::PPR_3bRegClassID:
1263 case AArch64::PPR_p8to15RegClassID:
1264 case AArch64::PNRRegClassID:
1265 case AArch64::PNR_p8to15RegClassID:
1266 case AArch64::PPRorPNRRegClassID:
1267 RK = RegKind::SVEPredicateVector;
1273 return (Kind == k_Register &&
Reg.Kind == RK) &&
1274 getAArch64MCRegisterClass(Class).contains(
getReg());
1277 template <
unsigned Class>
bool isFPRasZPR()
const {
1278 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1279 getAArch64MCRegisterClass(Class).contains(
getReg());
1282 template <
int ElementW
idth,
unsigned Class>
1283 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1284 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1287 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1293 template <
int ElementW
idth,
unsigned Class>
1294 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1295 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1296 Reg.Kind != RegKind::SVEPredicateVector))
1299 if ((isSVEPredicateAsCounterReg<Class>() ||
1300 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1301 Reg.ElementWidth == ElementWidth)
1307 template <
int ElementW
idth,
unsigned Class>
1308 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1309 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1312 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1318 template <
int ElementW
idth,
unsigned Class>
1319 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1320 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1323 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1329 template <
int ElementWidth,
unsigned Class,
1331 bool ShiftWidthAlwaysSame>
1332 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1333 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1334 if (!VectorMatch.isMatch())
1340 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1343 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1346 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1352 bool isGPR32as64()
const {
1353 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1354 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1358 bool isGPR64as32()
const {
1359 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1360 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1364 bool isGPR64x8()
const {
1365 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1366 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1370 bool isWSeqPair()
const {
1371 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1372 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1376 bool isXSeqPair()
const {
1377 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1378 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1382 bool isSyspXzrPair()
const {
1386 template<
int64_t Angle,
int64_t Remainder>
1387 DiagnosticPredicate isComplexRotation()
const {
1394 uint64_t
Value =
CE->getValue();
1396 if (
Value % Angle == Remainder &&
Value <= 270)
1401 template <
unsigned RegClassID>
bool isGPR64()
const {
1402 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1403 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1406 template <
unsigned RegClassID,
int ExtW
idth>
1407 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1408 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1412 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1419 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1420 bool isImplicitlyTypedVectorList()
const {
1421 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1422 VectorList.NumElements == 0 &&
1423 VectorList.RegisterKind == VectorKind &&
1424 (!IsConsecutive || (VectorList.Stride == 1));
1427 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1428 unsigned ElementWidth,
unsigned Stride = 1>
1429 bool isTypedVectorList()
const {
1430 if (Kind != k_VectorList)
1432 if (VectorList.Count != NumRegs)
1434 if (VectorList.RegisterKind != VectorKind)
1436 if (VectorList.ElementWidth != ElementWidth)
1438 if (VectorList.Stride != Stride)
1440 return VectorList.NumElements == NumElements;
1443 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1444 unsigned ElementWidth,
unsigned RegClass>
1445 DiagnosticPredicate isTypedVectorListMultiple()
const {
1447 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1450 if (!getAArch64MCRegisterClass(RegClass).
contains(VectorList.Reg))
1455 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1456 unsigned ElementWidth>
1457 DiagnosticPredicate isTypedVectorListStrided()
const {
1458 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1459 ElementWidth, Stride>();
1462 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1463 ((VectorList.Reg >= AArch64::Z16) &&
1464 (VectorList.Reg < (AArch64::Z16 + Stride))))
1469 template <
int Min,
int Max>
1470 DiagnosticPredicate isVectorIndex()
const {
1471 if (Kind != k_VectorIndex)
1473 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1478 bool isToken()
const override {
return Kind == k_Token; }
1480 bool isTokenEqual(StringRef Str)
const {
1481 return Kind == k_Token &&
getToken() == Str;
1483 bool isSysCR()
const {
return Kind == k_SysCR; }
1484 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1485 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1486 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1487 bool isShifter()
const {
1488 if (!isShiftExtend())
1497 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1498 if (Kind != k_FPImm)
1501 if (getFPImmIsExact()) {
1503 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1505 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1508 APFloat RealVal(APFloat::IEEEdouble());
1510 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1511 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1514 if (
getFPImm().bitwiseIsEqual(RealVal))
1521 template <
unsigned ImmA,
unsigned ImmB>
1522 DiagnosticPredicate isExactFPImm()
const {
1524 if ((Res = isExactFPImm<ImmA>()))
1526 if ((Res = isExactFPImm<ImmB>()))
1531 bool isExtend()
const {
1532 if (!isShiftExtend())
1541 getShiftExtendAmount() <= 4;
1544 bool isExtend64()
const {
1554 bool isExtendLSL64()
const {
1560 getShiftExtendAmount() <= 4;
1563 bool isLSLImm3Shift()
const {
1564 if (!isShiftExtend())
1570 template<
int W
idth>
bool isMemXExtend()
const {
1575 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1576 getShiftExtendAmount() == 0);
1579 template<
int W
idth>
bool isMemWExtend()
const {
1584 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1585 getShiftExtendAmount() == 0);
1588 template <
unsigned w
idth>
1589 bool isArithmeticShifter()
const {
1599 template <
unsigned w
idth>
1600 bool isLogicalShifter()
const {
1608 getShiftExtendAmount() < width;
1611 bool isMovImm32Shifter()
const {
1619 uint64_t Val = getShiftExtendAmount();
1620 return (Val == 0 || Val == 16);
1623 bool isMovImm64Shifter()
const {
1631 uint64_t Val = getShiftExtendAmount();
1632 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1635 bool isLogicalVecShifter()
const {
1640 unsigned Shift = getShiftExtendAmount();
1642 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1645 bool isLogicalVecHalfWordShifter()
const {
1646 if (!isLogicalVecShifter())
1650 unsigned Shift = getShiftExtendAmount();
1652 (Shift == 0 || Shift == 8);
1655 bool isMoveVecShifter()
const {
1656 if (!isShiftExtend())
1660 unsigned Shift = getShiftExtendAmount();
1662 (Shift == 8 || Shift == 16);
1671 bool isSImm9OffsetFB()
const {
1672 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1675 bool isAdrpLabel()
const {
1682 int64_t Val =
CE->getValue();
1683 int64_t Min = - (4096 * (1LL << (21 - 1)));
1684 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1685 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1691 bool isAdrLabel()
const {
1698 int64_t Val =
CE->getValue();
1699 int64_t Min = - (1LL << (21 - 1));
1700 int64_t
Max = ((1LL << (21 - 1)) - 1);
1701 return Val >= Min && Val <=
Max;
1707 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1708 DiagnosticPredicate isMatrixRegOperand()
const {
1711 if (getMatrixKind() != Kind ||
1712 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1713 EltSize != getMatrixElementWidth())
1718 bool isPAuthPCRelLabel16Operand()
const {
1730 return (Val <= 0) && (Val > -(1 << 18));
1733 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1743 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1744 assert(
N == 1 &&
"Invalid number of operands!");
1748 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1749 assert(
N == 1 &&
"Invalid number of operands!");
1753 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1754 assert(
N == 1 &&
"Invalid number of operands!");
1756 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1758 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1765 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1766 assert(
N == 1 &&
"Invalid number of operands!");
1768 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1770 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1777 template <
int W
idth>
1778 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1781 case 8:
Base = AArch64::B0;
break;
1782 case 16:
Base = AArch64::H0;
break;
1783 case 32:
Base = AArch64::S0;
break;
1784 case 64:
Base = AArch64::D0;
break;
1785 case 128:
Base = AArch64::Q0;
break;
1792 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1793 assert(
N == 1 &&
"Invalid number of operands!");
1796 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1797 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1801 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1802 assert(
N == 1 &&
"Invalid number of operands!");
1807 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1808 assert(
N == 1 &&
"Invalid number of operands!");
1809 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1814 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1815 assert(
N == 1 &&
"Invalid number of operands!");
1816 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1821 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1822 assert(
N == 1 &&
"Invalid number of operands!");
1826 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1827 assert(
N == 1 &&
"Invalid number of operands!");
1831 enum VecListIndexType {
1832 VecListIdx_DReg = 0,
1833 VecListIdx_QReg = 1,
1834 VecListIdx_ZReg = 2,
1835 VecListIdx_PReg = 3,
1838 template <VecListIndexType RegTy,
unsigned NumRegs,
1839 bool IsConsecutive =
false>
1840 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1841 assert(
N == 1 &&
"Invalid number of operands!");
1842 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1843 "Expected consecutive registers");
1844 static const unsigned FirstRegs[][5] = {
1846 AArch64::D0, AArch64::D0_D1,
1847 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1849 AArch64::Q0, AArch64::Q0_Q1,
1850 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1852 AArch64::Z0, AArch64::Z0_Z1,
1853 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1855 AArch64::P0, AArch64::P0_P1 }
1858 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1859 " NumRegs must be <= 4 for ZRegs");
1861 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1862 " NumRegs must be <= 2 for PRegs");
1864 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1866 FirstRegs[(
unsigned)RegTy][0]));
1869 template <
unsigned NumRegs>
1870 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1871 assert(
N == 1 &&
"Invalid number of operands!");
1872 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1876 if (getVectorListStart() < AArch64::Z16) {
1877 assert((getVectorListStart() < AArch64::Z8) &&
1878 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1880 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1882 assert((getVectorListStart() < AArch64::Z24) &&
1883 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1885 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1889 if (getVectorListStart() < AArch64::Z16) {
1890 assert((getVectorListStart() < AArch64::Z4) &&
1891 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1893 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1895 assert((getVectorListStart() < AArch64::Z20) &&
1896 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1898 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1906 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1907 assert(
N == 1 &&
"Invalid number of operands!");
1908 unsigned RegMask = getMatrixTileListRegMask();
1909 assert(RegMask <= 0xFF &&
"Invalid mask!");
1913 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1914 assert(
N == 1 &&
"Invalid number of operands!");
1918 template <
unsigned ImmIs0,
unsigned ImmIs1>
1919 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1920 assert(
N == 1 &&
"Invalid number of operands!");
1921 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1925 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1926 assert(
N == 1 &&
"Invalid number of operands!");
1933 template <
int Shift>
1934 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1935 assert(
N == 2 &&
"Invalid number of operands!");
1936 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1939 }
else if (isShiftedImm()) {
1940 addExpr(Inst, getShiftedImmVal());
1948 template <
int Shift>
1949 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1950 assert(
N == 2 &&
"Invalid number of operands!");
1951 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1958 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1959 assert(
N == 1 &&
"Invalid number of operands!");
1963 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1964 assert(
N == 1 &&
"Invalid number of operands!");
1972 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1973 addImmOperands(Inst,
N);
1977 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1978 assert(
N == 1 &&
"Invalid number of operands!");
1988 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1989 assert(
N == 1 &&
"Invalid number of operands!");
1994 template <
int Scale>
1995 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
1996 assert(
N == 1 &&
"Invalid number of operands!");
2001 template <
int Scale>
2002 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2003 assert(
N == 1 &&
"Invalid number of operands!");
2007 template <
typename T>
2008 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2009 assert(
N == 1 &&
"Invalid number of operands!");
2011 std::make_unsigned_t<T> Val = MCE->
getValue();
2016 template <
typename T>
2017 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2018 assert(
N == 1 &&
"Invalid number of operands!");
2020 std::make_unsigned_t<T> Val = ~MCE->getValue();
2025 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2026 assert(
N == 1 &&
"Invalid number of operands!");
2032 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2036 assert(
N == 1 &&
"Invalid number of operands!");
2042 assert(MCE &&
"Invalid constant immediate operand!");
2046 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2050 assert(
N == 1 &&
"Invalid number of operands!");
2059 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2063 assert(
N == 1 &&
"Invalid number of operands!");
2069 assert(MCE &&
"Invalid constant immediate operand!");
2073 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2077 assert(
N == 1 &&
"Invalid number of operands!");
2083 assert(MCE &&
"Invalid constant immediate operand!");
2087 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2091 assert(
N == 1 &&
"Invalid number of operands!");
2097 assert(MCE &&
"Invalid constant immediate operand!");
2101 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2102 assert(
N == 1 &&
"Invalid number of operands!");
2107 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2108 assert(
N == 1 &&
"Invalid number of operands!");
2112 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2113 assert(
N == 1 &&
"Invalid number of operands!");
2117 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2118 assert(
N == 1 &&
"Invalid number of operands!");
2123 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2124 assert(
N == 1 &&
"Invalid number of operands!");
2129 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2130 assert(
N == 1 &&
"Invalid number of operands!");
2135 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2141 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2142 assert(
N == 1 &&
"Invalid number of operands!");
2147 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2148 assert(
N == 1 &&
"Invalid number of operands!");
2152 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2153 assert(
N == 1 &&
"Invalid number of operands!");
2157 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2158 assert(
N == 1 &&
"Invalid number of operands!");
2162 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2169 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2170 assert(
N == 1 &&
"Invalid number of operands!");
2171 unsigned Imm = getShiftExtendAmount();
2175 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2176 assert(
N == 1 &&
"Invalid number of operands!");
2181 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2184 if (
Reg != AArch64::XZR)
2190 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2191 assert(
N == 1 &&
"Invalid number of operands!");
2198 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2199 assert(
N == 1 &&
"Invalid number of operands!");
2206 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2207 assert(
N == 2 &&
"Invalid number of operands!");
2218 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2219 assert(
N == 2 &&
"Invalid number of operands!");
2227 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2228 assert(
N == 1 &&
"Invalid number of operands!");
2232 uint64_t
Value =
CE->getValue();
2240 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2241 assert(
N == 1 &&
"Invalid number of operands!");
2244 uint64_t
Value =
CE->getValue();
2248 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2249 assert(
N == 1 &&
"Invalid number of operands!");
2254 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2255 assert(
N == 1 &&
"Invalid number of operands!");
2260 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2262 static std::unique_ptr<AArch64Operand>
2263 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2264 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2265 Op->Tok.Data = Str.data();
2266 Op->Tok.Length = Str.size();
2267 Op->Tok.IsSuffix = IsSuffix;
2273 static std::unique_ptr<AArch64Operand>
2274 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2275 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2277 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2278 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2280 Op->Reg.Kind = Kind;
2281 Op->Reg.ElementWidth = 0;
2282 Op->Reg.EqualityTy = EqTy;
2283 Op->Reg.ShiftExtend.Type = ExtTy;
2284 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2285 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2291 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2292 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2294 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2295 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2296 Kind == RegKind::SVEPredicateVector ||
2297 Kind == RegKind::SVEPredicateAsCounter) &&
2298 "Invalid vector kind");
2299 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2301 Op->Reg.ElementWidth = ElementWidth;
2305 static std::unique_ptr<AArch64Operand>
2306 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2307 unsigned NumElements,
unsigned ElementWidth,
2308 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2309 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2310 Op->VectorList.Reg =
Reg;
2312 Op->VectorList.Stride = Stride;
2313 Op->VectorList.NumElements = NumElements;
2314 Op->VectorList.ElementWidth = ElementWidth;
2315 Op->VectorList.RegisterKind = RegisterKind;
2321 static std::unique_ptr<AArch64Operand>
2322 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2323 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2324 Op->VectorIndex.Val = Idx;
2330 static std::unique_ptr<AArch64Operand>
2331 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2332 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2333 Op->MatrixTileList.RegMask = RegMask;
2339 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2340 const unsigned ElementWidth) {
2341 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2343 {{0, AArch64::ZAB0},
2344 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2345 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2346 {{8, AArch64::ZAB0},
2347 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2348 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2349 {{16, AArch64::ZAH0},
2350 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2351 {{16, AArch64::ZAH1},
2352 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2353 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2354 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2355 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2356 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2359 if (ElementWidth == 64)
2362 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2363 assert(!Regs.empty() &&
"Invalid tile or element width!");
2368 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2369 SMLoc
E, MCContext &Ctx) {
2370 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2377 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2378 unsigned ShiftAmount,
2381 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2382 Op->ShiftedImm .Val = Val;
2383 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2389 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2390 unsigned Last, SMLoc S,
2393 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2395 Op->ImmRange.Last =
Last;
2400 static std::unique_ptr<AArch64Operand>
2402 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2403 Op->CondCode.Code =
Code;
2409 static std::unique_ptr<AArch64Operand>
2410 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2411 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2413 Op->FPImm.IsExact = IsExact;
2419 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2423 bool HasnXSModifier) {
2424 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2425 Op->Barrier.Val = Val;
2426 Op->Barrier.Data = Str.data();
2427 Op->Barrier.Length = Str.size();
2428 Op->Barrier.HasnXSModifier = HasnXSModifier;
2434 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2437 uint32_t PStateField,
2439 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2440 Op->SysReg.Data = Str.data();
2441 Op->SysReg.Length = Str.size();
2442 Op->SysReg.MRSReg = MRSReg;
2443 Op->SysReg.MSRReg = MSRReg;
2444 Op->SysReg.PStateField = PStateField;
2450 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2451 SMLoc
E, MCContext &Ctx) {
2452 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2453 Op->SysCRImm.Val = Val;
2459 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2463 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2464 Op->Prefetch.Val = Val;
2465 Op->Barrier.Data = Str.data();
2466 Op->Barrier.Length = Str.size();
2472 static std::unique_ptr<AArch64Operand>
2473 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2474 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2475 Op->TIndexHint.Val = Val;
2476 Op->TIndexHint.Data = Str.data();
2477 Op->TIndexHint.Length = Str.size();
2483 static std::unique_ptr<AArch64Operand>
2484 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2485 SMLoc S, SMLoc
E, MCContext &Ctx) {
2486 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2487 Op->MatrixReg.Reg =
Reg;
2488 Op->MatrixReg.ElementWidth = ElementWidth;
2489 Op->MatrixReg.Kind = Kind;
2495 static std::unique_ptr<AArch64Operand>
2496 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2497 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2498 Op->SVCR.PStateField = PStateField;
2499 Op->SVCR.Data = Str.data();
2500 Op->SVCR.Length = Str.size();
2506 static std::unique_ptr<AArch64Operand>
2508 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2509 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2510 Op->ShiftExtend.Type = ShOp;
2511 Op->ShiftExtend.Amount = Val;
2512 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2524 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2525 if (!getFPImmIsExact())
2530 StringRef
Name = getBarrierName();
2532 OS <<
"<barrier " <<
Name <<
">";
2534 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2540 case k_ShiftedImm: {
2541 unsigned Shift = getShiftedImmShift();
2542 OS <<
"<shiftedimm ";
2549 OS << getFirstImmVal();
2550 OS <<
":" << getLastImmVal() <<
">";
2556 case k_VectorList: {
2557 OS <<
"<vectorlist ";
2558 MCRegister
Reg = getVectorListStart();
2559 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2560 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2565 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2568 OS <<
"<sysreg: " << getSysReg() <<
'>';
2574 OS <<
"c" << getSysCR();
2577 StringRef
Name = getPrefetchName();
2579 OS <<
"<prfop " <<
Name <<
">";
2581 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2585 OS << getTIndexHintName();
2587 case k_MatrixRegister:
2588 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2590 case k_MatrixTileList: {
2591 OS <<
"<matrixlist ";
2592 unsigned RegMask = getMatrixTileListRegMask();
2593 unsigned MaxBits = 8;
2594 for (
unsigned I = MaxBits;
I > 0; --
I)
2595 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2604 OS <<
"<register " <<
getReg().
id() <<
">";
2605 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2610 << getShiftExtendAmount();
2611 if (!hasShiftExtendAmount())
2627 .
Case(
"v0", AArch64::Q0)
2628 .
Case(
"v1", AArch64::Q1)
2629 .
Case(
"v2", AArch64::Q2)
2630 .
Case(
"v3", AArch64::Q3)
2631 .
Case(
"v4", AArch64::Q4)
2632 .
Case(
"v5", AArch64::Q5)
2633 .
Case(
"v6", AArch64::Q6)
2634 .
Case(
"v7", AArch64::Q7)
2635 .
Case(
"v8", AArch64::Q8)
2636 .
Case(
"v9", AArch64::Q9)
2637 .
Case(
"v10", AArch64::Q10)
2638 .
Case(
"v11", AArch64::Q11)
2639 .
Case(
"v12", AArch64::Q12)
2640 .
Case(
"v13", AArch64::Q13)
2641 .
Case(
"v14", AArch64::Q14)
2642 .
Case(
"v15", AArch64::Q15)
2643 .
Case(
"v16", AArch64::Q16)
2644 .
Case(
"v17", AArch64::Q17)
2645 .
Case(
"v18", AArch64::Q18)
2646 .
Case(
"v19", AArch64::Q19)
2647 .
Case(
"v20", AArch64::Q20)
2648 .
Case(
"v21", AArch64::Q21)
2649 .
Case(
"v22", AArch64::Q22)
2650 .
Case(
"v23", AArch64::Q23)
2651 .
Case(
"v24", AArch64::Q24)
2652 .
Case(
"v25", AArch64::Q25)
2653 .
Case(
"v26", AArch64::Q26)
2654 .
Case(
"v27", AArch64::Q27)
2655 .
Case(
"v28", AArch64::Q28)
2656 .
Case(
"v29", AArch64::Q29)
2657 .
Case(
"v30", AArch64::Q30)
2658 .
Case(
"v31", AArch64::Q31)
2667 RegKind VectorKind) {
2668 std::pair<int, int> Res = {-1, -1};
2670 switch (VectorKind) {
2671 case RegKind::NeonVector:
2674 .Case(
".1d", {1, 64})
2675 .Case(
".1q", {1, 128})
2677 .Case(
".2h", {2, 16})
2678 .Case(
".2b", {2, 8})
2679 .Case(
".2s", {2, 32})
2680 .Case(
".2d", {2, 64})
2683 .Case(
".4b", {4, 8})
2684 .Case(
".4h", {4, 16})
2685 .Case(
".4s", {4, 32})
2686 .Case(
".8b", {8, 8})
2687 .Case(
".8h", {8, 16})
2688 .Case(
".16b", {16, 8})
2693 .Case(
".h", {0, 16})
2694 .Case(
".s", {0, 32})
2695 .Case(
".d", {0, 64})
2698 case RegKind::SVEPredicateAsCounter:
2699 case RegKind::SVEPredicateVector:
2700 case RegKind::SVEDataVector:
2701 case RegKind::Matrix:
2705 .Case(
".h", {0, 16})
2706 .Case(
".s", {0, 32})
2707 .Case(
".d", {0, 64})
2708 .Case(
".q", {0, 128})
2715 if (Res == std::make_pair(-1, -1))
2716 return std::nullopt;
2718 return std::optional<std::pair<int, int>>(Res);
2727 .
Case(
"z0", AArch64::Z0)
2728 .
Case(
"z1", AArch64::Z1)
2729 .
Case(
"z2", AArch64::Z2)
2730 .
Case(
"z3", AArch64::Z3)
2731 .
Case(
"z4", AArch64::Z4)
2732 .
Case(
"z5", AArch64::Z5)
2733 .
Case(
"z6", AArch64::Z6)
2734 .
Case(
"z7", AArch64::Z7)
2735 .
Case(
"z8", AArch64::Z8)
2736 .
Case(
"z9", AArch64::Z9)
2737 .
Case(
"z10", AArch64::Z10)
2738 .
Case(
"z11", AArch64::Z11)
2739 .
Case(
"z12", AArch64::Z12)
2740 .
Case(
"z13", AArch64::Z13)
2741 .
Case(
"z14", AArch64::Z14)
2742 .
Case(
"z15", AArch64::Z15)
2743 .
Case(
"z16", AArch64::Z16)
2744 .
Case(
"z17", AArch64::Z17)
2745 .
Case(
"z18", AArch64::Z18)
2746 .
Case(
"z19", AArch64::Z19)
2747 .
Case(
"z20", AArch64::Z20)
2748 .
Case(
"z21", AArch64::Z21)
2749 .
Case(
"z22", AArch64::Z22)
2750 .
Case(
"z23", AArch64::Z23)
2751 .
Case(
"z24", AArch64::Z24)
2752 .
Case(
"z25", AArch64::Z25)
2753 .
Case(
"z26", AArch64::Z26)
2754 .
Case(
"z27", AArch64::Z27)
2755 .
Case(
"z28", AArch64::Z28)
2756 .
Case(
"z29", AArch64::Z29)
2757 .
Case(
"z30", AArch64::Z30)
2758 .
Case(
"z31", AArch64::Z31)
2764 .
Case(
"p0", AArch64::P0)
2765 .
Case(
"p1", AArch64::P1)
2766 .
Case(
"p2", AArch64::P2)
2767 .
Case(
"p3", AArch64::P3)
2768 .
Case(
"p4", AArch64::P4)
2769 .
Case(
"p5", AArch64::P5)
2770 .
Case(
"p6", AArch64::P6)
2771 .
Case(
"p7", AArch64::P7)
2772 .
Case(
"p8", AArch64::P8)
2773 .
Case(
"p9", AArch64::P9)
2774 .
Case(
"p10", AArch64::P10)
2775 .
Case(
"p11", AArch64::P11)
2776 .
Case(
"p12", AArch64::P12)
2777 .
Case(
"p13", AArch64::P13)
2778 .
Case(
"p14", AArch64::P14)
2779 .
Case(
"p15", AArch64::P15)
2785 .
Case(
"pn0", AArch64::PN0)
2786 .
Case(
"pn1", AArch64::PN1)
2787 .
Case(
"pn2", AArch64::PN2)
2788 .
Case(
"pn3", AArch64::PN3)
2789 .
Case(
"pn4", AArch64::PN4)
2790 .
Case(
"pn5", AArch64::PN5)
2791 .
Case(
"pn6", AArch64::PN6)
2792 .
Case(
"pn7", AArch64::PN7)
2793 .
Case(
"pn8", AArch64::PN8)
2794 .
Case(
"pn9", AArch64::PN9)
2795 .
Case(
"pn10", AArch64::PN10)
2796 .
Case(
"pn11", AArch64::PN11)
2797 .
Case(
"pn12", AArch64::PN12)
2798 .
Case(
"pn13", AArch64::PN13)
2799 .
Case(
"pn14", AArch64::PN14)
2800 .
Case(
"pn15", AArch64::PN15)
2806 .
Case(
"za0.d", AArch64::ZAD0)
2807 .
Case(
"za1.d", AArch64::ZAD1)
2808 .
Case(
"za2.d", AArch64::ZAD2)
2809 .
Case(
"za3.d", AArch64::ZAD3)
2810 .
Case(
"za4.d", AArch64::ZAD4)
2811 .
Case(
"za5.d", AArch64::ZAD5)
2812 .
Case(
"za6.d", AArch64::ZAD6)
2813 .
Case(
"za7.d", AArch64::ZAD7)
2814 .
Case(
"za0.s", AArch64::ZAS0)
2815 .
Case(
"za1.s", AArch64::ZAS1)
2816 .
Case(
"za2.s", AArch64::ZAS2)
2817 .
Case(
"za3.s", AArch64::ZAS3)
2818 .
Case(
"za0.h", AArch64::ZAH0)
2819 .
Case(
"za1.h", AArch64::ZAH1)
2820 .
Case(
"za0.b", AArch64::ZAB0)
2826 .
Case(
"za", AArch64::ZA)
2827 .
Case(
"za0.q", AArch64::ZAQ0)
2828 .
Case(
"za1.q", AArch64::ZAQ1)
2829 .
Case(
"za2.q", AArch64::ZAQ2)
2830 .
Case(
"za3.q", AArch64::ZAQ3)
2831 .
Case(
"za4.q", AArch64::ZAQ4)
2832 .
Case(
"za5.q", AArch64::ZAQ5)
2833 .
Case(
"za6.q", AArch64::ZAQ6)
2834 .
Case(
"za7.q", AArch64::ZAQ7)
2835 .
Case(
"za8.q", AArch64::ZAQ8)
2836 .
Case(
"za9.q", AArch64::ZAQ9)
2837 .
Case(
"za10.q", AArch64::ZAQ10)
2838 .
Case(
"za11.q", AArch64::ZAQ11)
2839 .
Case(
"za12.q", AArch64::ZAQ12)
2840 .
Case(
"za13.q", AArch64::ZAQ13)
2841 .
Case(
"za14.q", AArch64::ZAQ14)
2842 .
Case(
"za15.q", AArch64::ZAQ15)
2843 .
Case(
"za0.d", AArch64::ZAD0)
2844 .
Case(
"za1.d", AArch64::ZAD1)
2845 .
Case(
"za2.d", AArch64::ZAD2)
2846 .
Case(
"za3.d", AArch64::ZAD3)
2847 .
Case(
"za4.d", AArch64::ZAD4)
2848 .
Case(
"za5.d", AArch64::ZAD5)
2849 .
Case(
"za6.d", AArch64::ZAD6)
2850 .
Case(
"za7.d", AArch64::ZAD7)
2851 .
Case(
"za0.s", AArch64::ZAS0)
2852 .
Case(
"za1.s", AArch64::ZAS1)
2853 .
Case(
"za2.s", AArch64::ZAS2)
2854 .
Case(
"za3.s", AArch64::ZAS3)
2855 .
Case(
"za0.h", AArch64::ZAH0)
2856 .
Case(
"za1.h", AArch64::ZAH1)
2857 .
Case(
"za0.b", AArch64::ZAB0)
2858 .
Case(
"za0h.q", AArch64::ZAQ0)
2859 .
Case(
"za1h.q", AArch64::ZAQ1)
2860 .
Case(
"za2h.q", AArch64::ZAQ2)
2861 .
Case(
"za3h.q", AArch64::ZAQ3)
2862 .
Case(
"za4h.q", AArch64::ZAQ4)
2863 .
Case(
"za5h.q", AArch64::ZAQ5)
2864 .
Case(
"za6h.q", AArch64::ZAQ6)
2865 .
Case(
"za7h.q", AArch64::ZAQ7)
2866 .
Case(
"za8h.q", AArch64::ZAQ8)
2867 .
Case(
"za9h.q", AArch64::ZAQ9)
2868 .
Case(
"za10h.q", AArch64::ZAQ10)
2869 .
Case(
"za11h.q", AArch64::ZAQ11)
2870 .
Case(
"za12h.q", AArch64::ZAQ12)
2871 .
Case(
"za13h.q", AArch64::ZAQ13)
2872 .
Case(
"za14h.q", AArch64::ZAQ14)
2873 .
Case(
"za15h.q", AArch64::ZAQ15)
2874 .
Case(
"za0h.d", AArch64::ZAD0)
2875 .
Case(
"za1h.d", AArch64::ZAD1)
2876 .
Case(
"za2h.d", AArch64::ZAD2)
2877 .
Case(
"za3h.d", AArch64::ZAD3)
2878 .
Case(
"za4h.d", AArch64::ZAD4)
2879 .
Case(
"za5h.d", AArch64::ZAD5)
2880 .
Case(
"za6h.d", AArch64::ZAD6)
2881 .
Case(
"za7h.d", AArch64::ZAD7)
2882 .
Case(
"za0h.s", AArch64::ZAS0)
2883 .
Case(
"za1h.s", AArch64::ZAS1)
2884 .
Case(
"za2h.s", AArch64::ZAS2)
2885 .
Case(
"za3h.s", AArch64::ZAS3)
2886 .
Case(
"za0h.h", AArch64::ZAH0)
2887 .
Case(
"za1h.h", AArch64::ZAH1)
2888 .
Case(
"za0h.b", AArch64::ZAB0)
2889 .
Case(
"za0v.q", AArch64::ZAQ0)
2890 .
Case(
"za1v.q", AArch64::ZAQ1)
2891 .
Case(
"za2v.q", AArch64::ZAQ2)
2892 .
Case(
"za3v.q", AArch64::ZAQ3)
2893 .
Case(
"za4v.q", AArch64::ZAQ4)
2894 .
Case(
"za5v.q", AArch64::ZAQ5)
2895 .
Case(
"za6v.q", AArch64::ZAQ6)
2896 .
Case(
"za7v.q", AArch64::ZAQ7)
2897 .
Case(
"za8v.q", AArch64::ZAQ8)
2898 .
Case(
"za9v.q", AArch64::ZAQ9)
2899 .
Case(
"za10v.q", AArch64::ZAQ10)
2900 .
Case(
"za11v.q", AArch64::ZAQ11)
2901 .
Case(
"za12v.q", AArch64::ZAQ12)
2902 .
Case(
"za13v.q", AArch64::ZAQ13)
2903 .
Case(
"za14v.q", AArch64::ZAQ14)
2904 .
Case(
"za15v.q", AArch64::ZAQ15)
2905 .
Case(
"za0v.d", AArch64::ZAD0)
2906 .
Case(
"za1v.d", AArch64::ZAD1)
2907 .
Case(
"za2v.d", AArch64::ZAD2)
2908 .
Case(
"za3v.d", AArch64::ZAD3)
2909 .
Case(
"za4v.d", AArch64::ZAD4)
2910 .
Case(
"za5v.d", AArch64::ZAD5)
2911 .
Case(
"za6v.d", AArch64::ZAD6)
2912 .
Case(
"za7v.d", AArch64::ZAD7)
2913 .
Case(
"za0v.s", AArch64::ZAS0)
2914 .
Case(
"za1v.s", AArch64::ZAS1)
2915 .
Case(
"za2v.s", AArch64::ZAS2)
2916 .
Case(
"za3v.s", AArch64::ZAS3)
2917 .
Case(
"za0v.h", AArch64::ZAH0)
2918 .
Case(
"za1v.h", AArch64::ZAH1)
2919 .
Case(
"za0v.b", AArch64::ZAB0)
2923bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2925 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2928ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2930 StartLoc = getLoc();
2931 ParseStatus Res = tryParseScalarRegister(
Reg);
2937MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2939 MCRegister
Reg = MCRegister();
2941 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2944 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2947 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2950 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2953 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2955 if (
Name.equals_insensitive(
"zt0"))
2956 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2960 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2964 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2965 .Case(
"fp", AArch64::FP)
2966 .Case(
"lr", AArch64::LR)
2967 .Case(
"x31", AArch64::XZR)
2968 .Case(
"w31", AArch64::WZR)
2970 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2976 if (Entry == RegisterReqs.
end())
2977 return MCRegister();
2980 if (Kind ==
Entry->getValue().first)
2986unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2988 case RegKind::Scalar:
2989 case RegKind::NeonVector:
2990 case RegKind::SVEDataVector:
2992 case RegKind::Matrix:
2993 case RegKind::SVEPredicateVector:
2994 case RegKind::SVEPredicateAsCounter:
2996 case RegKind::LookupTable:
3005ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3006 const AsmToken &Tok = getTok();
3011 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3021ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3025 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3028 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3029 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3033 if (BadNum || CRNum > 15)
3034 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3038 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3043ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3045 const AsmToken &Tok = getTok();
3047 unsigned MaxVal = 63;
3052 const MCExpr *ImmVal;
3053 if (getParser().parseExpression(ImmVal))
3058 return TokError(
"immediate value expected for prefetch operand");
3061 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3064 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3065 Operands.
push_back(AArch64Operand::CreatePrefetch(
3066 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3072 return TokError(
"prefetch hint expected");
3074 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3076 return TokError(
"prefetch hint expected");
3078 Operands.
push_back(AArch64Operand::CreatePrefetch(
3085template <
bool IsSVEPrefetch>
3086ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3088 const AsmToken &Tok = getTok();
3090 auto LookupByName = [](StringRef
N) {
3091 if (IsSVEPrefetch) {
3092 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3093 return std::optional<unsigned>(Res->Encoding);
3094 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3095 return std::optional<unsigned>(Res->Encoding);
3096 return std::optional<unsigned>();
3099 auto LookupByEncoding = [](
unsigned E) {
3100 if (IsSVEPrefetch) {
3101 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3102 return std::optional<StringRef>(
3103 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3104 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3105 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3106 return std::optional<StringRef>();
3108 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3114 const MCExpr *ImmVal;
3115 if (getParser().parseExpression(ImmVal))
3120 return TokError(
"immediate value expected for prefetch operand");
3123 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3126 auto PRFM = LookupByEncoding(MCE->
getValue());
3127 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3133 return TokError(
"prefetch hint expected");
3135 auto PRFM = LookupByName(Tok.
getString());
3137 return TokError(
"prefetch hint expected");
3139 Operands.
push_back(AArch64Operand::CreatePrefetch(
3145ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3146 SMLoc StartLoc = getLoc();
3152 auto RegTok = getTok();
3153 if (!tryParseScalarRegister(RegNum).isSuccess())
3156 if (RegNum != AArch64::XZR) {
3157 getLexer().UnLex(RegTok);
3164 if (!tryParseScalarRegister(RegNum).isSuccess())
3165 return TokError(
"expected register operand");
3167 if (RegNum != AArch64::XZR)
3168 return TokError(
"xzr must be followed by xzr");
3172 Operands.
push_back(AArch64Operand::CreateReg(
3173 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3179ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3181 const AsmToken &Tok = getTok();
3183 return TokError(
"invalid operand for instruction");
3185 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3187 return TokError(
"invalid operand for instruction");
3189 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3197ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3199 const MCExpr *Expr =
nullptr;
3205 if (parseSymbolicImmVal(Expr))
3211 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3220 return Error(S,
"gotpage label reference not allowed an addend");
3232 return Error(S,
"page or gotpage label reference expected");
3247ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3249 const MCExpr *Expr =
nullptr;
3258 if (parseSymbolicImmVal(Expr))
3264 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3276 return Error(S,
"unexpected adr label");
3286template <
bool AddFPZeroAsLiteral>
3287ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3295 const AsmToken &Tok = getTok();
3299 return TokError(
"invalid floating point immediate");
3304 if (Tok.
getIntVal() > 255 || isNegative)
3305 return TokError(
"encoded floating point value out of range");
3309 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3312 APFloat RealVal(APFloat::IEEEdouble());
3314 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3316 return TokError(
"invalid floating point representation");
3319 RealVal.changeSign();
3321 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3325 Operands.
push_back(AArch64Operand::CreateFPImm(
3326 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3337AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3348 return tryParseImmRange(Operands);
3350 const MCExpr *
Imm =
nullptr;
3351 if (parseSymbolicImmVal(Imm))
3355 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3362 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3364 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3366 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3372 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3373 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3381 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3383 int64_t ShiftAmount = getTok().getIntVal();
3385 if (ShiftAmount < 0)
3386 return Error(getLoc(),
"positive shift amount required");
3390 if (ShiftAmount == 0 && Imm !=
nullptr) {
3392 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3396 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3404AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3438 Suggestion =
"nfrst";
3444bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3445 bool invertCondCode) {
3447 const AsmToken &Tok = getTok();
3451 std::string Suggestion;
3454 std::string Msg =
"invalid condition code";
3455 if (!Suggestion.empty())
3456 Msg +=
", did you mean " + Suggestion +
"?";
3457 return TokError(Msg);
3461 if (invertCondCode) {
3463 return TokError(
"condition codes AL and NV are invalid for this instruction");
3468 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3472ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3473 const AsmToken &Tok = getTok();
3477 return TokError(
"invalid operand for instruction");
3479 unsigned PStateImm = -1;
3480 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3483 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3484 PStateImm = SVCR->Encoding;
3492ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3493 const AsmToken &Tok = getTok();
3498 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3500 unsigned ElementWidth = 0;
3501 auto DotPosition =
Name.find(
'.');
3503 const auto &KindRes =
3507 "Expected the register to be followed by element width suffix");
3508 ElementWidth = KindRes->second;
3510 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3511 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3516 if (parseOperand(Operands,
false,
false))
3523 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3527 size_t DotPosition =
Name.find(
'.');
3530 StringRef Head =
Name.take_front(DotPosition);
3531 StringRef
Tail =
Name.drop_front(DotPosition);
3532 StringRef RowOrColumn = Head.
take_back();
3534 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3535 .Case(
"h", MatrixKind::Row)
3536 .Case(
"v", MatrixKind::Col)
3537 .Default(MatrixKind::Tile);
3543 "Expected the register to be followed by element width suffix");
3544 unsigned ElementWidth = KindRes->second;
3548 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3554 if (parseOperand(Operands,
false,
false))
3563AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3564 const AsmToken &Tok = getTok();
3567 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3596 return TokError(
"expected #imm after shift specifier");
3602 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3611 return Error(
E,
"expected integer shift amount");
3613 const MCExpr *ImmVal;
3614 if (getParser().parseExpression(ImmVal))
3619 return Error(
E,
"expected constant '#imm' after shift specifier");
3622 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3628 {{
"crc"}, {AArch64::FeatureCRC}},
3629 {{
"sm4"}, {AArch64::FeatureSM4}},
3630 {{
"sha3"}, {AArch64::FeatureSHA3}},
3631 {{
"sha2"}, {AArch64::FeatureSHA2}},
3632 {{
"aes"}, {AArch64::FeatureAES}},
3633 {{
"crypto"}, {AArch64::FeatureCrypto}},
3634 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3635 {{
"simd"}, {AArch64::FeatureNEON}},
3636 {{
"ras"}, {AArch64::FeatureRAS}},
3637 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3638 {{
"lse"}, {AArch64::FeatureLSE}},
3639 {{
"predres"}, {AArch64::FeaturePredRes}},
3640 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3641 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3642 {{
"mte"}, {AArch64::FeatureMTE}},
3643 {{
"memtag"}, {AArch64::FeatureMTE}},
3644 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3645 {{
"pan"}, {AArch64::FeaturePAN}},
3646 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3647 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3648 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3649 {{
"rng"}, {AArch64::FeatureRandGen}},
3650 {{
"sve"}, {AArch64::FeatureSVE}},
3651 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3652 {{
"sve2"}, {AArch64::FeatureSVE2}},
3653 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3654 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3655 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3656 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3657 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3658 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3659 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3661 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3662 AArch64::FeatureSVE2}},
3663 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3664 {{
"ls64"}, {AArch64::FeatureLS64}},
3665 {{
"xs"}, {AArch64::FeatureXS}},
3666 {{
"pauth"}, {AArch64::FeaturePAuth}},
3667 {{
"flagm"}, {AArch64::FeatureFlagM}},
3668 {{
"rme"}, {AArch64::FeatureRME}},
3669 {{
"sme"}, {AArch64::FeatureSME}},
3670 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3671 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3672 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3673 {{
"sme2"}, {AArch64::FeatureSME2}},
3674 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3675 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3676 {{
"hbc"}, {AArch64::FeatureHBC}},
3677 {{
"mops"}, {AArch64::FeatureMOPS}},
3678 {{
"mec"}, {AArch64::FeatureMEC}},
3679 {{
"the"}, {AArch64::FeatureTHE}},
3680 {{
"d128"}, {AArch64::FeatureD128}},
3681 {{
"lse128"}, {AArch64::FeatureLSE128}},
3682 {{
"ite"}, {AArch64::FeatureITE}},
3683 {{
"cssc"}, {AArch64::FeatureCSSC}},
3684 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3685 {{
"gcs"}, {AArch64::FeatureGCS}},
3686 {{
"bf16"}, {AArch64::FeatureBF16}},
3687 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3688 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3689 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3690 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3691 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3692 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3693 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3694 {{
"lor"}, {AArch64::FeatureLOR}},
3695 {{
"profile"}, {AArch64::FeatureSPE}},
3699 {{
"rdm"}, {AArch64::FeatureRDM}},
3700 {{
"rdma"}, {AArch64::FeatureRDM}},
3701 {{
"sb"}, {AArch64::FeatureSB}},
3702 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3703 {{
"fp8"}, {AArch64::FeatureFP8}},
3704 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3705 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3706 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3707 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3708 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3709 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3710 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3711 {{
"lut"}, {AArch64::FeatureLUT}},
3712 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3713 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3714 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3715 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3716 {{
"cpa"}, {AArch64::FeatureCPA}},
3717 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3718 {{
"pops"}, {AArch64::FeaturePoPS}},
3719 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3720 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3721 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3722 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3723 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3724 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3725 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3726 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3727 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3728 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3729 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3730 {{
"lsui"}, {AArch64::FeatureLSUI}},
3731 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3732 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3733 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3734 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3735 {{
"lscp"}, {AArch64::FeatureLSCP}},
3736 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3737 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3738 {{
"gcie"}, {AArch64::FeatureGCIE}},
3739 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3740 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3741 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3742 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3743 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3744 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3745 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3746 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3747 {{
"tev"}, {AArch64::FeatureTEV}},
3748 {{
"btie"}, {AArch64::FeatureBTIE}},
3749 {{
"hinte"}, {AArch64::FeatureHINTE}},
3750 {{
"dit"}, {AArch64::FeatureDIT}},
3751 {{
"brbe"}, {AArch64::FeatureBRBE}},
3752 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3753 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3754 {{
"jscvt"}, {AArch64::FeatureJS}},
3755 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3756 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3757 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3762 if (FBS[AArch64::HasV8_0aOps])
3764 if (FBS[AArch64::HasV8_1aOps])
3766 else if (FBS[AArch64::HasV8_2aOps])
3768 else if (FBS[AArch64::HasV8_3aOps])
3770 else if (FBS[AArch64::HasV8_4aOps])
3772 else if (FBS[AArch64::HasV8_5aOps])
3774 else if (FBS[AArch64::HasV8_6aOps])
3776 else if (FBS[AArch64::HasV8_7aOps])
3778 else if (FBS[AArch64::HasV8_8aOps])
3780 else if (FBS[AArch64::HasV8_9aOps])
3782 else if (FBS[AArch64::HasV9_0aOps])
3784 else if (FBS[AArch64::HasV9_1aOps])
3786 else if (FBS[AArch64::HasV9_2aOps])
3788 else if (FBS[AArch64::HasV9_3aOps])
3790 else if (FBS[AArch64::HasV9_4aOps])
3792 else if (FBS[AArch64::HasV9_5aOps])
3794 else if (FBS[AArch64::HasV9_6aOps])
3796 else if (FBS[AArch64::HasV9_7aOps])
3798 else if (FBS[AArch64::HasV8_0rOps])
3807 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3811void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
3813 const uint16_t Op2 = Encoding & 7;
3814 const uint16_t Cm = (Encoding & 0x78) >> 3;
3815 const uint16_t Cn = (Encoding & 0x780) >> 7;
3816 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3821 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3823 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3825 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3828 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3834bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3836 if (
Name.contains(
'.'))
3837 return TokError(
"invalid operand");
3842 const AsmToken &Tok = getTok();
3845 bool ExpectRegister =
true;
3846 bool OptionalRegister =
false;
3847 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3848 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3850 if (Mnemonic ==
"ic") {
3851 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3853 return TokError(
"invalid operand for IC instruction");
3854 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3855 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3858 return TokError(Str);
3861 createSysAlias(IC->
Encoding, Operands, S);
3862 }
else if (Mnemonic ==
"dc") {
3863 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3865 return TokError(
"invalid operand for DC instruction");
3866 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3867 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3870 return TokError(Str);
3872 createSysAlias(DC->
Encoding, Operands, S);
3873 }
else if (Mnemonic ==
"at") {
3874 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3876 return TokError(
"invalid operand for AT instruction");
3877 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3878 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3881 return TokError(Str);
3883 createSysAlias(AT->
Encoding, Operands, S);
3884 }
else if (Mnemonic ==
"tlbi") {
3885 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3887 return TokError(
"invalid operand for TLBI instruction");
3888 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3889 std::string Str(
"TLBI " +
3890 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3893 return TokError(Str);
3895 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3896 if (hasAll || hasTLBID)
3897 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3898 createSysAlias(TLBI->
Encoding, Operands, S);
3899 }
else if (Mnemonic ==
"gic") {
3900 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3902 return TokError(
"invalid operand for GIC instruction");
3903 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3904 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3907 return TokError(Str);
3910 createSysAlias(GIC->
Encoding, Operands, S);
3911 }
else if (Mnemonic ==
"gsb") {
3912 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3914 return TokError(
"invalid operand for GSB instruction");
3915 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3916 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3919 return TokError(Str);
3921 ExpectRegister =
false;
3922 createSysAlias(GSB->
Encoding, Operands, S);
3923 }
else if (Mnemonic ==
"plbi") {
3924 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3926 return TokError(
"invalid operand for PLBI instruction");
3927 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3928 std::string Str(
"PLBI " +
3929 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3932 return TokError(Str);
3934 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3935 if (hasAll || hasTLBID)
3936 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3937 createSysAlias(PLBI->
Encoding, Operands, S);
3938 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3939 Mnemonic ==
"cosp") {
3941 if (
Op.lower() !=
"rctx")
3942 return TokError(
"invalid operand for prediction restriction instruction");
3944 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3945 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3947 if (Mnemonic ==
"cosp" && !hasSpecres2)
3948 return TokError(
"COSP requires: predres2");
3950 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3952 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3953 : Mnemonic ==
"dvp" ? 0b101
3954 : Mnemonic ==
"cosp" ? 0b110
3955 : Mnemonic ==
"cpp" ? 0b111
3958 "Invalid mnemonic for prediction restriction instruction");
3959 const auto SYS_3_7_3 = 0b01101110011;
3960 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3962 createSysAlias(Encoding, Operands, S);
3967 bool HasRegister =
false;
3972 return TokError(
"expected register operand");
3976 if (!OptionalRegister) {
3977 if (ExpectRegister && !HasRegister)
3978 return TokError(
"specified " + Mnemonic +
" op requires a register");
3979 else if (!ExpectRegister && HasRegister)
3980 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3992bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
3997 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4000 SMLoc startLoc = getLoc();
4001 const AsmToken ®Tok = getTok();
4003 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4005 return TokError(
"expected register operand");
4007 Operands.
push_back(AArch64Operand::CreateReg(
4008 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4015 const AsmToken &operandTok = getTok();
4017 SMLoc S2 = operandTok.
getLoc();
4020 if (Mnemonic ==
"gicr") {
4021 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4023 return Error(S2,
"invalid operand for GICR instruction");
4024 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4025 std::string Str(
"GICR " +
4026 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4029 return Error(S2, Str);
4031 createSysAlias(GICR->
Encoding, Operands, S2);
4042bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4044 if (
Name.contains(
'.'))
4045 return TokError(
"invalid operand");
4049 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4051 const AsmToken &Tok = getTok();
4055 if (Mnemonic ==
"tlbip") {
4056 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4058 return TokError(
"invalid operand for TLBIP instruction");
4061 std::string Str(
"instruction requires: ");
4063 return TokError(Str);
4065 createSysAlias(TLBIP->
Encoding, Operands, S);
4074 return TokError(
"expected register identifier");
4075 auto Result = tryParseSyspXzrPair(Operands);
4077 Result = tryParseGPRSeqPair(Operands);
4079 return TokError(
"specified " + Mnemonic +
4080 " op requires a pair of registers");
4088ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4089 MCAsmParser &Parser = getParser();
4090 const AsmToken &Tok = getTok();
4094 const MCExpr *ImmVal;
4095 SMLoc ExprLoc = getLoc();
4096 AsmToken IntTok = Tok;
4097 if (getParser().parseExpression(ImmVal))
4101 return Error(ExprLoc,
"immediate value expected for barrier operand");
4103 if (Mnemonic ==
"dsb" &&
Value > 15) {
4111 return Error(ExprLoc,
"barrier operand out of range");
4112 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4113 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4114 Operands.
push_back(AArch64Operand::CreateBarrier(
4120 return TokError(
"invalid operand for instruction");
4123 auto DB = AArch64DB::lookupDBByName(Operand);
4125 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4126 return TokError(
"'sy' or #imm operand expected");
4128 if (Mnemonic ==
"dsb") {
4133 return TokError(
"invalid barrier option name");
4137 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4145AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4146 const AsmToken &Tok = getTok();
4148 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4149 if (Mnemonic !=
"dsb")
4154 const MCExpr *ImmVal;
4155 SMLoc ExprLoc = getLoc();
4156 if (getParser().parseExpression(ImmVal))
4160 return Error(ExprLoc,
"immediate value expected for barrier operand");
4165 return Error(ExprLoc,
"barrier operand out of range");
4166 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4167 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4168 Operands.
push_back(AArch64Operand::CreateBarrier(
4174 return TokError(
"invalid operand for instruction");
4177 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4180 return TokError(
"invalid barrier option name");
4183 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4190ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4191 const AsmToken &Tok = getTok();
4196 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4200 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4201 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4202 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4203 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4207 unsigned PStateImm = -1;
4208 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4209 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4210 PStateImm = PState15->Encoding;
4212 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4213 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4214 PStateImm = PState1->Encoding;
4218 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4226bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4234 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4242 unsigned ElementWidth = KindRes->second;
4244 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4252 return tryParseVectorIndex(Operands).isFailure();
4255ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4256 SMLoc SIdx = getLoc();
4258 const MCExpr *ImmVal;
4259 if (getParser().parseExpression(ImmVal))
4263 return TokError(
"immediate value expected for vector index");
4281ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4283 RegKind MatchKind) {
4284 const AsmToken &Tok = getTok();
4293 StringRef Head =
Name.slice(Start,
Next);
4294 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4300 return TokError(
"invalid vector kind qualifier");
4311ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4313 ParseStatus Status =
4314 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4316 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4321template <RegKind RK>
4323AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4325 const SMLoc S = getLoc();
4328 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4336 unsigned ElementWidth = KindRes->second;
4337 Operands.
push_back(AArch64Operand::CreateVectorReg(
4338 RegNum, RK, ElementWidth, S,
4342 if (RK == RegKind::SVEPredicateAsCounter) {
4343 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4349 if (parseOperand(Operands,
false,
false))
4360 return Error(S,
"not expecting size suffix");
4368 auto Pred = getTok().getString().lower();
4369 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4370 return Error(getLoc(),
"expecting 'z' predication");
4372 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4373 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4376 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4384bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4386 if (!tryParseNeonVectorRegister(Operands))
4389 if (tryParseZTOperand(Operands).isSuccess())
4393 if (tryParseGPROperand<false>(Operands).isSuccess())
4399bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4400 bool HasELFModifier =
false;
4402 SMLoc Loc = getLexer().getLoc();
4404 HasELFModifier =
true;
4407 return TokError(
"expect relocation specifier in operand after ':'");
4409 std::string LowerCase = getTok().getIdentifier().lower();
4410 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4465 return TokError(
"expect relocation specifier in operand after ':'");
4469 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4473 if (getParser().parseExpression(ImmVal))
4480 if (
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4481 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4491 if (getParser().parsePrimaryExpr(Term, EndLoc))
4499ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4503 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4504 unsigned &ElementWidth) -> ParseStatus {
4505 StringRef
Name = getTok().getString();
4506 size_t DotPosition =
Name.find(
'.');
4514 StringRef
Tail =
Name.drop_front(DotPosition);
4515 const std::optional<std::pair<int, int>> &KindRes =
4519 "Expected the register to be followed by element width suffix");
4520 ElementWidth = KindRes->second;
4527 auto LCurly = getTok();
4532 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4538 if (getTok().getString().equals_insensitive(
"za")) {
4544 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4549 SMLoc TileLoc = getLoc();
4551 unsigned FirstReg, ElementWidth;
4552 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4553 if (!ParseRes.isSuccess()) {
4554 getLexer().UnLex(LCurly);
4558 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4560 unsigned PrevReg = FirstReg;
4562 SmallSet<unsigned, 8> DRegs;
4563 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4565 SmallSet<unsigned, 8> SeenRegs;
4566 SeenRegs.
insert(FirstReg);
4570 unsigned Reg, NextElementWidth;
4571 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4572 if (!ParseRes.isSuccess())
4576 if (ElementWidth != NextElementWidth)
4577 return Error(TileLoc,
"mismatched register size suffix");
4580 Warning(TileLoc,
"tile list not in ascending order");
4583 Warning(TileLoc,
"duplicate tile in list");
4586 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4595 unsigned RegMask = 0;
4596 for (
auto Reg : DRegs)
4600 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4605template <RegKind VectorKind>
4606ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4608 MCAsmParser &Parser = getParser();
4613 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4614 bool NoMatchIsError) -> ParseStatus {
4615 auto RegTok = getTok();
4616 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4617 if (ParseRes.isSuccess()) {
4624 RegTok.getString().equals_insensitive(
"zt0"))
4628 (ParseRes.isNoMatch() && NoMatchIsError &&
4629 !RegTok.getString().starts_with_insensitive(
"za")))
4630 return Error(Loc,
"vector register expected");
4635 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4637 auto LCurly = getTok();
4641 MCRegister FirstReg;
4642 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4646 if (ParseRes.isNoMatch())
4649 if (!ParseRes.isSuccess())
4652 MCRegister PrevReg = FirstReg;
4655 unsigned Stride = 1;
4657 SMLoc Loc = getLoc();
4661 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4662 if (!ParseRes.isSuccess())
4666 if (Kind != NextKind)
4667 return Error(Loc,
"mismatched register size suffix");
4670 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4672 if (Space == 0 || Space > 3)
4673 return Error(Loc,
"invalid number of vectors");
4678 bool HasCalculatedStride =
false;
4680 SMLoc Loc = getLoc();
4683 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4684 if (!ParseRes.isSuccess())
4688 if (Kind != NextKind)
4689 return Error(Loc,
"mismatched register size suffix");
4691 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4692 unsigned PrevRegVal =
4693 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4694 if (!HasCalculatedStride) {
4695 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4696 : (NumRegs - (PrevRegVal - RegVal));
4697 HasCalculatedStride =
true;
4701 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4702 return Error(Loc,
"registers must have the same sequential stride");
4713 return Error(S,
"invalid number of vectors");
4715 unsigned NumElements = 0;
4716 unsigned ElementWidth = 0;
4717 if (!
Kind.empty()) {
4719 std::tie(NumElements, ElementWidth) = *VK;
4722 Operands.
push_back(AArch64Operand::CreateVectorList(
4723 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4727 ParseStatus Res = tryParseVectorIndex(Operands);
4737bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4738 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4739 if (!ParseRes.isSuccess())
4742 return tryParseVectorIndex(Operands).isFailure();
4745ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4746 SMLoc StartLoc = getLoc();
4749 ParseStatus Res = tryParseScalarRegister(RegNum);
4754 Operands.
push_back(AArch64Operand::CreateReg(
4755 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4762 return Error(getLoc(),
"index must be absent or #0");
4764 const MCExpr *ImmVal;
4767 return Error(getLoc(),
"index must be absent or #0");
4769 Operands.
push_back(AArch64Operand::CreateReg(
4770 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4774ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
4775 SMLoc StartLoc = getLoc();
4776 const AsmToken &Tok = getTok();
4779 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4784 Operands.
push_back(AArch64Operand::CreateReg(
4785 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4791 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4792 const MCExpr *ImmVal;
4793 if (getParser().parseExpression(ImmVal))
4797 return TokError(
"immediate value expected for vector index");
4798 Operands.
push_back(AArch64Operand::CreateImm(
4802 if (parseOptionalMulOperand(Operands))
4807 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4812template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4813ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
4814 SMLoc StartLoc = getLoc();
4817 ParseStatus Res = tryParseScalarRegister(RegNum);
4823 Operands.
push_back(AArch64Operand::CreateReg(
4824 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4833 Res = tryParseOptionalShiftExtend(ExtOpnd);
4837 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4838 Operands.
push_back(AArch64Operand::CreateReg(
4839 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4840 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4841 Ext->hasShiftExtendAmount()));
4846bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
4847 MCAsmParser &Parser = getParser();
4855 if (!getTok().getString().equals_insensitive(
"mul") ||
4856 !(NextIsVL || NextIsHash))
4860 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4865 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4875 const MCExpr *ImmVal;
4878 Operands.
push_back(AArch64Operand::CreateImm(
4885 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4888bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
4889 StringRef &VecGroup) {
4890 MCAsmParser &Parser = getParser();
4891 auto Tok = Parser.
getTok();
4896 .Case(
"vgx2",
"vgx2")
4897 .Case(
"vgx4",
"vgx4")
4908bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
4909 auto Tok = getTok();
4916 .Case(
"csync",
"csync")
4919 .Case(
"keep",
"keep")
4923 .Case(
"strm",
"strm")
4935bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
4936 bool invertCondCode) {
4937 MCAsmParser &Parser = getParser();
4940 MatchOperandParserImpl(Operands, Mnemonic,
true);
4954 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4956 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
4959 getLexer().UnLex(SavedTok);
4963 switch (getLexer().getKind()) {
4967 if (parseSymbolicImmVal(Expr))
4968 return Error(S,
"invalid operand");
4972 return parseOptionalShiftExtend(getTok());
4976 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4981 return parseOperand(Operands,
false,
false);
4984 if (!parseNeonVectorList(Operands))
4988 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
4993 return parseOperand(Operands,
false,
false);
4998 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5000 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5008 if (!parseRegister(Operands)) {
5010 AsmToken SavedTok = getTok();
5015 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5019 Res = tryParseOptionalShiftExtend(Operands);
5022 getLexer().UnLex(SavedTok);
5029 if (!parseOptionalMulOperand(Operands))
5034 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5035 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5036 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh")
5037 return parseKeywordOperand(Operands);
5041 const MCExpr *IdVal, *
Term;
5043 if (getParser().parseExpression(IdVal))
5045 if (getParser().parseAtSpecifier(IdVal,
E))
5047 std::optional<MCBinaryExpr::Opcode> Opcode;
5053 if (getParser().parsePrimaryExpr(Term,
E))
5060 return parseOptionalShiftExtend(getTok());
5071 bool isNegative =
false;
5083 const AsmToken &Tok = getTok();
5086 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5087 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5088 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5089 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5090 return TokError(
"unexpected floating point literal");
5091 else if (IntVal != 0 || isNegative)
5092 return TokError(
"expected floating-point constant #0.0");
5100 const MCExpr *ImmVal;
5101 if (parseSymbolicImmVal(ImmVal))
5108 return parseOptionalShiftExtend(Tok);
5111 SMLoc Loc = getLoc();
5112 if (Mnemonic !=
"ldr")
5113 return TokError(
"unexpected token in operand");
5115 const MCExpr *SubExprVal;
5116 if (getParser().parseExpression(SubExprVal))
5119 if (Operands.
size() < 2 ||
5120 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5121 return Error(Loc,
"Only valid when first operand is register");
5123 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5124 .contains(Operands[1]->
getReg());
5131 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5136 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5137 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5138 Operands.
push_back(AArch64Operand::CreateImm(
5142 ShiftAmt,
true, S,
E, Ctx));
5145 APInt Simm = APInt(64, Imm << ShiftAmt);
5148 return Error(Loc,
"Immediate too large for register");
5151 const MCExpr *CPLoc =
5152 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5153 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5159bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5160 const MCExpr *Expr =
nullptr;
5162 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5165 if (check(!
Value, L,
"expected constant expression"))
5167 Out =
Value->getValue();
5171bool AArch64AsmParser::parseComma() {
5179bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5183 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5188 unsigned RangeEnd =
Last;
5189 if (
Base == AArch64::X0) {
5190 if (
Last == AArch64::FP) {
5191 RangeEnd = AArch64::X28;
5192 if (
Reg == AArch64::FP) {
5197 if (
Last == AArch64::LR) {
5198 RangeEnd = AArch64::X28;
5199 if (
Reg == AArch64::FP) {
5202 }
else if (
Reg == AArch64::LR) {
5210 Twine(
"expected register in range ") +
5218bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5219 const MCParsedAsmOperand &Op2)
const {
5220 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5221 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5223 if (AOp1.isVectorList() && AOp2.isVectorList())
5224 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5225 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5226 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5228 if (!AOp1.isReg() || !AOp2.isReg())
5231 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5232 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5235 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5236 "Testing equality of non-scalar registers not supported");
5239 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5241 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5243 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5245 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5252bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5253 StringRef Name, SMLoc NameLoc,
5255 Name = StringSwitch<StringRef>(
Name.lower())
5256 .Case(
"beq",
"b.eq")
5257 .Case(
"bne",
"b.ne")
5258 .Case(
"bhs",
"b.hs")
5259 .Case(
"bcs",
"b.cs")
5260 .Case(
"blo",
"b.lo")
5261 .Case(
"bcc",
"b.cc")
5262 .Case(
"bmi",
"b.mi")
5263 .Case(
"bpl",
"b.pl")
5264 .Case(
"bvs",
"b.vs")
5265 .Case(
"bvc",
"b.vc")
5266 .Case(
"bhi",
"b.hi")
5267 .Case(
"bls",
"b.ls")
5268 .Case(
"bge",
"b.ge")
5269 .Case(
"blt",
"b.lt")
5270 .Case(
"bgt",
"b.gt")
5271 .Case(
"ble",
"b.le")
5272 .Case(
"bal",
"b.al")
5273 .Case(
"bnv",
"b.nv")
5278 getTok().getIdentifier().lower() ==
".req") {
5279 parseDirectiveReq(Name, NameLoc);
5287 StringRef Head =
Name.slice(Start,
Next);
5291 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5292 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5293 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5294 return parseSysAlias(Head, NameLoc, Operands);
5298 return parseSyslAlias(Head, NameLoc, Operands);
5301 if (Head ==
"tlbip")
5302 return parseSyspAlias(Head, NameLoc, Operands);
5311 Head =
Name.slice(Start + 1,
Next);
5315 std::string Suggestion;
5318 std::string Msg =
"invalid condition code";
5319 if (!Suggestion.empty())
5320 Msg +=
", did you mean " + Suggestion +
"?";
5321 return Error(SuffixLoc, Msg);
5326 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5336 Operands.
push_back(AArch64Operand::CreateToken(
5342 bool condCodeFourthOperand =
5343 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5344 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5345 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5353 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5354 bool condCodeThirdOperand =
5355 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5363 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5364 (
N == 3 && condCodeThirdOperand) ||
5365 (
N == 2 && condCodeSecondOperand),
5366 condCodeSecondOperand || condCodeThirdOperand)) {
5386 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5389 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5392 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5405 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5406 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5407 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5408 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5409 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5410 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5411 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5423bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5424 SmallVectorImpl<SMLoc> &Loc) {
5425 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5426 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5432 PrefixInfo
Prefix = NextPrefix;
5433 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5444 return Error(IDLoc,
"instruction is unpredictable when following a"
5445 " movprfx, suggest replacing movprfx with mov");
5449 return Error(Loc[0],
"instruction is unpredictable when following a"
5450 " movprfx writing to a different destination");
5457 return Error(Loc[0],
"instruction is unpredictable when following a"
5458 " movprfx and destination also used as non-destructive"
5462 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5463 if (
Prefix.isPredicated()) {
5477 return Error(IDLoc,
"instruction is unpredictable when following a"
5478 " predicated movprfx, suggest using unpredicated movprfx");
5482 return Error(IDLoc,
"instruction is unpredictable when following a"
5483 " predicated movprfx using a different general predicate");
5487 return Error(IDLoc,
"instruction is unpredictable when following a"
5488 " predicated movprfx with a different element size");
5494 if (IsWindowsArm64EC) {
5500 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5501 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5502 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5503 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5504 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5505 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5506 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5507 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5508 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5509 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5511 " is disallowed on ARM64EC.");
5521 case AArch64::LDPSWpre:
5522 case AArch64::LDPWpost:
5523 case AArch64::LDPWpre:
5524 case AArch64::LDPXpost:
5525 case AArch64::LDPXpre: {
5530 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5531 "is also a destination");
5533 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5534 "is also a destination");
5537 case AArch64::LDR_ZA:
5538 case AArch64::STR_ZA: {
5541 return Error(Loc[1],
5542 "unpredictable instruction, immediate and offset mismatch.");
5545 case AArch64::LDPDi:
5546 case AArch64::LDPQi:
5547 case AArch64::LDPSi:
5548 case AArch64::LDPSWi:
5549 case AArch64::LDPWi:
5550 case AArch64::LDPXi: {
5554 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5557 case AArch64::LDPDpost:
5558 case AArch64::LDPDpre:
5559 case AArch64::LDPQpost:
5560 case AArch64::LDPQpre:
5561 case AArch64::LDPSpost:
5562 case AArch64::LDPSpre:
5563 case AArch64::LDPSWpost: {
5567 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5570 case AArch64::STPDpost:
5571 case AArch64::STPDpre:
5572 case AArch64::STPQpost:
5573 case AArch64::STPQpre:
5574 case AArch64::STPSpost:
5575 case AArch64::STPSpre:
5576 case AArch64::STPWpost:
5577 case AArch64::STPWpre:
5578 case AArch64::STPXpost:
5579 case AArch64::STPXpre: {
5584 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5585 "is also a source");
5587 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5588 "is also a source");
5591 case AArch64::LDRBBpre:
5592 case AArch64::LDRBpre:
5593 case AArch64::LDRHHpre:
5594 case AArch64::LDRHpre:
5595 case AArch64::LDRSBWpre:
5596 case AArch64::LDRSBXpre:
5597 case AArch64::LDRSHWpre:
5598 case AArch64::LDRSHXpre:
5599 case AArch64::LDRSWpre:
5600 case AArch64::LDRWpre:
5601 case AArch64::LDRXpre:
5602 case AArch64::LDRBBpost:
5603 case AArch64::LDRBpost:
5604 case AArch64::LDRHHpost:
5605 case AArch64::LDRHpost:
5606 case AArch64::LDRSBWpost:
5607 case AArch64::LDRSBXpost:
5608 case AArch64::LDRSHWpost:
5609 case AArch64::LDRSHXpost:
5610 case AArch64::LDRSWpost:
5611 case AArch64::LDRWpost:
5612 case AArch64::LDRXpost: {
5616 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5617 "is also a source");
5620 case AArch64::STRBBpost:
5621 case AArch64::STRBpost:
5622 case AArch64::STRHHpost:
5623 case AArch64::STRHpost:
5624 case AArch64::STRWpost:
5625 case AArch64::STRXpost:
5626 case AArch64::STRBBpre:
5627 case AArch64::STRBpre:
5628 case AArch64::STRHHpre:
5629 case AArch64::STRHpre:
5630 case AArch64::STRWpre:
5631 case AArch64::STRXpre: {
5635 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5636 "is also a source");
5639 case AArch64::STXRB:
5640 case AArch64::STXRH:
5641 case AArch64::STXRW:
5642 case AArch64::STXRX:
5643 case AArch64::STLXRB:
5644 case AArch64::STLXRH:
5645 case AArch64::STLXRW:
5646 case AArch64::STLXRX: {
5652 return Error(Loc[0],
5653 "unpredictable STXR instruction, status is also a source");
5656 case AArch64::STXPW:
5657 case AArch64::STXPX:
5658 case AArch64::STLXPW:
5659 case AArch64::STLXPX: {
5666 return Error(Loc[0],
5667 "unpredictable STXP instruction, status is also a source");
5670 case AArch64::LDRABwriteback:
5671 case AArch64::LDRAAwriteback: {
5675 return Error(Loc[0],
5676 "unpredictable LDRA instruction, writeback base"
5677 " is also a destination");
5684 case AArch64::CPYFP:
5685 case AArch64::CPYFPWN:
5686 case AArch64::CPYFPRN:
5687 case AArch64::CPYFPN:
5688 case AArch64::CPYFPWT:
5689 case AArch64::CPYFPWTWN:
5690 case AArch64::CPYFPWTRN:
5691 case AArch64::CPYFPWTN:
5692 case AArch64::CPYFPRT:
5693 case AArch64::CPYFPRTWN:
5694 case AArch64::CPYFPRTRN:
5695 case AArch64::CPYFPRTN:
5696 case AArch64::CPYFPT:
5697 case AArch64::CPYFPTWN:
5698 case AArch64::CPYFPTRN:
5699 case AArch64::CPYFPTN:
5700 case AArch64::CPYFM:
5701 case AArch64::CPYFMWN:
5702 case AArch64::CPYFMRN:
5703 case AArch64::CPYFMN:
5704 case AArch64::CPYFMWT:
5705 case AArch64::CPYFMWTWN:
5706 case AArch64::CPYFMWTRN:
5707 case AArch64::CPYFMWTN:
5708 case AArch64::CPYFMRT:
5709 case AArch64::CPYFMRTWN:
5710 case AArch64::CPYFMRTRN:
5711 case AArch64::CPYFMRTN:
5712 case AArch64::CPYFMT:
5713 case AArch64::CPYFMTWN:
5714 case AArch64::CPYFMTRN:
5715 case AArch64::CPYFMTN:
5716 case AArch64::CPYFE:
5717 case AArch64::CPYFEWN:
5718 case AArch64::CPYFERN:
5719 case AArch64::CPYFEN:
5720 case AArch64::CPYFEWT:
5721 case AArch64::CPYFEWTWN:
5722 case AArch64::CPYFEWTRN:
5723 case AArch64::CPYFEWTN:
5724 case AArch64::CPYFERT:
5725 case AArch64::CPYFERTWN:
5726 case AArch64::CPYFERTRN:
5727 case AArch64::CPYFERTN:
5728 case AArch64::CPYFET:
5729 case AArch64::CPYFETWN:
5730 case AArch64::CPYFETRN:
5731 case AArch64::CPYFETN:
5733 case AArch64::CPYPWN:
5734 case AArch64::CPYPRN:
5735 case AArch64::CPYPN:
5736 case AArch64::CPYPWT:
5737 case AArch64::CPYPWTWN:
5738 case AArch64::CPYPWTRN:
5739 case AArch64::CPYPWTN:
5740 case AArch64::CPYPRT:
5741 case AArch64::CPYPRTWN:
5742 case AArch64::CPYPRTRN:
5743 case AArch64::CPYPRTN:
5744 case AArch64::CPYPT:
5745 case AArch64::CPYPTWN:
5746 case AArch64::CPYPTRN:
5747 case AArch64::CPYPTN:
5749 case AArch64::CPYMWN:
5750 case AArch64::CPYMRN:
5751 case AArch64::CPYMN:
5752 case AArch64::CPYMWT:
5753 case AArch64::CPYMWTWN:
5754 case AArch64::CPYMWTRN:
5755 case AArch64::CPYMWTN:
5756 case AArch64::CPYMRT:
5757 case AArch64::CPYMRTWN:
5758 case AArch64::CPYMRTRN:
5759 case AArch64::CPYMRTN:
5760 case AArch64::CPYMT:
5761 case AArch64::CPYMTWN:
5762 case AArch64::CPYMTRN:
5763 case AArch64::CPYMTN:
5765 case AArch64::CPYEWN:
5766 case AArch64::CPYERN:
5767 case AArch64::CPYEN:
5768 case AArch64::CPYEWT:
5769 case AArch64::CPYEWTWN:
5770 case AArch64::CPYEWTRN:
5771 case AArch64::CPYEWTN:
5772 case AArch64::CPYERT:
5773 case AArch64::CPYERTWN:
5774 case AArch64::CPYERTRN:
5775 case AArch64::CPYERTN:
5776 case AArch64::CPYET:
5777 case AArch64::CPYETWN:
5778 case AArch64::CPYETRN:
5779 case AArch64::CPYETN: {
5790 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5791 " registers are the same");
5793 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5794 " registers are the same");
5796 return Error(Loc[0],
"invalid CPY instruction, source and size"
5797 " registers are the same");
5801 case AArch64::SETPT:
5802 case AArch64::SETPN:
5803 case AArch64::SETPTN:
5805 case AArch64::SETMT:
5806 case AArch64::SETMN:
5807 case AArch64::SETMTN:
5809 case AArch64::SETET:
5810 case AArch64::SETEN:
5811 case AArch64::SETETN:
5812 case AArch64::SETGP:
5813 case AArch64::SETGPT:
5814 case AArch64::SETGPN:
5815 case AArch64::SETGPTN:
5816 case AArch64::SETGM:
5817 case AArch64::SETGMT:
5818 case AArch64::SETGMN:
5819 case AArch64::SETGMTN:
5820 case AArch64::MOPSSETGE:
5821 case AArch64::MOPSSETGET:
5822 case AArch64::MOPSSETGEN:
5823 case AArch64::MOPSSETGETN: {
5833 return Error(Loc[0],
"invalid SET instruction, destination and size"
5834 " registers are the same");
5836 return Error(Loc[0],
"invalid SET instruction, destination and source"
5837 " registers are the same");
5839 return Error(Loc[0],
"invalid SET instruction, source and size"
5840 " registers are the same");
5843 case AArch64::SETGOP:
5844 case AArch64::SETGOPT:
5845 case AArch64::SETGOPN:
5846 case AArch64::SETGOPTN:
5847 case AArch64::SETGOM:
5848 case AArch64::SETGOMT:
5849 case AArch64::SETGOMN:
5850 case AArch64::SETGOMTN:
5851 case AArch64::SETGOE:
5852 case AArch64::SETGOET:
5853 case AArch64::SETGOEN:
5854 case AArch64::SETGOETN: {
5863 return Error(Loc[0],
"invalid SET instruction, destination and size"
5864 " registers are the same");
5873 case AArch64::ADDSWri:
5874 case AArch64::ADDSXri:
5875 case AArch64::ADDWri:
5876 case AArch64::ADDXri:
5877 case AArch64::SUBSWri:
5878 case AArch64::SUBSXri:
5879 case AArch64::SUBWri:
5880 case AArch64::SUBXri: {
5888 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5913 return Error(Loc.
back(),
"invalid immediate expression");
5926 unsigned VariantID = 0);
5928bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5932 case Match_InvalidTiedOperand: {
5933 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
5934 if (
Op.isVectorList())
5935 return Error(
Loc,
"operand must match destination register list");
5937 assert(
Op.isReg() &&
"Unexpected operand type");
5938 switch (
Op.getRegEqualityTy()) {
5939 case RegConstraintEqualityTy::EqualsSubReg:
5940 return Error(
Loc,
"operand must be 64-bit form of destination register");
5941 case RegConstraintEqualityTy::EqualsSuperReg:
5942 return Error(
Loc,
"operand must be 32-bit form of destination register");
5943 case RegConstraintEqualityTy::EqualsReg:
5944 return Error(
Loc,
"operand must match destination register");
5948 case Match_MissingFeature:
5950 "instruction requires a CPU feature not currently enabled");
5951 case Match_InvalidOperand:
5952 return Error(Loc,
"invalid operand for instruction");
5953 case Match_InvalidSuffix:
5954 return Error(Loc,
"invalid type suffix for instruction");
5955 case Match_InvalidCondCode:
5956 return Error(Loc,
"expected AArch64 condition code");
5957 case Match_AddSubRegExtendSmall:
5959 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5960 case Match_AddSubRegExtendLarge:
5962 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5963 case Match_AddSubSecondSource:
5965 "expected compatible register, symbol or integer in range [0, 4095]");
5966 case Match_LogicalSecondSource:
5967 return Error(Loc,
"expected compatible register or logical immediate");
5968 case Match_InvalidMovImm32Shift:
5969 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5970 case Match_InvalidMovImm64Shift:
5971 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5972 case Match_AddSubRegShift32:
5974 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5975 case Match_AddSubRegShift64:
5977 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5978 case Match_InvalidFPImm:
5980 "expected compatible register or floating-point constant");
5981 case Match_InvalidMemoryIndexedSImm6:
5982 return Error(Loc,
"index must be an integer in range [-32, 31].");
5983 case Match_InvalidMemoryIndexedSImm5:
5984 return Error(Loc,
"index must be an integer in range [-16, 15].");
5985 case Match_InvalidMemoryIndexed1SImm4:
5986 return Error(Loc,
"index must be an integer in range [-8, 7].");
5987 case Match_InvalidMemoryIndexed2SImm4:
5988 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5989 case Match_InvalidMemoryIndexed3SImm4:
5990 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5991 case Match_InvalidMemoryIndexed4SImm4:
5992 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5993 case Match_InvalidMemoryIndexed16SImm4:
5994 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5995 case Match_InvalidMemoryIndexed32SImm4:
5996 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5997 case Match_InvalidMemoryIndexed1SImm6:
5998 return Error(Loc,
"index must be an integer in range [-32, 31].");
5999 case Match_InvalidMemoryIndexedSImm8:
6000 return Error(Loc,
"index must be an integer in range [-128, 127].");
6001 case Match_InvalidMemoryIndexedSImm9:
6002 return Error(Loc,
"index must be an integer in range [-256, 255].");
6003 case Match_InvalidMemoryIndexed16SImm9:
6004 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6005 case Match_InvalidMemoryIndexed8SImm10:
6006 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6007 case Match_InvalidMemoryIndexed4SImm7:
6008 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6009 case Match_InvalidMemoryIndexed8SImm7:
6010 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6011 case Match_InvalidMemoryIndexed16SImm7:
6012 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6013 case Match_InvalidMemoryIndexed8UImm5:
6014 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6015 case Match_InvalidMemoryIndexed8UImm3:
6016 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6017 case Match_InvalidMemoryIndexed4UImm5:
6018 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6019 case Match_InvalidMemoryIndexed2UImm5:
6020 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6021 case Match_InvalidMemoryIndexed8UImm6:
6022 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6023 case Match_InvalidMemoryIndexed16UImm6:
6024 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6025 case Match_InvalidMemoryIndexed4UImm6:
6026 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6027 case Match_InvalidMemoryIndexed2UImm6:
6028 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6029 case Match_InvalidMemoryIndexed1UImm6:
6030 return Error(Loc,
"index must be in range [0, 63].");
6031 case Match_InvalidMemoryWExtend8:
6033 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6034 case Match_InvalidMemoryWExtend16:
6036 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6037 case Match_InvalidMemoryWExtend32:
6039 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6040 case Match_InvalidMemoryWExtend64:
6042 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6043 case Match_InvalidMemoryWExtend128:
6045 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6046 case Match_InvalidMemoryXExtend8:
6048 "expected 'lsl' or 'sxtx' with optional shift of #0");
6049 case Match_InvalidMemoryXExtend16:
6051 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6052 case Match_InvalidMemoryXExtend32:
6054 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6055 case Match_InvalidMemoryXExtend64:
6057 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6058 case Match_InvalidMemoryXExtend128:
6060 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6061 case Match_InvalidMemoryIndexed1:
6062 return Error(Loc,
"index must be an integer in range [0, 4095].");
6063 case Match_InvalidMemoryIndexed2:
6064 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6065 case Match_InvalidMemoryIndexed4:
6066 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6067 case Match_InvalidMemoryIndexed8:
6068 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6069 case Match_InvalidMemoryIndexed16:
6070 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6071 case Match_InvalidImm0_0:
6072 return Error(Loc,
"immediate must be 0.");
6073 case Match_InvalidImm0_1:
6074 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6075 case Match_InvalidImm0_3:
6076 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6077 case Match_InvalidImm0_7:
6078 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6079 case Match_InvalidImm0_15:
6080 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6081 case Match_InvalidImm0_31:
6082 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6083 case Match_InvalidImm0_63:
6084 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6085 case Match_InvalidImm0_127:
6086 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6087 case Match_InvalidImm0_255:
6088 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6089 case Match_InvalidImm0_65535:
6090 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6091 case Match_InvalidHinteUImm16:
6093 "immediate must be an integer in range [0, 65535], excluding "
6094 "values in range [12319, 16383] where (value - 12319) is a "
6096 case Match_InvalidImm1_8:
6097 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6098 case Match_InvalidImm1_16:
6099 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6100 case Match_InvalidImm1_32:
6101 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6102 case Match_InvalidImm1_64:
6103 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6104 case Match_InvalidImmM1_62:
6105 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6106 case Match_InvalidMemoryIndexedRange2UImm0:
6107 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6108 case Match_InvalidMemoryIndexedRange2UImm1:
6109 return Error(Loc,
"vector select offset must be an immediate range of the "
6110 "form <immf>:<imml>, where the first "
6111 "immediate is a multiple of 2 in the range [0, 2], and "
6112 "the second immediate is immf + 1.");
6113 case Match_InvalidMemoryIndexedRange2UImm2:
6114 case Match_InvalidMemoryIndexedRange2UImm3:
6117 "vector select offset must be an immediate range of the form "
6119 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6121 "depending on the instruction, and the second immediate is immf + 1.");
6122 case Match_InvalidMemoryIndexedRange4UImm0:
6123 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6124 case Match_InvalidMemoryIndexedRange4UImm1:
6125 case Match_InvalidMemoryIndexedRange4UImm2:
6128 "vector select offset must be an immediate range of the form "
6130 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6132 "depending on the instruction, and the second immediate is immf + 3.");
6133 case Match_InvalidSVEAddSubImm8:
6134 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6135 " with a shift amount of 0");
6136 case Match_InvalidSVEAddSubImm16:
6137 case Match_InvalidSVEAddSubImm32:
6138 case Match_InvalidSVEAddSubImm64:
6139 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6140 "multiple of 256 in range [256, 65280]");
6141 case Match_InvalidSVECpyImm8:
6142 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6143 " with a shift amount of 0");
6144 case Match_InvalidSVECpyImm16:
6145 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6146 "multiple of 256 in range [-32768, 65280]");
6147 case Match_InvalidSVECpyImm32:
6148 case Match_InvalidSVECpyImm64:
6149 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6150 "multiple of 256 in range [-32768, 32512]");
6151 case Match_InvalidIndexRange0_0:
6152 return Error(Loc,
"expected lane specifier '[0]'");
6153 case Match_InvalidIndexRange1_1:
6154 return Error(Loc,
"expected lane specifier '[1]'");
6155 case Match_InvalidIndexRange0_15:
6156 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6157 case Match_InvalidIndexRange0_7:
6158 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6159 case Match_InvalidIndexRange0_3:
6160 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6161 case Match_InvalidIndexRange0_1:
6162 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6163 case Match_InvalidSVEIndexRange0_63:
6164 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6165 case Match_InvalidSVEIndexRange0_31:
6166 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6167 case Match_InvalidSVEIndexRange0_15:
6168 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6169 case Match_InvalidSVEIndexRange0_7:
6170 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6171 case Match_InvalidSVEIndexRange0_3:
6172 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6173 case Match_InvalidLabel:
6174 return Error(Loc,
"expected label or encodable integer pc offset");
6176 return Error(Loc,
"expected readable system register");
6178 case Match_InvalidSVCR:
6179 return Error(Loc,
"expected writable system register or pstate");
6180 case Match_InvalidComplexRotationEven:
6181 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6182 case Match_InvalidComplexRotationOdd:
6183 return Error(Loc,
"complex rotation must be 90 or 270.");
6184 case Match_MnemonicFail: {
6186 ((AArch64Operand &)*Operands[0]).
getToken(),
6187 ComputeAvailableFeatures(STI->getFeatureBits()));
6188 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6190 case Match_InvalidGPR64shifted8:
6191 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6192 case Match_InvalidGPR64shifted16:
6193 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6194 case Match_InvalidGPR64shifted32:
6195 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6196 case Match_InvalidGPR64shifted64:
6197 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6198 case Match_InvalidGPR64shifted128:
6200 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6201 case Match_InvalidGPR64NoXZRshifted8:
6202 return Error(Loc,
"register must be x0..x30 without shift");
6203 case Match_InvalidGPR64NoXZRshifted16:
6204 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6205 case Match_InvalidGPR64NoXZRshifted32:
6206 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6207 case Match_InvalidGPR64NoXZRshifted64:
6208 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6209 case Match_InvalidGPR64NoXZRshifted128:
6210 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6211 case Match_InvalidZPR32UXTW8:
6212 case Match_InvalidZPR32SXTW8:
6213 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6214 case Match_InvalidZPR32UXTW16:
6215 case Match_InvalidZPR32SXTW16:
6216 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6217 case Match_InvalidZPR32UXTW32:
6218 case Match_InvalidZPR32SXTW32:
6219 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6220 case Match_InvalidZPR32UXTW64:
6221 case Match_InvalidZPR32SXTW64:
6222 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6223 case Match_InvalidZPR64UXTW8:
6224 case Match_InvalidZPR64SXTW8:
6225 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6226 case Match_InvalidZPR64UXTW16:
6227 case Match_InvalidZPR64SXTW16:
6228 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6229 case Match_InvalidZPR64UXTW32:
6230 case Match_InvalidZPR64SXTW32:
6231 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6232 case Match_InvalidZPR64UXTW64:
6233 case Match_InvalidZPR64SXTW64:
6234 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6235 case Match_InvalidZPR32LSL8:
6236 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6237 case Match_InvalidZPR32LSL16:
6238 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6239 case Match_InvalidZPR32LSL32:
6240 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6241 case Match_InvalidZPR32LSL64:
6242 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6243 case Match_InvalidZPR64LSL8:
6244 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6245 case Match_InvalidZPR64LSL16:
6246 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6247 case Match_InvalidZPR64LSL32:
6248 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6249 case Match_InvalidZPR64LSL64:
6250 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6251 case Match_InvalidZPR0:
6252 return Error(Loc,
"expected register without element width suffix");
6253 case Match_InvalidZPR8:
6254 case Match_InvalidZPR16:
6255 case Match_InvalidZPR32:
6256 case Match_InvalidZPR64:
6257 case Match_InvalidZPR128:
6258 return Error(Loc,
"invalid element width");
6259 case Match_InvalidZPR_3b8:
6260 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6261 case Match_InvalidZPR_3b16:
6262 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6263 case Match_InvalidZPR_3b32:
6264 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6265 case Match_InvalidZPR_4b8:
6267 "Invalid restricted vector register, expected z0.b..z15.b");
6268 case Match_InvalidZPR_4b16:
6269 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6270 case Match_InvalidZPR_4b32:
6271 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6272 case Match_InvalidZPR_4b64:
6273 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6274 case Match_InvalidZPRMul2_Lo8:
6275 return Error(Loc,
"Invalid restricted vector register, expected even "
6276 "register in z0.b..z14.b");
6277 case Match_InvalidZPRMul2_Hi8:
6278 return Error(Loc,
"Invalid restricted vector register, expected even "
6279 "register in z16.b..z30.b");
6280 case Match_InvalidZPRMul2_Lo16:
6281 return Error(Loc,
"Invalid restricted vector register, expected even "
6282 "register in z0.h..z14.h");
6283 case Match_InvalidZPRMul2_Hi16:
6284 return Error(Loc,
"Invalid restricted vector register, expected even "
6285 "register in z16.h..z30.h");
6286 case Match_InvalidZPRMul2_Lo32:
6287 return Error(Loc,
"Invalid restricted vector register, expected even "
6288 "register in z0.s..z14.s");
6289 case Match_InvalidZPRMul2_Hi32:
6290 return Error(Loc,
"Invalid restricted vector register, expected even "
6291 "register in z16.s..z30.s");
6292 case Match_InvalidZPRMul2_Lo64:
6293 return Error(Loc,
"Invalid restricted vector register, expected even "
6294 "register in z0.d..z14.d");
6295 case Match_InvalidZPRMul2_Hi64:
6296 return Error(Loc,
"Invalid restricted vector register, expected even "
6297 "register in z16.d..z30.d");
6298 case Match_InvalidZPR_K0:
6299 return Error(Loc,
"invalid restricted vector register, expected register "
6300 "in z20..z23 or z28..z31");
6301 case Match_InvalidSVEPattern:
6302 return Error(Loc,
"invalid predicate pattern");
6303 case Match_InvalidSVEPPRorPNRAnyReg:
6304 case Match_InvalidSVEPPRorPNRBReg:
6305 case Match_InvalidSVEPredicateAnyReg:
6306 case Match_InvalidSVEPredicateBReg:
6307 case Match_InvalidSVEPredicateHReg:
6308 case Match_InvalidSVEPredicateSReg:
6309 case Match_InvalidSVEPredicateDReg:
6310 return Error(Loc,
"invalid predicate register.");
6311 case Match_InvalidSVEPredicate3bAnyReg:
6312 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6313 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6314 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6315 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6316 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6317 return Error(Loc,
"Invalid predicate register, expected PN in range "
6318 "pn8..pn15 with element suffix.");
6319 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6320 return Error(Loc,
"invalid restricted predicate-as-counter register "
6321 "expected pn8..pn15");
6322 case Match_InvalidSVEPNPredicateBReg:
6323 case Match_InvalidSVEPNPredicateHReg:
6324 case Match_InvalidSVEPNPredicateSReg:
6325 case Match_InvalidSVEPNPredicateDReg:
6326 return Error(Loc,
"Invalid predicate register, expected PN in range "
6327 "pn0..pn15 with element suffix.");
6328 case Match_InvalidSVEVecLenSpecifier:
6329 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6330 case Match_InvalidSVEPredicateListMul2x8:
6331 case Match_InvalidSVEPredicateListMul2x16:
6332 case Match_InvalidSVEPredicateListMul2x32:
6333 case Match_InvalidSVEPredicateListMul2x64:
6334 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6335 "predicate registers, where the first vector is a multiple of 2 "
6336 "and with correct element type");
6337 case Match_InvalidSVEExactFPImmOperandHalfOne:
6338 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6339 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6340 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6341 case Match_InvalidSVEExactFPImmOperandZeroOne:
6342 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6343 case Match_InvalidMatrixTileVectorH8:
6344 case Match_InvalidMatrixTileVectorV8:
6345 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6346 case Match_InvalidMatrixTileVectorH16:
6347 case Match_InvalidMatrixTileVectorV16:
6349 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6350 case Match_InvalidMatrixTileVectorH32:
6351 case Match_InvalidMatrixTileVectorV32:
6353 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6354 case Match_InvalidMatrixTileVectorH64:
6355 case Match_InvalidMatrixTileVectorV64:
6357 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6358 case Match_InvalidMatrixTileVectorH128:
6359 case Match_InvalidMatrixTileVectorV128:
6361 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6362 case Match_InvalidMatrixTile16:
6363 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6364 case Match_InvalidMatrixTile32:
6365 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6366 case Match_InvalidMatrixTile64:
6367 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6368 case Match_InvalidMatrix:
6369 return Error(Loc,
"invalid matrix operand, expected za");
6370 case Match_InvalidMatrix8:
6371 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6372 case Match_InvalidMatrix16:
6373 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6374 case Match_InvalidMatrix32:
6375 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6376 case Match_InvalidMatrix64:
6377 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6378 case Match_InvalidMatrixIndexGPR32_12_15:
6379 return Error(Loc,
"operand must be a register in range [w12, w15]");
6380 case Match_InvalidMatrixIndexGPR32_8_11:
6381 return Error(Loc,
"operand must be a register in range [w8, w11]");
6382 case Match_InvalidSVEVectorList2x8Mul2:
6383 case Match_InvalidSVEVectorList2x16Mul2:
6384 case Match_InvalidSVEVectorList2x32Mul2:
6385 case Match_InvalidSVEVectorList2x64Mul2:
6386 case Match_InvalidSVEVectorList2x128Mul2:
6387 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6388 "SVE vectors, where the first vector is a multiple of 2 "
6389 "and with matching element types");
6390 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6391 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6392 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6393 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6394 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6395 "SVE vectors in the range z0-z14, where the first vector "
6396 "is a multiple of 2 "
6397 "and with matching element types");
6398 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6399 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6400 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6401 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6403 "Invalid vector list, expected list with 2 consecutive "
6404 "SVE vectors in the range z16-z30, where the first vector "
6405 "is a multiple of 2 "
6406 "and with matching element types");
6407 case Match_InvalidSVEVectorList4x8Mul4:
6408 case Match_InvalidSVEVectorList4x16Mul4:
6409 case Match_InvalidSVEVectorList4x32Mul4:
6410 case Match_InvalidSVEVectorList4x64Mul4:
6411 case Match_InvalidSVEVectorList4x128Mul4:
6412 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6413 "SVE vectors, where the first vector is a multiple of 4 "
6414 "and with matching element types");
6415 case Match_InvalidLookupTable:
6416 return Error(Loc,
"Invalid lookup table, expected zt0");
6417 case Match_InvalidSVEVectorListStrided2x8:
6418 case Match_InvalidSVEVectorListStrided2x16:
6419 case Match_InvalidSVEVectorListStrided2x32:
6420 case Match_InvalidSVEVectorListStrided2x64:
6423 "Invalid vector list, expected list with each SVE vector in the list "
6424 "8 registers apart, and the first register in the range [z0, z7] or "
6425 "[z16, z23] and with correct element type");
6426 case Match_InvalidSVEVectorListStrided4x8:
6427 case Match_InvalidSVEVectorListStrided4x16:
6428 case Match_InvalidSVEVectorListStrided4x32:
6429 case Match_InvalidSVEVectorListStrided4x64:
6432 "Invalid vector list, expected list with each SVE vector in the list "
6433 "4 registers apart, and the first register in the range [z0, z3] or "
6434 "[z16, z19] and with correct element type");
6435 case Match_AddSubLSLImm3ShiftLarge:
6437 "expected 'lsl' with optional integer in range [0, 7]");
6445bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6449 bool MatchingInlineAsm) {
6450 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6451 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6452 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6455 unsigned NumOperands = Operands.
size();
6457 if (NumOperands == 4 && Tok ==
"lsl") {
6458 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6459 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6460 if (Op2.isScalarReg() && Op3.isImm()) {
6466 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6468 NewOp3Val = (32 - Op3Val) & 0x1f;
6469 NewOp4Val = 31 - Op3Val;
6471 NewOp3Val = (64 - Op3Val) & 0x3f;
6472 NewOp4Val = 63 - Op3Val;
6479 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6480 Operands.
push_back(AArch64Operand::CreateImm(
6481 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6482 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6486 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6488 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6489 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6490 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6492 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6496 if (LSBCE && WidthCE) {
6498 uint64_t Width = WidthCE->
getValue();
6500 uint64_t RegWidth = 0;
6501 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6507 if (LSB >= RegWidth)
6508 return Error(LSBOp.getStartLoc(),
6509 "expected integer in range [0, 31]");
6510 if (Width < 1 || Width > RegWidth)
6511 return Error(WidthOp.getStartLoc(),
6512 "expected integer in range [1, 32]");
6516 ImmR = (32 - LSB) & 0x1f;
6518 ImmR = (64 - LSB) & 0x3f;
6520 uint64_t ImmS = Width - 1;
6522 if (ImmR != 0 && ImmS >= ImmR)
6523 return Error(WidthOp.getStartLoc(),
6524 "requested insert overflows register");
6529 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6530 Operands[2] = AArch64Operand::CreateReg(
6531 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6533 Operands[3] = AArch64Operand::CreateImm(
6534 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6536 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6540 }
else if (NumOperands == 5) {
6543 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6544 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6545 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6546 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6548 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6552 if (Op3CE && Op4CE) {
6553 uint64_t Op3Val = Op3CE->
getValue();
6554 uint64_t Op4Val = Op4CE->
getValue();
6556 uint64_t RegWidth = 0;
6557 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6563 if (Op3Val >= RegWidth)
6564 return Error(Op3.getStartLoc(),
6565 "expected integer in range [0, 31]");
6566 if (Op4Val < 1 || Op4Val > RegWidth)
6567 return Error(Op4.getStartLoc(),
6568 "expected integer in range [1, 32]");
6570 uint64_t NewOp3Val = 0;
6572 NewOp3Val = (32 - Op3Val) & 0x1f;
6574 NewOp3Val = (64 - Op3Val) & 0x3f;
6576 uint64_t NewOp4Val = Op4Val - 1;
6578 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6579 return Error(Op4.getStartLoc(),
6580 "requested insert overflows register");
6582 const MCExpr *NewOp3 =
6584 const MCExpr *NewOp4 =
6586 Operands[3] = AArch64Operand::CreateImm(
6587 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6588 Operands[4] = AArch64Operand::CreateImm(
6589 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6591 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6593 else if (Tok ==
"sbfiz")
6594 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6596 else if (Tok ==
"ubfiz")
6597 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6606 }
else if (NumOperands == 5 &&
6607 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6608 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6609 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6610 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6612 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6616 if (Op3CE && Op4CE) {
6617 uint64_t Op3Val = Op3CE->
getValue();
6618 uint64_t Op4Val = Op4CE->
getValue();
6620 uint64_t RegWidth = 0;
6621 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6627 if (Op3Val >= RegWidth)
6628 return Error(Op3.getStartLoc(),
6629 "expected integer in range [0, 31]");
6630 if (Op4Val < 1 || Op4Val > RegWidth)
6631 return Error(Op4.getStartLoc(),
6632 "expected integer in range [1, 32]");
6634 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6636 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6637 return Error(Op4.getStartLoc(),
6638 "requested extract overflows register");
6640 const MCExpr *NewOp4 =
6642 Operands[4] = AArch64Operand::CreateImm(
6643 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6645 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6647 else if (Tok ==
"sbfx")
6648 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6650 else if (Tok ==
"ubfx")
6651 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6664 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6665 NumOperands == 4 && Tok ==
"movi") {
6666 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6667 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6668 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6669 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6670 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6671 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6672 if (Suffix.
lower() ==
".2d" &&
6674 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6675 " correctly on this CPU, converting to equivalent movi.16b");
6677 unsigned Idx = Op1.isToken() ? 1 : 2;
6679 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6687 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6690 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6691 if (
Op.isScalarReg()) {
6693 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6694 Op.getStartLoc(),
Op.getEndLoc(),
6699 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6700 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6701 if (
Op.isScalarReg() &&
6702 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6706 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6707 if (
Op.isScalarReg()) {
6709 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6716 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6717 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6718 if (
Op.isScalarReg() &&
6719 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6723 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6724 if (
Op.isScalarReg()) {
6726 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6734 FeatureBitset MissingFeatures;
6737 unsigned MatchResult =
6738 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6739 MatchingInlineAsm, 1);
6743 if (MatchResult != Match_Success) {
6746 auto ShortFormNEONErrorInfo = ErrorInfo;
6747 auto ShortFormNEONMatchResult = MatchResult;
6748 auto ShortFormNEONMissingFeatures = MissingFeatures;
6751 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6752 MatchingInlineAsm, 0);
6757 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6758 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6759 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6760 MatchResult = ShortFormNEONMatchResult;
6761 ErrorInfo = ShortFormNEONErrorInfo;
6762 MissingFeatures = ShortFormNEONMissingFeatures;
6766 switch (MatchResult) {
6767 case Match_Success: {
6770 NumOperands = Operands.
size();
6771 for (
unsigned i = 1; i < NumOperands; ++i)
6772 OperandLocs.
push_back(Operands[i]->getStartLoc());
6773 if (validateInstruction(Inst, IDLoc, OperandLocs))
6780 case Match_MissingFeature: {
6781 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6784 std::string Msg =
"instruction requires:";
6785 for (
unsigned Feature : MissingFeatures) {
6789 return Error(IDLoc, Msg);
6791 case Match_MnemonicFail:
6792 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
6793 case Match_InvalidOperand: {
6794 SMLoc ErrorLoc = IDLoc;
6796 if (ErrorInfo != ~0ULL) {
6797 if (ErrorInfo >= Operands.
size())
6798 return Error(IDLoc,
"too few operands for instruction",
6799 SMRange(IDLoc, getTok().getLoc()));
6801 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
6802 if (ErrorLoc == SMLoc())
6807 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
6808 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
6809 MatchResult = Match_InvalidSuffix;
6811 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
6813 case Match_InvalidTiedOperand:
6814 case Match_InvalidMemoryIndexed1:
6815 case Match_InvalidMemoryIndexed2:
6816 case Match_InvalidMemoryIndexed4:
6817 case Match_InvalidMemoryIndexed8:
6818 case Match_InvalidMemoryIndexed16:
6819 case Match_InvalidCondCode:
6820 case Match_AddSubLSLImm3ShiftLarge:
6821 case Match_AddSubRegExtendSmall:
6822 case Match_AddSubRegExtendLarge:
6823 case Match_AddSubSecondSource:
6824 case Match_LogicalSecondSource:
6825 case Match_AddSubRegShift32:
6826 case Match_AddSubRegShift64:
6827 case Match_InvalidMovImm32Shift:
6828 case Match_InvalidMovImm64Shift:
6829 case Match_InvalidFPImm:
6830 case Match_InvalidMemoryWExtend8:
6831 case Match_InvalidMemoryWExtend16:
6832 case Match_InvalidMemoryWExtend32:
6833 case Match_InvalidMemoryWExtend64:
6834 case Match_InvalidMemoryWExtend128:
6835 case Match_InvalidMemoryXExtend8:
6836 case Match_InvalidMemoryXExtend16:
6837 case Match_InvalidMemoryXExtend32:
6838 case Match_InvalidMemoryXExtend64:
6839 case Match_InvalidMemoryXExtend128:
6840 case Match_InvalidMemoryIndexed1SImm4:
6841 case Match_InvalidMemoryIndexed2SImm4:
6842 case Match_InvalidMemoryIndexed3SImm4:
6843 case Match_InvalidMemoryIndexed4SImm4:
6844 case Match_InvalidMemoryIndexed1SImm6:
6845 case Match_InvalidMemoryIndexed16SImm4:
6846 case Match_InvalidMemoryIndexed32SImm4:
6847 case Match_InvalidMemoryIndexed4SImm7:
6848 case Match_InvalidMemoryIndexed8SImm7:
6849 case Match_InvalidMemoryIndexed16SImm7:
6850 case Match_InvalidMemoryIndexed8UImm5:
6851 case Match_InvalidMemoryIndexed8UImm3:
6852 case Match_InvalidMemoryIndexed4UImm5:
6853 case Match_InvalidMemoryIndexed2UImm5:
6854 case Match_InvalidMemoryIndexed1UImm6:
6855 case Match_InvalidMemoryIndexed2UImm6:
6856 case Match_InvalidMemoryIndexed4UImm6:
6857 case Match_InvalidMemoryIndexed8UImm6:
6858 case Match_InvalidMemoryIndexed16UImm6:
6859 case Match_InvalidMemoryIndexedSImm6:
6860 case Match_InvalidMemoryIndexedSImm5:
6861 case Match_InvalidMemoryIndexedSImm8:
6862 case Match_InvalidMemoryIndexedSImm9:
6863 case Match_InvalidMemoryIndexed16SImm9:
6864 case Match_InvalidMemoryIndexed8SImm10:
6865 case Match_InvalidImm0_0:
6866 case Match_InvalidImm0_1:
6867 case Match_InvalidImm0_3:
6868 case Match_InvalidImm0_7:
6869 case Match_InvalidImm0_15:
6870 case Match_InvalidImm0_31:
6871 case Match_InvalidImm0_63:
6872 case Match_InvalidImm0_127:
6873 case Match_InvalidImm0_255:
6874 case Match_InvalidImm0_65535:
6875 case Match_InvalidHinteUImm16:
6876 case Match_InvalidImm1_8:
6877 case Match_InvalidImm1_16:
6878 case Match_InvalidImm1_32:
6879 case Match_InvalidImm1_64:
6880 case Match_InvalidImmM1_62:
6881 case Match_InvalidMemoryIndexedRange2UImm0:
6882 case Match_InvalidMemoryIndexedRange2UImm1:
6883 case Match_InvalidMemoryIndexedRange2UImm2:
6884 case Match_InvalidMemoryIndexedRange2UImm3:
6885 case Match_InvalidMemoryIndexedRange4UImm0:
6886 case Match_InvalidMemoryIndexedRange4UImm1:
6887 case Match_InvalidMemoryIndexedRange4UImm2:
6888 case Match_InvalidSVEAddSubImm8:
6889 case Match_InvalidSVEAddSubImm16:
6890 case Match_InvalidSVEAddSubImm32:
6891 case Match_InvalidSVEAddSubImm64:
6892 case Match_InvalidSVECpyImm8:
6893 case Match_InvalidSVECpyImm16:
6894 case Match_InvalidSVECpyImm32:
6895 case Match_InvalidSVECpyImm64:
6896 case Match_InvalidIndexRange0_0:
6897 case Match_InvalidIndexRange1_1:
6898 case Match_InvalidIndexRange0_15:
6899 case Match_InvalidIndexRange0_7:
6900 case Match_InvalidIndexRange0_3:
6901 case Match_InvalidIndexRange0_1:
6902 case Match_InvalidSVEIndexRange0_63:
6903 case Match_InvalidSVEIndexRange0_31:
6904 case Match_InvalidSVEIndexRange0_15:
6905 case Match_InvalidSVEIndexRange0_7:
6906 case Match_InvalidSVEIndexRange0_3:
6907 case Match_InvalidLabel:
6908 case Match_InvalidComplexRotationEven:
6909 case Match_InvalidComplexRotationOdd:
6910 case Match_InvalidGPR64shifted8:
6911 case Match_InvalidGPR64shifted16:
6912 case Match_InvalidGPR64shifted32:
6913 case Match_InvalidGPR64shifted64:
6914 case Match_InvalidGPR64shifted128:
6915 case Match_InvalidGPR64NoXZRshifted8:
6916 case Match_InvalidGPR64NoXZRshifted16:
6917 case Match_InvalidGPR64NoXZRshifted32:
6918 case Match_InvalidGPR64NoXZRshifted64:
6919 case Match_InvalidGPR64NoXZRshifted128:
6920 case Match_InvalidZPR32UXTW8:
6921 case Match_InvalidZPR32UXTW16:
6922 case Match_InvalidZPR32UXTW32:
6923 case Match_InvalidZPR32UXTW64:
6924 case Match_InvalidZPR32SXTW8:
6925 case Match_InvalidZPR32SXTW16:
6926 case Match_InvalidZPR32SXTW32:
6927 case Match_InvalidZPR32SXTW64:
6928 case Match_InvalidZPR64UXTW8:
6929 case Match_InvalidZPR64SXTW8:
6930 case Match_InvalidZPR64UXTW16:
6931 case Match_InvalidZPR64SXTW16:
6932 case Match_InvalidZPR64UXTW32:
6933 case Match_InvalidZPR64SXTW32:
6934 case Match_InvalidZPR64UXTW64:
6935 case Match_InvalidZPR64SXTW64:
6936 case Match_InvalidZPR32LSL8:
6937 case Match_InvalidZPR32LSL16:
6938 case Match_InvalidZPR32LSL32:
6939 case Match_InvalidZPR32LSL64:
6940 case Match_InvalidZPR64LSL8:
6941 case Match_InvalidZPR64LSL16:
6942 case Match_InvalidZPR64LSL32:
6943 case Match_InvalidZPR64LSL64:
6944 case Match_InvalidZPR0:
6945 case Match_InvalidZPR8:
6946 case Match_InvalidZPR16:
6947 case Match_InvalidZPR32:
6948 case Match_InvalidZPR64:
6949 case Match_InvalidZPR128:
6950 case Match_InvalidZPR_3b8:
6951 case Match_InvalidZPR_3b16:
6952 case Match_InvalidZPR_3b32:
6953 case Match_InvalidZPR_4b8:
6954 case Match_InvalidZPR_4b16:
6955 case Match_InvalidZPR_4b32:
6956 case Match_InvalidZPR_4b64:
6957 case Match_InvalidSVEPPRorPNRAnyReg:
6958 case Match_InvalidSVEPPRorPNRBReg:
6959 case Match_InvalidSVEPredicateAnyReg:
6960 case Match_InvalidSVEPattern:
6961 case Match_InvalidSVEVecLenSpecifier:
6962 case Match_InvalidSVEPredicateBReg:
6963 case Match_InvalidSVEPredicateHReg:
6964 case Match_InvalidSVEPredicateSReg:
6965 case Match_InvalidSVEPredicateDReg:
6966 case Match_InvalidSVEPredicate3bAnyReg:
6967 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6968 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6969 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6970 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6971 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6972 case Match_InvalidSVEPNPredicateBReg:
6973 case Match_InvalidSVEPNPredicateHReg:
6974 case Match_InvalidSVEPNPredicateSReg:
6975 case Match_InvalidSVEPNPredicateDReg:
6976 case Match_InvalidSVEPredicateListMul2x8:
6977 case Match_InvalidSVEPredicateListMul2x16:
6978 case Match_InvalidSVEPredicateListMul2x32:
6979 case Match_InvalidSVEPredicateListMul2x64:
6980 case Match_InvalidSVEExactFPImmOperandHalfOne:
6981 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6982 case Match_InvalidSVEExactFPImmOperandZeroOne:
6983 case Match_InvalidMatrixTile16:
6984 case Match_InvalidMatrixTile32:
6985 case Match_InvalidMatrixTile64:
6986 case Match_InvalidMatrix:
6987 case Match_InvalidMatrix8:
6988 case Match_InvalidMatrix16:
6989 case Match_InvalidMatrix32:
6990 case Match_InvalidMatrix64:
6991 case Match_InvalidMatrixTileVectorH8:
6992 case Match_InvalidMatrixTileVectorH16:
6993 case Match_InvalidMatrixTileVectorH32:
6994 case Match_InvalidMatrixTileVectorH64:
6995 case Match_InvalidMatrixTileVectorH128:
6996 case Match_InvalidMatrixTileVectorV8:
6997 case Match_InvalidMatrixTileVectorV16:
6998 case Match_InvalidMatrixTileVectorV32:
6999 case Match_InvalidMatrixTileVectorV64:
7000 case Match_InvalidMatrixTileVectorV128:
7001 case Match_InvalidSVCR:
7002 case Match_InvalidMatrixIndexGPR32_12_15:
7003 case Match_InvalidMatrixIndexGPR32_8_11:
7004 case Match_InvalidLookupTable:
7005 case Match_InvalidZPRMul2_Lo8:
7006 case Match_InvalidZPRMul2_Hi8:
7007 case Match_InvalidZPRMul2_Lo16:
7008 case Match_InvalidZPRMul2_Hi16:
7009 case Match_InvalidZPRMul2_Lo32:
7010 case Match_InvalidZPRMul2_Hi32:
7011 case Match_InvalidZPRMul2_Lo64:
7012 case Match_InvalidZPRMul2_Hi64:
7013 case Match_InvalidZPR_K0:
7014 case Match_InvalidSVEVectorList2x8Mul2:
7015 case Match_InvalidSVEVectorList2x16Mul2:
7016 case Match_InvalidSVEVectorList2x32Mul2:
7017 case Match_InvalidSVEVectorList2x64Mul2:
7018 case Match_InvalidSVEVectorList2x128Mul2:
7019 case Match_InvalidSVEVectorList4x8Mul4:
7020 case Match_InvalidSVEVectorList4x16Mul4:
7021 case Match_InvalidSVEVectorList4x32Mul4:
7022 case Match_InvalidSVEVectorList4x64Mul4:
7023 case Match_InvalidSVEVectorList4x128Mul4:
7024 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7025 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7026 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7027 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7028 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7029 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7030 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7031 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7032 case Match_InvalidSVEVectorListStrided2x8:
7033 case Match_InvalidSVEVectorListStrided2x16:
7034 case Match_InvalidSVEVectorListStrided2x32:
7035 case Match_InvalidSVEVectorListStrided2x64:
7036 case Match_InvalidSVEVectorListStrided4x8:
7037 case Match_InvalidSVEVectorListStrided4x16:
7038 case Match_InvalidSVEVectorListStrided4x32:
7039 case Match_InvalidSVEVectorListStrided4x64:
7042 if (ErrorInfo >= Operands.
size())
7043 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7046 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7047 if (ErrorLoc == SMLoc())
7049 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7057bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7064 SMLoc Loc = DirectiveID.
getLoc();
7065 if (IDVal ==
".arch")
7066 parseDirectiveArch(Loc);
7067 else if (IDVal ==
".cpu")
7068 parseDirectiveCPU(Loc);
7069 else if (IDVal ==
".tlsdesccall")
7070 parseDirectiveTLSDescCall(Loc);
7071 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7072 parseDirectiveLtorg(Loc);
7073 else if (IDVal ==
".unreq")
7074 parseDirectiveUnreq(Loc);
7075 else if (IDVal ==
".inst")
7076 parseDirectiveInst(Loc);
7077 else if (IDVal ==
".cfi_negate_ra_state")
7078 parseDirectiveCFINegateRAState();
7079 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7080 parseDirectiveCFINegateRAStateWithPC();
7081 else if (IDVal ==
".cfi_b_key_frame")
7082 parseDirectiveCFIBKeyFrame();
7083 else if (IDVal ==
".cfi_mte_tagged_frame")
7084 parseDirectiveCFIMTETaggedFrame();
7085 else if (IDVal ==
".arch_extension")
7086 parseDirectiveArchExtension(Loc);
7087 else if (IDVal ==
".variant_pcs")
7088 parseDirectiveVariantPCS(Loc);
7091 parseDirectiveLOH(IDVal, Loc);
7094 }
else if (IsCOFF) {
7095 if (IDVal ==
".seh_stackalloc")
7096 parseDirectiveSEHAllocStack(Loc);
7097 else if (IDVal ==
".seh_endprologue")
7098 parseDirectiveSEHPrologEnd(Loc);
7099 else if (IDVal ==
".seh_save_r19r20_x")
7100 parseDirectiveSEHSaveR19R20X(Loc);
7101 else if (IDVal ==
".seh_save_fplr")
7102 parseDirectiveSEHSaveFPLR(Loc);
7103 else if (IDVal ==
".seh_save_fplr_x")
7104 parseDirectiveSEHSaveFPLRX(Loc);
7105 else if (IDVal ==
".seh_save_reg")
7106 parseDirectiveSEHSaveReg(Loc);
7107 else if (IDVal ==
".seh_save_reg_x")
7108 parseDirectiveSEHSaveRegX(Loc);
7109 else if (IDVal ==
".seh_save_regp")
7110 parseDirectiveSEHSaveRegP(Loc);
7111 else if (IDVal ==
".seh_save_regp_x")
7112 parseDirectiveSEHSaveRegPX(Loc);
7113 else if (IDVal ==
".seh_save_lrpair")
7114 parseDirectiveSEHSaveLRPair(Loc);
7115 else if (IDVal ==
".seh_save_freg")
7116 parseDirectiveSEHSaveFReg(Loc);
7117 else if (IDVal ==
".seh_save_freg_x")
7118 parseDirectiveSEHSaveFRegX(Loc);
7119 else if (IDVal ==
".seh_save_fregp")
7120 parseDirectiveSEHSaveFRegP(Loc);
7121 else if (IDVal ==
".seh_save_fregp_x")
7122 parseDirectiveSEHSaveFRegPX(Loc);
7123 else if (IDVal ==
".seh_set_fp")
7124 parseDirectiveSEHSetFP(Loc);
7125 else if (IDVal ==
".seh_add_fp")
7126 parseDirectiveSEHAddFP(Loc);
7127 else if (IDVal ==
".seh_nop")
7128 parseDirectiveSEHNop(Loc);
7129 else if (IDVal ==
".seh_save_next")
7130 parseDirectiveSEHSaveNext(Loc);
7131 else if (IDVal ==
".seh_startepilogue")
7132 parseDirectiveSEHEpilogStart(Loc);
7133 else if (IDVal ==
".seh_endepilogue")
7134 parseDirectiveSEHEpilogEnd(Loc);
7135 else if (IDVal ==
".seh_trap_frame")
7136 parseDirectiveSEHTrapFrame(Loc);
7137 else if (IDVal ==
".seh_pushframe")
7138 parseDirectiveSEHMachineFrame(Loc);
7139 else if (IDVal ==
".seh_context")
7140 parseDirectiveSEHContext(Loc);
7141 else if (IDVal ==
".seh_ec_context")
7142 parseDirectiveSEHECContext(Loc);
7143 else if (IDVal ==
".seh_clear_unwound_to_call")
7144 parseDirectiveSEHClearUnwoundToCall(Loc);
7145 else if (IDVal ==
".seh_pac_sign_lr")
7146 parseDirectiveSEHPACSignLR(Loc);
7147 else if (IDVal ==
".seh_save_any_reg")
7148 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7149 else if (IDVal ==
".seh_save_any_reg_p")
7150 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7151 else if (IDVal ==
".seh_save_any_reg_x")
7152 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7153 else if (IDVal ==
".seh_save_any_reg_px")
7154 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7155 else if (IDVal ==
".seh_allocz")
7156 parseDirectiveSEHAllocZ(Loc);
7157 else if (IDVal ==
".seh_save_zreg")
7158 parseDirectiveSEHSaveZReg(Loc);
7159 else if (IDVal ==
".seh_save_preg")
7160 parseDirectiveSEHSavePReg(Loc);
7164 if (IDVal ==
".aeabi_subsection")
7165 parseDirectiveAeabiSubSectionHeader(Loc);
7166 else if (IDVal ==
".aeabi_attribute")
7167 parseDirectiveAeabiAArch64Attr(Loc);
7180 if (!NoCrypto && Crypto) {
7183 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7184 ArchInfo == AArch64::ARMV8_3A) {
7188 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7189 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7190 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7191 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7192 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7193 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7199 }
else if (NoCrypto) {
7202 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7203 ArchInfo == AArch64::ARMV8_3A) {
7204 RequestedExtensions.
push_back(
"nosha2");
7207 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7208 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7209 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7210 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7211 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7212 ArchInfo == AArch64::ARMV9_4A) {
7214 RequestedExtensions.
push_back(
"nosha3");
7215 RequestedExtensions.
push_back(
"nosha2");
7227bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7228 SMLoc CurLoc = getLoc();
7230 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7231 StringRef Arch, ExtensionString;
7232 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7236 return Error(CurLoc,
"unknown arch name");
7242 std::vector<StringRef> AArch64Features;
7243 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7246 MCSubtargetInfo &STI = copySTI();
7247 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7249 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7252 if (!ExtensionString.
empty())
7253 ExtensionString.
split(RequestedExtensions,
'+');
7258 for (
auto Name : RequestedExtensions) {
7262 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7269 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7277 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7278 setAvailableFeatures(Features);
7280 getTargetStreamer().emitDirectiveArch(Name);
7286bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7287 SMLoc ExtLoc = getLoc();
7289 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7294 bool EnableFeature =
true;
7295 StringRef
Name = FullName;
7296 if (
Name.starts_with_insensitive(
"no")) {
7297 EnableFeature =
false;
7306 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7308 MCSubtargetInfo &STI = copySTI();
7313 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7314 setAvailableFeatures(Features);
7316 getTargetStreamer().emitDirectiveArchExtension(FullName);
7322bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7323 SMLoc CurLoc = getLoc();
7325 StringRef CPU, ExtensionString;
7326 std::tie(CPU, ExtensionString) =
7327 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7333 if (!ExtensionString.
empty())
7334 ExtensionString.
split(RequestedExtensions,
'+');
7338 Error(CurLoc,
"unknown CPU name");
7343 MCSubtargetInfo &STI = copySTI();
7347 for (
auto Name : RequestedExtensions) {
7351 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7358 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7366 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7367 setAvailableFeatures(Features);
7373bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7375 return Error(Loc,
"expected expression following '.inst' directive");
7377 auto parseOp = [&]() ->
bool {
7379 const MCExpr *Expr =
nullptr;
7380 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7383 if (check(!
Value, L,
"expected constant expression"))
7385 getTargetStreamer().emitInst(
Value->getValue());
7389 return parseMany(parseOp);
7394bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7396 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7408 getParser().getStreamer().emitInstruction(Inst, getSTI());
7414bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7418 return TokError(
"expected an identifier or a number in directive");
7421 int64_t
Id = getTok().getIntVal();
7423 return TokError(
"invalid numeric identifier in directive");
7426 StringRef
Name = getTok().getIdentifier();
7432 return TokError(
"invalid identifier in directive");
7440 assert(NbArgs != -1 &&
"Invalid number of arguments");
7443 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7445 if (getParser().parseIdentifier(Name))
7446 return TokError(
"expected identifier in directive");
7449 if (Idx + 1 == NbArgs)
7457 getStreamer().emitLOHDirective(Kind, Args);
7463bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7466 getTargetStreamer().emitCurrentConstantPool();
7472bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7474 SMLoc SRegLoc = getLoc();
7475 RegKind RegisterKind = RegKind::Scalar;
7477 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7481 RegisterKind = RegKind::NeonVector;
7482 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7488 return Error(SRegLoc,
"vector register without type specifier expected");
7493 RegisterKind = RegKind::SVEDataVector;
7495 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7501 return Error(SRegLoc,
7502 "sve vector register without type specifier expected");
7507 RegisterKind = RegKind::SVEPredicateVector;
7508 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7514 return Error(SRegLoc,
7515 "sve predicate register without type specifier expected");
7519 return Error(SRegLoc,
"register name or alias expected");
7525 auto pair = std::make_pair(RegisterKind, RegNum);
7526 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7527 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7534bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7536 return TokError(
"unexpected input in .unreq directive.");
7537 RegisterReqs.
erase(getTok().getIdentifier().lower());
7542bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7545 getStreamer().emitCFINegateRAState();
7549bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7552 getStreamer().emitCFINegateRAStateWithPC();
7558bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7561 getStreamer().emitCFIBKeyFrame();
7567bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7570 getStreamer().emitCFIMTETaggedFrame();
7576bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7578 if (getParser().parseIdentifier(Name))
7579 return TokError(
"expected symbol name");
7582 getTargetStreamer().emitDirectiveVariantPCS(
7589bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7591 if (parseImmExpr(
Size))
7593 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7599bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7600 getTargetStreamer().emitARM64WinCFIPrologEnd();
7606bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7608 if (parseImmExpr(
Offset))
7610 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7616bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7618 if (parseImmExpr(
Offset))
7620 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7626bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7628 if (parseImmExpr(
Offset))
7630 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7636bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7639 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7640 parseComma() || parseImmExpr(
Offset))
7642 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7648bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7651 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7652 parseComma() || parseImmExpr(
Offset))
7654 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7660bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7663 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7664 parseComma() || parseImmExpr(
Offset))
7666 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7672bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7675 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7676 parseComma() || parseImmExpr(
Offset))
7678 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7684bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7688 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7689 parseComma() || parseImmExpr(
Offset))
7691 if (check(((
Reg - 19) % 2 != 0), L,
7692 "expected register with even offset from x19"))
7694 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7700bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7703 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7704 parseComma() || parseImmExpr(
Offset))
7706 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7712bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7715 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7716 parseComma() || parseImmExpr(
Offset))
7718 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7724bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7727 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7728 parseComma() || parseImmExpr(
Offset))
7730 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7736bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7739 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7740 parseComma() || parseImmExpr(
Offset))
7742 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7748bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7749 getTargetStreamer().emitARM64WinCFISetFP();
7755bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7757 if (parseImmExpr(
Size))
7759 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7765bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7766 getTargetStreamer().emitARM64WinCFINop();
7772bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7773 getTargetStreamer().emitARM64WinCFISaveNext();
7779bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7780 getTargetStreamer().emitARM64WinCFIEpilogStart();
7786bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7787 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7793bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7794 getTargetStreamer().emitARM64WinCFITrapFrame();
7800bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7801 getTargetStreamer().emitARM64WinCFIMachineFrame();
7807bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7808 getTargetStreamer().emitARM64WinCFIContext();
7814bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7815 getTargetStreamer().emitARM64WinCFIECContext();
7821bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7822 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7828bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7829 getTargetStreamer().emitARM64WinCFIPACSignLR();
7838bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7843 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7844 parseComma() || parseImmExpr(
Offset))
7847 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7848 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7849 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7850 return Error(L,
"invalid save_any_reg offset");
7851 unsigned EncodedReg;
7852 if (
Reg == AArch64::FP)
7854 else if (
Reg == AArch64::LR)
7857 EncodedReg =
Reg - AArch64::X0;
7859 if (
Reg == AArch64::LR)
7860 return Error(Start,
"lr cannot be paired with another register");
7862 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7864 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7867 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7869 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7871 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7872 unsigned EncodedReg =
Reg - AArch64::D0;
7873 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7874 return Error(L,
"invalid save_any_reg offset");
7876 if (
Reg == AArch64::D31)
7877 return Error(Start,
"d31 cannot be paired with another register");
7879 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7881 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7884 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7886 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7888 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7889 unsigned EncodedReg =
Reg - AArch64::Q0;
7891 return Error(L,
"invalid save_any_reg offset");
7893 if (
Reg == AArch64::Q31)
7894 return Error(Start,
"q31 cannot be paired with another register");
7896 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7898 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7901 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7903 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7906 return Error(Start,
"save_any_reg register must be x, q or d register");
7913bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7915 if (parseImmExpr(
Offset))
7917 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7923bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
7928 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7931 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
7932 "expected register in range z8 to z23"))
7934 if (parseComma() || parseImmExpr(
Offset))
7936 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
7942bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
7947 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7950 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
7951 "expected register in range p4 to p15"))
7953 if (parseComma() || parseImmExpr(
Offset))
7955 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
7959bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
7965 MCAsmParser &Parser = getParser();
7968 StringRef SubsectionName;
7979 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
7980 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
7985 if (SubsectionExists) {
7986 getTargetStreamer().emitAttributesSubsection(
7989 SubsectionExists->IsOptional),
7991 SubsectionExists->ParameterType));
7997 "Could not switch to subsection '" + SubsectionName +
7998 "' using subsection name, subsection has not been defined");
8021 if (SubsectionExists) {
8022 if (IsOptional != SubsectionExists->IsOptional) {
8024 "optionality mismatch! subsection '" + SubsectionName +
8025 "' already exists with optionality defined as '" +
8027 SubsectionExists->IsOptional) +
8035 "optionality parameter not found, expected required|optional");
8042 "aeabi_feature_and_bits must be marked as optional");
8049 "aeabi_pauthabi must be marked as required");
8069 if (SubsectionExists) {
8070 if (
Type != SubsectionExists->ParameterType) {
8072 "type mismatch! subsection '" + SubsectionName +
8073 "' already exists with type defined as '" +
8075 SubsectionExists->ParameterType) +
8083 "type parameter not found, expected uleb128|ntbs");
8091 SubsectionName +
" must be marked as ULEB128");
8100 "attributes subsection header directive");
8104 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8109bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8113 MCAsmParser &Parser = getParser();
8115 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8116 getTargetStreamer().getActiveAttributesSubsection();
8117 if (
nullptr == ActiveSubsection) {
8119 "no active subsection, build attribute can not be added");
8122 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8123 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8131 ActiveSubsectionName)
8134 StringRef TagStr =
"";
8137 Tag = getTok().getIntVal();
8140 switch (ActiveSubsectionID) {
8145 "' \nExcept for public subsections, "
8146 "tags have to be an unsigned int.");
8153 TagStr +
"' for subsection '" +
8154 ActiveSubsectionName +
"'");
8162 TagStr +
"' for subsection '" +
8163 ActiveSubsectionName +
"'");
8181 unsigned ValueInt = unsigned(-1);
8182 std::string ValueStr =
"";
8187 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8190 ValueInt = getTok().getIntVal();
8195 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8203 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8214 if (0 != ValueInt && 1 != ValueInt) {
8216 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8217 "' options are 0|1");
8226 "unexpected token for AArch64 build attributes tag and value "
8227 "attribute directive");
8231 if (
unsigned(-1) != ValueInt) {
8232 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8234 if (
"" != ValueStr) {
8235 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8241bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8242 SMLoc Loc = getLoc();
8244 return TokError(
"expected '%' relocation specifier");
8245 StringRef
Identifier = getParser().getTok().getIdentifier();
8248 return TokError(
"invalid relocation specifier");
8254 const MCExpr *SubExpr;
8255 if (getParser().parseParenExpression(SubExpr,
E))
8262bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8265 return parseExprWithSpecifier(Res, EndLoc);
8267 if (getParser().parseExpression(Res))
8269 MCAsmParser &Parser = getParser();
8273 return Error(getLoc(),
"expected relocation specifier");
8276 SMLoc Loc = getLoc();
8278 if (Identifier ==
"auth")
8279 return parseAuthExpr(Res, EndLoc);
8283 if (Identifier ==
"got")
8287 return Error(Loc,
"invalid relocation specifier");
8292 return Error(Loc,
"@ specifier only allowed after a symbol");
8295 std::optional<MCBinaryExpr::Opcode> Opcode;
8303 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8314bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8315 MCAsmParser &Parser = getParser();
8317 AsmToken Tok = Parser.
getTok();
8324 return TokError(
"expected key name");
8329 return TokError(
"invalid key '" + KeyStr +
"'");
8336 return TokError(
"expected integer discriminator");
8340 return TokError(
"integer discriminator " + Twine(Discriminator) +
8341 " out of range [0, 0xFFFF]");
8344 bool UseAddressDiversity =
false;
8349 return TokError(
"expected 'addr'");
8350 UseAddressDiversity =
true;
8359 UseAddressDiversity, Ctx, Res->
getLoc());
8363bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8372 ELFSpec = AE->getSpecifier();
8373 Expr = AE->getSubExpr();
8413#define GET_REGISTER_MATCHER
8414#define GET_SUBTARGET_FEATURE_NAME
8415#define GET_MATCHER_IMPLEMENTATION
8416#define GET_MNEMONIC_SPELL_CHECKER
8417#include "AArch64GenAsmMatcher.inc"
8423 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8425 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8427 return Match_InvalidOperand;
8430 return Match_InvalidOperand;
8431 if (CE->getValue() == ExpectedVal)
8432 return Match_Success;
8433 return Match_InvalidOperand;
8438 return Match_InvalidOperand;
8444 if (
Op.isTokenEqual(
"za"))
8445 return Match_Success;
8446 return Match_InvalidOperand;
8452#define MATCH_HASH(N) \
8453 case MCK__HASH_##N: \
8454 return MatchesOpImmediate(N);
8480#define MATCH_HASH_MINUS(N) \
8481 case MCK__HASH__MINUS_##N: \
8482 return MatchesOpImmediate(-N);
8486#undef MATCH_HASH_MINUS
8490ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8495 return Error(S,
"expected register");
8497 MCRegister FirstReg;
8498 ParseStatus Res = tryParseScalarRegister(FirstReg);
8500 return Error(S,
"expected first even register of a consecutive same-size "
8501 "even/odd register pair");
8503 const MCRegisterClass &WRegClass =
8504 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8505 const MCRegisterClass &XRegClass =
8506 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8508 bool isXReg = XRegClass.
contains(FirstReg),
8509 isWReg = WRegClass.
contains(FirstReg);
8510 if (!isXReg && !isWReg)
8511 return Error(S,
"expected first even register of a consecutive same-size "
8512 "even/odd register pair");
8514 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8517 if (FirstEncoding & 0x1)
8518 return Error(S,
"expected first even register of a consecutive same-size "
8519 "even/odd register pair");
8522 return Error(getLoc(),
"expected comma");
8527 MCRegister SecondReg;
8528 Res = tryParseScalarRegister(SecondReg);
8530 return Error(
E,
"expected second odd register of a consecutive same-size "
8531 "even/odd register pair");
8534 (isXReg && !XRegClass.
contains(SecondReg)) ||
8535 (isWReg && !WRegClass.
contains(SecondReg)))
8536 return Error(
E,
"expected second odd register of a consecutive same-size "
8537 "even/odd register pair");
8542 FirstReg, AArch64::sube64,
8543 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8546 FirstReg, AArch64::sube32,
8547 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8550 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8556template <
bool ParseShiftExtend,
bool ParseSuffix>
8557ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8558 const SMLoc S = getLoc();
8564 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8569 if (ParseSuffix &&
Kind.empty())
8576 unsigned ElementWidth = KindRes->second;
8580 Operands.
push_back(AArch64Operand::CreateVectorReg(
8581 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8583 ParseStatus Res = tryParseVectorIndex(Operands);
8594 Res = tryParseOptionalShiftExtend(ExtOpnd);
8598 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8599 Operands.
push_back(AArch64Operand::CreateVectorReg(
8600 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8601 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8602 Ext->hasShiftExtendAmount()));
8607ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8608 MCAsmParser &Parser = getParser();
8610 SMLoc
SS = getLoc();
8611 const AsmToken &TokE = getTok();
8622 const MCExpr *ImmVal;
8629 return TokError(
"invalid operand for instruction");
8634 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8639 Pattern = Pat->Encoding;
8640 assert(Pattern >= 0 && Pattern < 32);
8651AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8653 SMLoc
SS = getLoc();
8654 const AsmToken &TokE = getTok();
8656 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8662 Pattern = Pat->Encoding;
8663 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8672ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8673 SMLoc
SS = getLoc();
8676 if (!tryParseScalarRegister(XReg).isSuccess())
8682 XReg, AArch64::x8sub_0,
8683 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8686 "expected an even-numbered x-register in the range [x0,x22]");
8689 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8693ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8703 if (getParser().parseExpression(ImmF))
8713 SMLoc
E = getTok().getLoc();
8715 if (getParser().parseExpression(ImmL))
8722 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8727ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8737 if (getParser().parseExpression(Ex))
8747 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8754 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
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.
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
Context & getContext() const
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