73 SVEPredicateAsCounter,
79enum class MatrixKind { Array, Tile, Row, Col };
81enum RegConstraintEqualityTy {
92 StringMap<std::pair<RegKind, MCRegister>> RegisterReqs;
96 static PrefixInfo CreateFromInst(
const MCInst &Inst, uint64_t TSFlags) {
99 case AArch64::MOVPRFX_ZZ:
103 case AArch64::MOVPRFX_ZPmZ_B:
104 case AArch64::MOVPRFX_ZPmZ_H:
105 case AArch64::MOVPRFX_ZPmZ_S:
106 case AArch64::MOVPRFX_ZPmZ_D:
111 "No destructive element size set for movprfx");
115 case AArch64::MOVPRFX_ZPzZ_B:
116 case AArch64::MOVPRFX_ZPzZ_H:
117 case AArch64::MOVPRFX_ZPzZ_S:
118 case AArch64::MOVPRFX_ZPzZ_D:
123 "No destructive element size set for movprfx");
134 PrefixInfo() =
default;
135 bool isActive()
const {
return Active; }
137 unsigned getElementSize()
const {
141 MCRegister getDstReg()
const {
return Dst; }
142 MCRegister getPgReg()
const {
149 bool Predicated =
false;
150 unsigned ElementSize;
155 AArch64TargetStreamer &getTargetStreamer() {
156 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
157 return static_cast<AArch64TargetStreamer &
>(TS);
160 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
162 bool parseSysAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
163 bool parseSyslAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
164 bool parseSyspAlias(StringRef Name, SMLoc NameLoc,
OperandVector &Operands);
165 void createSysAlias(uint16_t Encoding,
OperandVector &Operands, SMLoc S);
167 std::string &Suggestion);
169 MCRegister matchRegisterNameAlias(StringRef Name, RegKind Kind);
171 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
174 bool parseOptionalVGOperand(
OperandVector &Operands, StringRef &VecGroup);
177 bool invertCondCode);
178 bool parseImmExpr(int64_t &Out);
180 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool showMatchError(SMLoc Loc,
unsigned ErrCode, uint64_t ErrorInfo,
186 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
187 bool parseDataExpr(
const MCExpr *&Res)
override;
188 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
190 bool parseDirectiveArch(SMLoc L);
191 bool parseDirectiveArchExtension(SMLoc L);
192 bool parseDirectiveCPU(SMLoc L);
193 bool parseDirectiveInst(SMLoc L);
195 bool parseDirectiveTLSDescCall(SMLoc L);
197 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
198 bool parseDirectiveLtorg(SMLoc L);
200 bool parseDirectiveReq(StringRef Name, SMLoc L);
201 bool parseDirectiveUnreq(SMLoc L);
202 bool parseDirectiveCFINegateRAState();
203 bool parseDirectiveCFINegateRAStateWithPC();
204 bool parseDirectiveCFILLVMSetRAState();
205 bool parseDirectiveCFIBKeyFrame();
206 bool parseDirectiveCFIMTETaggedFrame();
208 bool parseDirectiveVariantPCS(SMLoc L);
210 bool parseDirectiveSEHAllocStack(SMLoc L);
211 bool parseDirectiveSEHPrologEnd(SMLoc L);
212 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
213 bool parseDirectiveSEHSaveFPLR(SMLoc L);
214 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
215 bool parseDirectiveSEHSaveReg(SMLoc L);
216 bool parseDirectiveSEHSaveRegX(SMLoc L);
217 bool parseDirectiveSEHSaveRegP(SMLoc L);
218 bool parseDirectiveSEHSaveRegPX(SMLoc L);
219 bool parseDirectiveSEHSaveLRPair(SMLoc L);
220 bool parseDirectiveSEHSaveFReg(SMLoc L);
221 bool parseDirectiveSEHSaveFRegX(SMLoc L);
222 bool parseDirectiveSEHSaveFRegP(SMLoc L);
223 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
224 bool parseDirectiveSEHSetFP(SMLoc L);
225 bool parseDirectiveSEHAddFP(SMLoc L);
226 bool parseDirectiveSEHNop(SMLoc L);
227 bool parseDirectiveSEHSaveNext(SMLoc L);
228 bool parseDirectiveSEHEpilogStart(SMLoc L);
229 bool parseDirectiveSEHEpilogEnd(SMLoc L);
230 bool parseDirectiveSEHTrapFrame(SMLoc L);
231 bool parseDirectiveSEHMachineFrame(SMLoc L);
232 bool parseDirectiveSEHContext(SMLoc L);
233 bool parseDirectiveSEHECContext(SMLoc L);
234 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
235 bool parseDirectiveSEHPACSignLR(SMLoc L);
236 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
237 bool parseDirectiveSEHAllocZ(SMLoc L);
238 bool parseDirectiveSEHSaveZReg(SMLoc L);
239 bool parseDirectiveSEHSavePReg(SMLoc L);
240 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
241 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
243 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
244 SmallVectorImpl<SMLoc> &Loc);
245 unsigned getNumRegsForRegKind(RegKind K);
246 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
249 bool MatchingInlineAsm)
override;
253#define GET_ASSEMBLER_HEADER
254#include "AArch64GenAsmMatcher.inc"
268 template <
bool IsSVEPrefetch = false>
274 template <
bool AddFPZeroAsLiteral>
282 template <
bool ParseShiftExtend,
283 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
286 template <
bool ParseShiftExtend,
bool ParseSuffix>
288 template <RegKind RK>
291 tryParseSVEPredicateOrPredicateAsCounterVector(
OperandVector &Operands);
292 template <RegKind VectorKind>
294 bool ExpectMatch =
false);
303 enum AArch64MatchResultTy {
304 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
305#define GET_OPERAND_DIAGNOSTIC_TYPES
306#include "AArch64GenAsmMatcher.inc"
309 bool IsWindowsArm64EC;
311 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
312 const MCInstrInfo &MII)
313 : MCTargetAsmParser(STI, MII) {
317 MCStreamer &S = getParser().getStreamer();
319 new AArch64TargetStreamer(S);
331 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
334 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
335 const MCParsedAsmOperand &Op2)
const override;
336 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
338 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
339 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
340 SMLoc &EndLoc)
override;
341 bool ParseDirective(AsmToken DirectiveID)
override;
342 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
343 unsigned Kind)
override;
375 SMLoc StartLoc, EndLoc;
384 struct ShiftExtendOp {
387 bool HasExplicitAmount;
397 RegConstraintEqualityTy EqualityTy;
413 ShiftExtendOp ShiftExtend;
418 unsigned ElementWidth;
422 struct MatrixTileListOp {
423 unsigned RegMask = 0;
426 struct VectorListOp {
430 unsigned NumElements;
431 unsigned ElementWidth;
432 RegKind RegisterKind;
435 struct VectorIndexOp {
443 struct ShiftedImmOp {
445 unsigned ShiftAmount;
474 uint32_t PStateField;
487 struct TIndexHintOp {
496 unsigned PStateField;
502 struct MatrixRegOp MatrixReg;
503 struct MatrixTileListOp MatrixTileList;
504 struct VectorListOp VectorList;
505 struct VectorIndexOp VectorIndex;
507 struct ShiftedImmOp ShiftedImm;
508 struct ImmRangeOp ImmRange;
510 struct FPImmOp FPImm;
512 struct SysRegOp SysReg;
513 struct SysCRImmOp SysCRImm;
515 struct TIndexHintOp TIndexHint;
516 struct ShiftExtendOp ShiftExtend;
525 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
527 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
529 StartLoc =
o.StartLoc;
539 ShiftedImm =
o.ShiftedImm;
542 ImmRange =
o.ImmRange;
556 case k_MatrixRegister:
557 MatrixReg =
o.MatrixReg;
559 case k_MatrixTileList:
560 MatrixTileList =
o.MatrixTileList;
563 VectorList =
o.VectorList;
566 VectorIndex =
o.VectorIndex;
572 SysCRImm =
o.SysCRImm;
578 TIndexHint =
o.TIndexHint;
581 ShiftExtend =
o.ShiftExtend;
590 SMLoc getStartLoc()
const override {
return StartLoc; }
592 SMLoc getEndLoc()
const override {
return EndLoc; }
595 assert(Kind == k_Token &&
"Invalid access!");
596 return StringRef(Tok.Data, Tok.Length);
599 bool isTokenSuffix()
const {
600 assert(Kind == k_Token &&
"Invalid access!");
604 const MCExpr *
getImm()
const {
605 assert(Kind == k_Immediate &&
"Invalid access!");
609 const MCExpr *getShiftedImmVal()
const {
610 assert(Kind == k_ShiftedImm &&
"Invalid access!");
611 return ShiftedImm.Val;
614 unsigned getShiftedImmShift()
const {
615 assert(Kind == k_ShiftedImm &&
"Invalid access!");
616 return ShiftedImm.ShiftAmount;
619 unsigned getFirstImmVal()
const {
620 assert(Kind == k_ImmRange &&
"Invalid access!");
621 return ImmRange.First;
624 unsigned getLastImmVal()
const {
625 assert(Kind == k_ImmRange &&
"Invalid access!");
626 return ImmRange.Last;
630 assert(Kind == k_CondCode &&
"Invalid access!");
635 assert (Kind == k_FPImm &&
"Invalid access!");
636 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
639 bool getFPImmIsExact()
const {
640 assert (Kind == k_FPImm &&
"Invalid access!");
641 return FPImm.IsExact;
644 unsigned getBarrier()
const {
645 assert(Kind == k_Barrier &&
"Invalid access!");
649 StringRef getBarrierName()
const {
650 assert(Kind == k_Barrier &&
"Invalid access!");
654 bool getBarriernXSModifier()
const {
655 assert(Kind == k_Barrier &&
"Invalid access!");
659 MCRegister
getReg()
const override {
660 assert(Kind == k_Register &&
"Invalid access!");
664 MCRegister getMatrixReg()
const {
665 assert(Kind == k_MatrixRegister &&
"Invalid access!");
666 return MatrixReg.Reg;
669 unsigned getMatrixElementWidth()
const {
670 assert(Kind == k_MatrixRegister &&
"Invalid access!");
671 return MatrixReg.ElementWidth;
674 MatrixKind getMatrixKind()
const {
675 assert(Kind == k_MatrixRegister &&
"Invalid access!");
676 return MatrixReg.Kind;
679 unsigned getMatrixTileListRegMask()
const {
680 assert(isMatrixTileList() &&
"Invalid access!");
681 return MatrixTileList.RegMask;
684 RegConstraintEqualityTy getRegEqualityTy()
const {
685 assert(Kind == k_Register &&
"Invalid access!");
686 return Reg.EqualityTy;
689 MCRegister getVectorListStart()
const {
690 assert(Kind == k_VectorList &&
"Invalid access!");
691 return VectorList.Reg;
694 unsigned getVectorListCount()
const {
695 assert(Kind == k_VectorList &&
"Invalid access!");
696 return VectorList.Count;
699 unsigned getVectorListStride()
const {
700 assert(Kind == k_VectorList &&
"Invalid access!");
701 return VectorList.Stride;
704 int getVectorIndex()
const {
705 assert(Kind == k_VectorIndex &&
"Invalid access!");
706 return VectorIndex.Val;
709 StringRef getSysReg()
const {
710 assert(Kind == k_SysReg &&
"Invalid access!");
711 return StringRef(SysReg.Data, SysReg.Length);
714 unsigned getSysCR()
const {
715 assert(Kind == k_SysCR &&
"Invalid access!");
719 unsigned getPrefetch()
const {
720 assert(Kind == k_Prefetch &&
"Invalid access!");
724 unsigned getTIndexHint()
const {
725 assert(Kind == k_TIndexHint &&
"Invalid access!");
726 return TIndexHint.Val;
729 StringRef getTIndexHintName()
const {
730 assert(Kind == k_TIndexHint &&
"Invalid access!");
731 return StringRef(TIndexHint.Data, TIndexHint.Length);
734 StringRef getSVCR()
const {
735 assert(Kind == k_SVCR &&
"Invalid access!");
736 return StringRef(SVCR.Data, SVCR.Length);
739 StringRef getPrefetchName()
const {
740 assert(Kind == k_Prefetch &&
"Invalid access!");
745 if (Kind == k_ShiftExtend)
746 return ShiftExtend.Type;
747 if (Kind == k_Register)
748 return Reg.ShiftExtend.Type;
752 unsigned getShiftExtendAmount()
const {
753 if (Kind == k_ShiftExtend)
754 return ShiftExtend.Amount;
755 if (Kind == k_Register)
756 return Reg.ShiftExtend.Amount;
760 bool hasShiftExtendAmount()
const {
761 if (Kind == k_ShiftExtend)
762 return ShiftExtend.HasExplicitAmount;
763 if (Kind == k_Register)
764 return Reg.ShiftExtend.HasExplicitAmount;
768 bool isImm()
const override {
return Kind == k_Immediate; }
769 bool isMem()
const override {
return false; }
771 bool isUImm6()
const {
778 return (Val >= 0 && Val < 64);
781 template <
int W
idth>
bool isSImm()
const {
782 return bool(isSImmScaled<Width, 1>());
785 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
786 return isImmScaled<Bits, Scale>(
true);
789 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
790 DiagnosticPredicate isUImmScaled()
const {
791 if (IsRange && isImmRange() &&
792 (getLastImmVal() != getFirstImmVal() +
Offset))
795 return isImmScaled<Bits, Scale, IsRange>(
false);
798 template <
int Bits,
int Scale,
bool IsRange = false>
799 DiagnosticPredicate isImmScaled(
bool Signed)
const {
800 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
801 (isImmRange() && !IsRange))
806 Val = getFirstImmVal();
814 int64_t MinVal, MaxVal;
816 int64_t Shift =
Bits - 1;
817 MinVal = (int64_t(1) << Shift) * -Scale;
818 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
821 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
824 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
830 DiagnosticPredicate isSVEPattern()
const {
837 if (Val >= 0 && Val < 32)
842 DiagnosticPredicate isSVEVecLenSpecifier()
const {
849 if (Val >= 0 && Val <= 1)
854 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
858 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
887 template <
int Scale>
bool isUImm12Offset()
const {
893 return isSymbolicUImm12Offset(
getImm());
896 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
899 template <
int N,
int M>
900 bool isImmInRange()
const {
907 return (Val >=
N && Val <= M);
910 bool isHinteUImm16()
const {
917 return Val >= 0 && Val <= 65535 &&
918 !(Val >= 12319 && Val <= 16383 && ((Val - 12319) % 32) == 0);
923 template <
typename T>
924 bool isLogicalImm()
const {
933 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
941 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
943 bool isImmRange()
const {
return Kind == k_ImmRange; }
948 template <
unsigned W
idth>
949 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
950 if (isShiftedImm() && Width == getShiftedImmShift())
952 return std::make_pair(
CE->getValue(), Width);
956 int64_t Val =
CE->getValue();
957 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
958 return std::make_pair(Val >> Width, Width);
960 return std::make_pair(Val, 0u);
966 bool isAddSubImm()
const {
967 if (!isShiftedImm() && !isImm())
973 if (isShiftedImm()) {
974 unsigned Shift = ShiftedImm.ShiftAmount;
975 Expr = ShiftedImm.Val;
976 if (Shift != 0 && Shift != 12)
985 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1001 if (
auto ShiftedVal = getShiftedVal<12>())
1002 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1009 bool isAddSubImmNeg()
const {
1010 if (!isShiftedImm() && !isImm())
1014 if (
auto ShiftedVal = getShiftedVal<12>())
1015 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1025 template <
typename T>
1026 DiagnosticPredicate isSVECpyImm()
const {
1030 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1031 std::is_same<int8_t, T>::value;
1032 if (
auto ShiftedImm = getShiftedVal<8>())
1033 if (!(IsByte && ShiftedImm->second) &&
1035 << ShiftedImm->second))
1044 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1048 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1049 std::is_same<int8_t, T>::value;
1050 if (
auto ShiftedImm = getShiftedVal<8>())
1051 if (!(IsByte && ShiftedImm->second) &&
1053 << ShiftedImm->second))
1059 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1060 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1067 bool isSIMDImmType10()
const {
1077 bool isBranchTarget()
const {
1086 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1087 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1097 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1107 bool isMovWSymbolG3()
const {
1111 bool isMovWSymbolG2()
const {
1118 bool isMovWSymbolG1()
const {
1126 bool isMovWSymbolG0()
const {
1134 template<
int RegW
idth,
int Shift>
1135 bool isMOVZMovAlias()
const {
1136 if (!isImm())
return false;
1140 uint64_t
Value =
CE->getValue();
1149 template<
int RegW
idth,
int Shift>
1150 bool isMOVNMovAlias()
const {
1151 if (!isImm())
return false;
1154 if (!CE)
return false;
1155 uint64_t
Value =
CE->getValue();
1160 bool isFPImm()
const {
1161 return Kind == k_FPImm &&
1165 bool isBarrier()
const {
1166 return Kind == k_Barrier && !getBarriernXSModifier();
1168 bool isBarriernXS()
const {
1169 return Kind == k_Barrier && getBarriernXSModifier();
1171 bool isSysReg()
const {
return Kind == k_SysReg; }
1173 bool isMRSSystemRegister()
const {
1174 if (!isSysReg())
return false;
1176 return SysReg.MRSReg != -1U;
1179 bool isMSRSystemRegister()
const {
1180 if (!isSysReg())
return false;
1181 return SysReg.MSRReg != -1U;
1184 bool isSystemPStateFieldWithImm0_1()
const {
1185 if (!isSysReg())
return false;
1186 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1189 bool isSystemPStateFieldWithImm0_15()
const {
1192 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1195 bool isSVCR()
const {
1198 return SVCR.PStateField != -1U;
1201 bool isReg()
const override {
1202 return Kind == k_Register;
1205 bool isVectorList()
const {
return Kind == k_VectorList; }
1207 bool isScalarReg()
const {
1208 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1211 bool isNeonVectorReg()
const {
1212 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1215 bool isNeonVectorRegLo()
const {
1216 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1217 (getAArch64MCRegisterClass(AArch64::FPR128_loRegClassID)
1218 .contains(
Reg.Reg) ||
1219 getAArch64MCRegisterClass(AArch64::FPR64_loRegClassID)
1220 .contains(
Reg.Reg));
1223 bool isNeonVectorReg0to7()
const {
1224 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1225 (getAArch64MCRegisterClass(AArch64::FPR128_0to7RegClassID)
1226 .contains(
Reg.Reg));
1229 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1230 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1232 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1235 case AArch64::PPRRegClassID:
1236 case AArch64::PPR_3bRegClassID:
1237 case AArch64::PPR_p8to15RegClassID:
1238 case AArch64::PNRRegClassID:
1239 case AArch64::PNR_p8to15RegClassID:
1240 case AArch64::PPRorPNRRegClassID:
1241 RK = RegKind::SVEPredicateAsCounter;
1247 return (Kind == k_Register &&
Reg.Kind == RK) &&
1248 getAArch64MCRegisterClass(Class).contains(
getReg());
1251 template <
unsigned Class>
bool isSVEVectorReg()
const {
1254 case AArch64::ZPRRegClassID:
1255 case AArch64::ZPR_3bRegClassID:
1256 case AArch64::ZPR_4bRegClassID:
1257 case AArch64::ZPRMul2_LoRegClassID:
1258 case AArch64::ZPRMul2_HiRegClassID:
1259 case AArch64::ZPR_KRegClassID:
1260 RK = RegKind::SVEDataVector;
1262 case AArch64::PPRRegClassID:
1263 case AArch64::PPR_3bRegClassID:
1264 case AArch64::PPR_p8to15RegClassID:
1265 case AArch64::PNRRegClassID:
1266 case AArch64::PNR_p8to15RegClassID:
1267 case AArch64::PPRorPNRRegClassID:
1268 RK = RegKind::SVEPredicateVector;
1274 return (Kind == k_Register &&
Reg.Kind == RK) &&
1275 getAArch64MCRegisterClass(Class).contains(
getReg());
1278 template <
unsigned Class>
bool isFPRasZPR()
const {
1279 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1280 getAArch64MCRegisterClass(Class).contains(
getReg());
1283 template <
int ElementW
idth,
unsigned Class>
1284 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1285 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1288 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1294 template <
int ElementW
idth,
unsigned Class>
1295 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1296 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1297 Reg.Kind != RegKind::SVEPredicateVector))
1300 if ((isSVEPredicateAsCounterReg<Class>() ||
1301 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1302 Reg.ElementWidth == ElementWidth)
1308 template <
int ElementW
idth,
unsigned Class>
1309 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1310 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1313 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1319 template <
int ElementW
idth,
unsigned Class>
1320 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1321 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1324 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1330 template <
int ElementWidth,
unsigned Class,
1332 bool ShiftWidthAlwaysSame>
1333 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1334 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1335 if (!VectorMatch.isMatch())
1341 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1344 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1347 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1353 bool isGPR32as64()
const {
1354 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1355 getAArch64MCRegisterClass(AArch64::GPR64RegClassID)
1359 bool isGPR64as32()
const {
1360 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1361 getAArch64MCRegisterClass(AArch64::GPR32RegClassID)
1365 bool isGPR64x8()
const {
1366 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1367 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
1371 bool isWSeqPair()
const {
1372 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1373 getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID)
1377 bool isXSeqPair()
const {
1378 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1379 getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID)
1383 bool isSyspXzrPair()
const {
1387 template<
int64_t Angle,
int64_t Remainder>
1388 DiagnosticPredicate isComplexRotation()
const {
1395 uint64_t
Value =
CE->getValue();
1397 if (
Value % Angle == Remainder &&
Value <= 270)
1402 template <
unsigned RegClassID>
bool isGPR64()
const {
1403 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1404 getAArch64MCRegisterClass(RegClassID).contains(
getReg());
1407 template <
unsigned RegClassID,
int ExtW
idth>
1408 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1409 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1413 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1420 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1421 bool isImplicitlyTypedVectorList()
const {
1422 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1423 VectorList.NumElements == 0 &&
1424 VectorList.RegisterKind == VectorKind &&
1425 (!IsConsecutive || (VectorList.Stride == 1));
1428 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1429 unsigned ElementWidth,
unsigned Stride = 1>
1430 bool isTypedVectorList()
const {
1431 if (Kind != k_VectorList)
1433 if (VectorList.Count != NumRegs)
1435 if (VectorList.RegisterKind != VectorKind)
1437 if (VectorList.ElementWidth != ElementWidth)
1439 if (VectorList.Stride != Stride)
1441 return VectorList.NumElements == NumElements;
1444 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1445 unsigned ElementWidth,
unsigned FirstReg,
unsigned LastReg,
1447 DiagnosticPredicate isTypedVectorListInRange()
const {
1449 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1452 if (VectorList.Reg < FirstReg || VectorList.Reg > LastReg ||
1453 (VectorList.Reg - FirstReg) % Multiple != 0)
1458 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1459 unsigned ElementWidth>
1460 DiagnosticPredicate isTypedVectorListStrided()
const {
1461 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1462 ElementWidth, Stride>();
1465 if ((VectorList.Reg < (AArch64::Z0 + Stride)) ||
1466 ((VectorList.Reg >= AArch64::Z16) &&
1467 (VectorList.Reg < (AArch64::Z16 + Stride))))
1472 template <
int Min,
int Max>
1473 DiagnosticPredicate isVectorIndex()
const {
1474 if (Kind != k_VectorIndex)
1476 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1481 bool isToken()
const override {
return Kind == k_Token; }
1483 bool isTokenEqual(StringRef Str)
const {
1484 return Kind == k_Token &&
getToken() == Str;
1486 bool isSysCR()
const {
return Kind == k_SysCR; }
1487 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1488 bool isTIndexHint()
const {
return Kind == k_TIndexHint; }
1489 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1490 bool isShifter()
const {
1491 if (!isShiftExtend())
1500 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1501 if (Kind != k_FPImm)
1504 if (getFPImmIsExact()) {
1506 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1508 StringRef DescRepr = AArch64ExactFPImm::getExactFPImmStr(
Desc->Repr);
1511 APFloat RealVal(APFloat::IEEEdouble());
1513 RealVal.convertFromString(DescRepr, APFloat::rmTowardZero);
1514 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1517 if (
getFPImm().bitwiseIsEqual(RealVal))
1524 template <
unsigned ImmA,
unsigned ImmB>
1525 DiagnosticPredicate isExactFPImm()
const {
1527 if ((Res = isExactFPImm<ImmA>()))
1529 if ((Res = isExactFPImm<ImmB>()))
1534 bool isExtend()
const {
1535 if (!isShiftExtend())
1544 getShiftExtendAmount() <= 4;
1547 bool isExtend64()
const {
1557 bool isExtendLSL64()
const {
1563 getShiftExtendAmount() <= 4;
1566 bool isLSLImm3Shift()
const {
1567 if (!isShiftExtend())
1573 template<
int W
idth>
bool isMemXExtend()
const {
1578 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1579 getShiftExtendAmount() == 0);
1582 template<
int W
idth>
bool isMemWExtend()
const {
1587 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1588 getShiftExtendAmount() == 0);
1591 template <
unsigned w
idth>
1592 bool isArithmeticShifter()
const {
1602 template <
unsigned w
idth>
1603 bool isLogicalShifter()
const {
1611 getShiftExtendAmount() < width;
1614 bool isMovImm32Shifter()
const {
1622 uint64_t Val = getShiftExtendAmount();
1623 return (Val == 0 || Val == 16);
1626 bool isMovImm64Shifter()
const {
1634 uint64_t Val = getShiftExtendAmount();
1635 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1638 bool isLogicalVecShifter()
const {
1643 unsigned Shift = getShiftExtendAmount();
1645 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1648 bool isLogicalVecHalfWordShifter()
const {
1649 if (!isLogicalVecShifter())
1653 unsigned Shift = getShiftExtendAmount();
1655 (Shift == 0 || Shift == 8);
1658 bool isMoveVecShifter()
const {
1659 if (!isShiftExtend())
1663 unsigned Shift = getShiftExtendAmount();
1665 (Shift == 8 || Shift == 16);
1674 bool isSImm9OffsetFB()
const {
1675 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1678 bool isAdrpLabel()
const {
1685 int64_t Val =
CE->getValue();
1686 int64_t Min = - (4096 * (1LL << (21 - 1)));
1687 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1688 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1694 bool isAdrLabel()
const {
1701 int64_t Val =
CE->getValue();
1702 int64_t Min = - (1LL << (21 - 1));
1703 int64_t
Max = ((1LL << (21 - 1)) - 1);
1704 return Val >= Min && Val <=
Max;
1710 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1711 DiagnosticPredicate isMatrixRegOperand()
const {
1714 if (getMatrixKind() != Kind ||
1715 !getAArch64MCRegisterClass(RegClass).
contains(getMatrixReg()) ||
1716 EltSize != getMatrixElementWidth())
1721 bool isPAuthPCRelLabel16Operand()
const {
1733 return (Val <= 0) && (Val > -(1 << 18));
1736 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1746 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1747 assert(
N == 1 &&
"Invalid number of operands!");
1751 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1752 assert(
N == 1 &&
"Invalid number of operands!");
1756 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1757 assert(
N == 1 &&
"Invalid number of operands!");
1759 getAArch64MCRegisterClass(AArch64::GPR64RegClassID).
contains(
getReg()));
1761 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1768 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1769 assert(
N == 1 &&
"Invalid number of operands!");
1771 getAArch64MCRegisterClass(AArch64::GPR32RegClassID).
contains(
getReg()));
1773 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1780 template <
int W
idth>
1781 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1784 case 8:
Base = AArch64::B0;
break;
1785 case 16:
Base = AArch64::H0;
break;
1786 case 32:
Base = AArch64::S0;
break;
1787 case 64:
Base = AArch64::D0;
break;
1788 case 128:
Base = AArch64::Q0;
break;
1795 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1796 assert(
N == 1 &&
"Invalid number of operands!");
1799 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1800 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1804 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1805 assert(
N == 1 &&
"Invalid number of operands!");
1810 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1811 assert(
N == 1 &&
"Invalid number of operands!");
1812 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1817 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1818 assert(
N == 1 &&
"Invalid number of operands!");
1819 assert(getAArch64MCRegisterClass(AArch64::FPR128RegClassID)
1824 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1825 assert(
N == 1 &&
"Invalid number of operands!");
1829 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1830 assert(
N == 1 &&
"Invalid number of operands!");
1834 enum VecListIndexType {
1835 VecListIdx_DReg = 0,
1836 VecListIdx_QReg = 1,
1837 VecListIdx_ZReg = 2,
1838 VecListIdx_PReg = 3,
1841 template <VecListIndexType RegTy,
unsigned NumRegs,
1842 bool IsConsecutive =
false>
1843 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1844 assert(
N == 1 &&
"Invalid number of operands!");
1845 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1846 "Expected consecutive registers");
1847 static const unsigned FirstRegs[][5] = {
1849 AArch64::D0, AArch64::D0_D1,
1850 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1852 AArch64::Q0, AArch64::Q0_Q1,
1853 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1855 AArch64::Z0, AArch64::Z0_Z1,
1856 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1858 AArch64::P0, AArch64::P0_P1 }
1861 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1862 " NumRegs must be <= 4 for ZRegs");
1864 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1865 " NumRegs must be <= 2 for PRegs");
1867 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1869 FirstRegs[(
unsigned)RegTy][0]));
1872 template <
unsigned NumRegs>
1873 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1874 assert(
N == 1 &&
"Invalid number of operands!");
1875 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1879 if (getVectorListStart() < AArch64::Z16) {
1880 assert((getVectorListStart() < AArch64::Z8) &&
1881 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1883 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1885 assert((getVectorListStart() < AArch64::Z24) &&
1886 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1888 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1892 if (getVectorListStart() < AArch64::Z16) {
1893 assert((getVectorListStart() < AArch64::Z4) &&
1894 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1896 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1898 assert((getVectorListStart() < AArch64::Z20) &&
1899 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1901 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1909 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1910 assert(
N == 1 &&
"Invalid number of operands!");
1911 unsigned RegMask = getMatrixTileListRegMask();
1912 assert(RegMask <= 0xFF &&
"Invalid mask!");
1916 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1917 assert(
N == 1 &&
"Invalid number of operands!");
1921 template <
unsigned ImmIs0,
unsigned ImmIs1>
1922 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1923 assert(
N == 1 &&
"Invalid number of operands!");
1924 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1928 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1929 assert(
N == 1 &&
"Invalid number of operands!");
1936 template <
int Shift>
1937 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1938 assert(
N == 2 &&
"Invalid number of operands!");
1939 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1942 }
else if (isShiftedImm()) {
1943 addExpr(Inst, getShiftedImmVal());
1951 template <
int Shift>
1952 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1953 assert(
N == 2 &&
"Invalid number of operands!");
1954 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1961 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1962 assert(
N == 1 &&
"Invalid number of operands!");
1966 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1967 assert(
N == 1 &&
"Invalid number of operands!");
1975 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
1976 addImmOperands(Inst,
N);
1980 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
1981 assert(
N == 1 &&
"Invalid number of operands!");
1991 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
1992 assert(
N == 1 &&
"Invalid number of operands!");
1997 template <
int Scale>
1998 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
1999 assert(
N == 1 &&
"Invalid number of operands!");
2004 template <
int Scale>
2005 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2006 assert(
N == 1 &&
"Invalid number of operands!");
2010 template <
typename T>
2011 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2012 assert(
N == 1 &&
"Invalid number of operands!");
2014 std::make_unsigned_t<T> Val = MCE->
getValue();
2019 template <
typename T>
2020 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2021 assert(
N == 1 &&
"Invalid number of operands!");
2023 std::make_unsigned_t<T> Val = ~MCE->getValue();
2028 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2029 assert(
N == 1 &&
"Invalid number of operands!");
2035 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2039 assert(
N == 1 &&
"Invalid number of operands!");
2045 assert(MCE &&
"Invalid constant immediate operand!");
2049 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2053 assert(
N == 1 &&
"Invalid number of operands!");
2062 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2066 assert(
N == 1 &&
"Invalid number of operands!");
2072 assert(MCE &&
"Invalid constant immediate operand!");
2076 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2080 assert(
N == 1 &&
"Invalid number of operands!");
2086 assert(MCE &&
"Invalid constant immediate operand!");
2090 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2094 assert(
N == 1 &&
"Invalid number of operands!");
2100 assert(MCE &&
"Invalid constant immediate operand!");
2104 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2105 assert(
N == 1 &&
"Invalid number of operands!");
2110 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2111 assert(
N == 1 &&
"Invalid number of operands!");
2115 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2116 assert(
N == 1 &&
"Invalid number of operands!");
2120 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2121 assert(
N == 1 &&
"Invalid number of operands!");
2126 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2127 assert(
N == 1 &&
"Invalid number of operands!");
2132 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2133 assert(
N == 1 &&
"Invalid number of operands!");
2138 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2139 assert(
N == 1 &&
"Invalid number of operands!");
2144 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2145 assert(
N == 1 &&
"Invalid number of operands!");
2150 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2151 assert(
N == 1 &&
"Invalid number of operands!");
2155 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2156 assert(
N == 1 &&
"Invalid number of operands!");
2160 void addTIndexHintOperands(MCInst &Inst,
unsigned N)
const {
2161 assert(
N == 1 &&
"Invalid number of operands!");
2165 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2166 assert(
N == 1 &&
"Invalid number of operands!");
2172 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2173 assert(
N == 1 &&
"Invalid number of operands!");
2174 unsigned Imm = getShiftExtendAmount();
2178 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2179 assert(
N == 1 &&
"Invalid number of operands!");
2184 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2187 if (
Reg != AArch64::XZR)
2193 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2194 assert(
N == 1 &&
"Invalid number of operands!");
2201 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2202 assert(
N == 1 &&
"Invalid number of operands!");
2209 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2210 assert(
N == 2 &&
"Invalid number of operands!");
2221 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2222 assert(
N == 2 &&
"Invalid number of operands!");
2230 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2231 assert(
N == 1 &&
"Invalid number of operands!");
2235 uint64_t
Value =
CE->getValue();
2243 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2244 assert(
N == 1 &&
"Invalid number of operands!");
2247 uint64_t
Value =
CE->getValue();
2251 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2252 assert(
N == 1 &&
"Invalid number of operands!");
2257 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2258 assert(
N == 1 &&
"Invalid number of operands!");
2263 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2265 static std::unique_ptr<AArch64Operand>
2266 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2267 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2268 Op->Tok.Data = Str.data();
2269 Op->Tok.Length = Str.size();
2270 Op->Tok.IsSuffix = IsSuffix;
2276 static std::unique_ptr<AArch64Operand>
2277 CreateReg(MCRegister
Reg, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2278 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2280 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2281 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2283 Op->Reg.Kind = Kind;
2284 Op->Reg.ElementWidth = 0;
2285 Op->Reg.EqualityTy = EqTy;
2286 Op->Reg.ShiftExtend.Type = ExtTy;
2287 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2288 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2294 static std::unique_ptr<AArch64Operand> CreateVectorReg(
2295 MCRegister
Reg, RegKind Kind,
unsigned ElementWidth, SMLoc S, SMLoc
E,
2297 unsigned ShiftAmount = 0,
unsigned HasExplicitAmount =
false) {
2298 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2299 Kind == RegKind::SVEPredicateVector ||
2300 Kind == RegKind::SVEPredicateAsCounter) &&
2301 "Invalid vector kind");
2302 auto Op = CreateReg(
Reg, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2304 Op->Reg.ElementWidth = ElementWidth;
2308 static std::unique_ptr<AArch64Operand>
2309 CreateVectorList(MCRegister
Reg,
unsigned Count,
unsigned Stride,
2310 unsigned NumElements,
unsigned ElementWidth,
2311 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2312 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2313 Op->VectorList.Reg =
Reg;
2315 Op->VectorList.Stride = Stride;
2316 Op->VectorList.NumElements = NumElements;
2317 Op->VectorList.ElementWidth = ElementWidth;
2318 Op->VectorList.RegisterKind = RegisterKind;
2324 static std::unique_ptr<AArch64Operand>
2325 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2326 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2327 Op->VectorIndex.Val = Idx;
2333 static std::unique_ptr<AArch64Operand>
2334 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2335 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2336 Op->MatrixTileList.RegMask = RegMask;
2342 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2343 const unsigned ElementWidth) {
2344 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2346 {{0, AArch64::ZAB0},
2347 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2348 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2349 {{8, AArch64::ZAB0},
2350 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2351 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2352 {{16, AArch64::ZAH0},
2353 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2354 {{16, AArch64::ZAH1},
2355 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2356 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2357 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2358 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2359 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2362 if (ElementWidth == 64)
2365 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2366 assert(!Regs.empty() &&
"Invalid tile or element width!");
2371 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2372 SMLoc
E, MCContext &Ctx) {
2373 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2380 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2381 unsigned ShiftAmount,
2384 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2385 Op->ShiftedImm .Val = Val;
2386 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2392 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2393 unsigned Last, SMLoc S,
2396 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2398 Op->ImmRange.Last =
Last;
2403 static std::unique_ptr<AArch64Operand>
2405 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2406 Op->CondCode.Code =
Code;
2412 static std::unique_ptr<AArch64Operand>
2413 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2414 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2416 Op->FPImm.IsExact = IsExact;
2422 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2426 bool HasnXSModifier) {
2427 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2428 Op->Barrier.Val = Val;
2429 Op->Barrier.Data = Str.data();
2430 Op->Barrier.Length = Str.size();
2431 Op->Barrier.HasnXSModifier = HasnXSModifier;
2437 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2440 uint32_t PStateField,
2442 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2443 Op->SysReg.Data = Str.data();
2444 Op->SysReg.Length = Str.size();
2445 Op->SysReg.MRSReg = MRSReg;
2446 Op->SysReg.MSRReg = MSRReg;
2447 Op->SysReg.PStateField = PStateField;
2453 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2454 SMLoc
E, MCContext &Ctx) {
2455 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2456 Op->SysCRImm.Val = Val;
2462 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2466 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2467 Op->Prefetch.Val = Val;
2468 Op->Barrier.Data = Str.data();
2469 Op->Barrier.Length = Str.size();
2475 static std::unique_ptr<AArch64Operand>
2476 CreateTIndexHint(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2477 auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
2478 Op->TIndexHint.Val = Val;
2479 Op->TIndexHint.Data = Str.data();
2480 Op->TIndexHint.Length = Str.size();
2486 static std::unique_ptr<AArch64Operand>
2487 CreateMatrixRegister(MCRegister
Reg,
unsigned ElementWidth, MatrixKind Kind,
2488 SMLoc S, SMLoc
E, MCContext &Ctx) {
2489 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2490 Op->MatrixReg.Reg =
Reg;
2491 Op->MatrixReg.ElementWidth = ElementWidth;
2492 Op->MatrixReg.Kind = Kind;
2498 static std::unique_ptr<AArch64Operand>
2499 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2500 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2501 Op->SVCR.PStateField = PStateField;
2502 Op->SVCR.Data = Str.data();
2503 Op->SVCR.Length = Str.size();
2509 static std::unique_ptr<AArch64Operand>
2511 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2512 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2513 Op->ShiftExtend.Type = ShOp;
2514 Op->ShiftExtend.Amount = Val;
2515 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2527 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2528 if (!getFPImmIsExact())
2533 StringRef
Name = getBarrierName();
2535 OS <<
"<barrier " <<
Name <<
">";
2537 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2543 case k_ShiftedImm: {
2544 unsigned Shift = getShiftedImmShift();
2545 OS <<
"<shiftedimm ";
2552 OS << getFirstImmVal();
2553 OS <<
":" << getLastImmVal() <<
">";
2559 case k_VectorList: {
2560 OS <<
"<vectorlist ";
2561 MCRegister
Reg = getVectorListStart();
2562 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2563 OS <<
Reg.
id() + i * getVectorListStride() <<
" ";
2568 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2571 OS <<
"<sysreg: " << getSysReg() <<
'>';
2577 OS <<
"c" << getSysCR();
2580 StringRef
Name = getPrefetchName();
2582 OS <<
"<prfop " <<
Name <<
">";
2584 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2588 OS << getTIndexHintName();
2590 case k_MatrixRegister:
2591 OS <<
"<matrix " << getMatrixReg().id() <<
">";
2593 case k_MatrixTileList: {
2594 OS <<
"<matrixlist ";
2595 unsigned RegMask = getMatrixTileListRegMask();
2596 unsigned MaxBits = 8;
2597 for (
unsigned I = MaxBits;
I > 0; --
I)
2598 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2607 OS <<
"<register " <<
getReg().
id() <<
">";
2608 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2613 << getShiftExtendAmount();
2614 if (!hasShiftExtendAmount())
2630 .
Case(
"v0", AArch64::Q0)
2631 .
Case(
"v1", AArch64::Q1)
2632 .
Case(
"v2", AArch64::Q2)
2633 .
Case(
"v3", AArch64::Q3)
2634 .
Case(
"v4", AArch64::Q4)
2635 .
Case(
"v5", AArch64::Q5)
2636 .
Case(
"v6", AArch64::Q6)
2637 .
Case(
"v7", AArch64::Q7)
2638 .
Case(
"v8", AArch64::Q8)
2639 .
Case(
"v9", AArch64::Q9)
2640 .
Case(
"v10", AArch64::Q10)
2641 .
Case(
"v11", AArch64::Q11)
2642 .
Case(
"v12", AArch64::Q12)
2643 .
Case(
"v13", AArch64::Q13)
2644 .
Case(
"v14", AArch64::Q14)
2645 .
Case(
"v15", AArch64::Q15)
2646 .
Case(
"v16", AArch64::Q16)
2647 .
Case(
"v17", AArch64::Q17)
2648 .
Case(
"v18", AArch64::Q18)
2649 .
Case(
"v19", AArch64::Q19)
2650 .
Case(
"v20", AArch64::Q20)
2651 .
Case(
"v21", AArch64::Q21)
2652 .
Case(
"v22", AArch64::Q22)
2653 .
Case(
"v23", AArch64::Q23)
2654 .
Case(
"v24", AArch64::Q24)
2655 .
Case(
"v25", AArch64::Q25)
2656 .
Case(
"v26", AArch64::Q26)
2657 .
Case(
"v27", AArch64::Q27)
2658 .
Case(
"v28", AArch64::Q28)
2659 .
Case(
"v29", AArch64::Q29)
2660 .
Case(
"v30", AArch64::Q30)
2661 .
Case(
"v31", AArch64::Q31)
2670 RegKind VectorKind) {
2671 std::pair<int, int> Res = {-1, -1};
2673 switch (VectorKind) {
2674 case RegKind::NeonVector:
2677 .Case(
".1d", {1, 64})
2678 .Case(
".1q", {1, 128})
2680 .Case(
".2h", {2, 16})
2681 .Case(
".2b", {2, 8})
2682 .Case(
".2s", {2, 32})
2683 .Case(
".2d", {2, 64})
2686 .Case(
".4b", {4, 8})
2687 .Case(
".4h", {4, 16})
2688 .Case(
".4s", {4, 32})
2689 .Case(
".8b", {8, 8})
2690 .Case(
".8h", {8, 16})
2691 .Case(
".16b", {16, 8})
2696 .Case(
".h", {0, 16})
2697 .Case(
".s", {0, 32})
2698 .Case(
".d", {0, 64})
2701 case RegKind::SVEPredicateAsCounter:
2702 case RegKind::SVEPredicateVector:
2703 case RegKind::SVEDataVector:
2704 case RegKind::Matrix:
2708 .Case(
".h", {0, 16})
2709 .Case(
".s", {0, 32})
2710 .Case(
".d", {0, 64})
2711 .Case(
".q", {0, 128})
2718 if (Res == std::make_pair(-1, -1))
2719 return std::nullopt;
2721 return std::optional<std::pair<int, int>>(Res);
2730 .
Case(
"z0", AArch64::Z0)
2731 .
Case(
"z1", AArch64::Z1)
2732 .
Case(
"z2", AArch64::Z2)
2733 .
Case(
"z3", AArch64::Z3)
2734 .
Case(
"z4", AArch64::Z4)
2735 .
Case(
"z5", AArch64::Z5)
2736 .
Case(
"z6", AArch64::Z6)
2737 .
Case(
"z7", AArch64::Z7)
2738 .
Case(
"z8", AArch64::Z8)
2739 .
Case(
"z9", AArch64::Z9)
2740 .
Case(
"z10", AArch64::Z10)
2741 .
Case(
"z11", AArch64::Z11)
2742 .
Case(
"z12", AArch64::Z12)
2743 .
Case(
"z13", AArch64::Z13)
2744 .
Case(
"z14", AArch64::Z14)
2745 .
Case(
"z15", AArch64::Z15)
2746 .
Case(
"z16", AArch64::Z16)
2747 .
Case(
"z17", AArch64::Z17)
2748 .
Case(
"z18", AArch64::Z18)
2749 .
Case(
"z19", AArch64::Z19)
2750 .
Case(
"z20", AArch64::Z20)
2751 .
Case(
"z21", AArch64::Z21)
2752 .
Case(
"z22", AArch64::Z22)
2753 .
Case(
"z23", AArch64::Z23)
2754 .
Case(
"z24", AArch64::Z24)
2755 .
Case(
"z25", AArch64::Z25)
2756 .
Case(
"z26", AArch64::Z26)
2757 .
Case(
"z27", AArch64::Z27)
2758 .
Case(
"z28", AArch64::Z28)
2759 .
Case(
"z29", AArch64::Z29)
2760 .
Case(
"z30", AArch64::Z30)
2761 .
Case(
"z31", AArch64::Z31)
2767 .
Case(
"p0", AArch64::P0)
2768 .
Case(
"p1", AArch64::P1)
2769 .
Case(
"p2", AArch64::P2)
2770 .
Case(
"p3", AArch64::P3)
2771 .
Case(
"p4", AArch64::P4)
2772 .
Case(
"p5", AArch64::P5)
2773 .
Case(
"p6", AArch64::P6)
2774 .
Case(
"p7", AArch64::P7)
2775 .
Case(
"p8", AArch64::P8)
2776 .
Case(
"p9", AArch64::P9)
2777 .
Case(
"p10", AArch64::P10)
2778 .
Case(
"p11", AArch64::P11)
2779 .
Case(
"p12", AArch64::P12)
2780 .
Case(
"p13", AArch64::P13)
2781 .
Case(
"p14", AArch64::P14)
2782 .
Case(
"p15", AArch64::P15)
2788 .
Case(
"pn0", AArch64::PN0)
2789 .
Case(
"pn1", AArch64::PN1)
2790 .
Case(
"pn2", AArch64::PN2)
2791 .
Case(
"pn3", AArch64::PN3)
2792 .
Case(
"pn4", AArch64::PN4)
2793 .
Case(
"pn5", AArch64::PN5)
2794 .
Case(
"pn6", AArch64::PN6)
2795 .
Case(
"pn7", AArch64::PN7)
2796 .
Case(
"pn8", AArch64::PN8)
2797 .
Case(
"pn9", AArch64::PN9)
2798 .
Case(
"pn10", AArch64::PN10)
2799 .
Case(
"pn11", AArch64::PN11)
2800 .
Case(
"pn12", AArch64::PN12)
2801 .
Case(
"pn13", AArch64::PN13)
2802 .
Case(
"pn14", AArch64::PN14)
2803 .
Case(
"pn15", AArch64::PN15)
2809 .
Case(
"za0.d", AArch64::ZAD0)
2810 .
Case(
"za1.d", AArch64::ZAD1)
2811 .
Case(
"za2.d", AArch64::ZAD2)
2812 .
Case(
"za3.d", AArch64::ZAD3)
2813 .
Case(
"za4.d", AArch64::ZAD4)
2814 .
Case(
"za5.d", AArch64::ZAD5)
2815 .
Case(
"za6.d", AArch64::ZAD6)
2816 .
Case(
"za7.d", AArch64::ZAD7)
2817 .
Case(
"za0.s", AArch64::ZAS0)
2818 .
Case(
"za1.s", AArch64::ZAS1)
2819 .
Case(
"za2.s", AArch64::ZAS2)
2820 .
Case(
"za3.s", AArch64::ZAS3)
2821 .
Case(
"za0.h", AArch64::ZAH0)
2822 .
Case(
"za1.h", AArch64::ZAH1)
2823 .
Case(
"za0.b", AArch64::ZAB0)
2829 .
Case(
"za", AArch64::ZA)
2830 .
Case(
"za0.q", AArch64::ZAQ0)
2831 .
Case(
"za1.q", AArch64::ZAQ1)
2832 .
Case(
"za2.q", AArch64::ZAQ2)
2833 .
Case(
"za3.q", AArch64::ZAQ3)
2834 .
Case(
"za4.q", AArch64::ZAQ4)
2835 .
Case(
"za5.q", AArch64::ZAQ5)
2836 .
Case(
"za6.q", AArch64::ZAQ6)
2837 .
Case(
"za7.q", AArch64::ZAQ7)
2838 .
Case(
"za8.q", AArch64::ZAQ8)
2839 .
Case(
"za9.q", AArch64::ZAQ9)
2840 .
Case(
"za10.q", AArch64::ZAQ10)
2841 .
Case(
"za11.q", AArch64::ZAQ11)
2842 .
Case(
"za12.q", AArch64::ZAQ12)
2843 .
Case(
"za13.q", AArch64::ZAQ13)
2844 .
Case(
"za14.q", AArch64::ZAQ14)
2845 .
Case(
"za15.q", AArch64::ZAQ15)
2846 .
Case(
"za0.d", AArch64::ZAD0)
2847 .
Case(
"za1.d", AArch64::ZAD1)
2848 .
Case(
"za2.d", AArch64::ZAD2)
2849 .
Case(
"za3.d", AArch64::ZAD3)
2850 .
Case(
"za4.d", AArch64::ZAD4)
2851 .
Case(
"za5.d", AArch64::ZAD5)
2852 .
Case(
"za6.d", AArch64::ZAD6)
2853 .
Case(
"za7.d", AArch64::ZAD7)
2854 .
Case(
"za0.s", AArch64::ZAS0)
2855 .
Case(
"za1.s", AArch64::ZAS1)
2856 .
Case(
"za2.s", AArch64::ZAS2)
2857 .
Case(
"za3.s", AArch64::ZAS3)
2858 .
Case(
"za0.h", AArch64::ZAH0)
2859 .
Case(
"za1.h", AArch64::ZAH1)
2860 .
Case(
"za0.b", AArch64::ZAB0)
2861 .
Case(
"za0h.q", AArch64::ZAQ0)
2862 .
Case(
"za1h.q", AArch64::ZAQ1)
2863 .
Case(
"za2h.q", AArch64::ZAQ2)
2864 .
Case(
"za3h.q", AArch64::ZAQ3)
2865 .
Case(
"za4h.q", AArch64::ZAQ4)
2866 .
Case(
"za5h.q", AArch64::ZAQ5)
2867 .
Case(
"za6h.q", AArch64::ZAQ6)
2868 .
Case(
"za7h.q", AArch64::ZAQ7)
2869 .
Case(
"za8h.q", AArch64::ZAQ8)
2870 .
Case(
"za9h.q", AArch64::ZAQ9)
2871 .
Case(
"za10h.q", AArch64::ZAQ10)
2872 .
Case(
"za11h.q", AArch64::ZAQ11)
2873 .
Case(
"za12h.q", AArch64::ZAQ12)
2874 .
Case(
"za13h.q", AArch64::ZAQ13)
2875 .
Case(
"za14h.q", AArch64::ZAQ14)
2876 .
Case(
"za15h.q", AArch64::ZAQ15)
2877 .
Case(
"za0h.d", AArch64::ZAD0)
2878 .
Case(
"za1h.d", AArch64::ZAD1)
2879 .
Case(
"za2h.d", AArch64::ZAD2)
2880 .
Case(
"za3h.d", AArch64::ZAD3)
2881 .
Case(
"za4h.d", AArch64::ZAD4)
2882 .
Case(
"za5h.d", AArch64::ZAD5)
2883 .
Case(
"za6h.d", AArch64::ZAD6)
2884 .
Case(
"za7h.d", AArch64::ZAD7)
2885 .
Case(
"za0h.s", AArch64::ZAS0)
2886 .
Case(
"za1h.s", AArch64::ZAS1)
2887 .
Case(
"za2h.s", AArch64::ZAS2)
2888 .
Case(
"za3h.s", AArch64::ZAS3)
2889 .
Case(
"za0h.h", AArch64::ZAH0)
2890 .
Case(
"za1h.h", AArch64::ZAH1)
2891 .
Case(
"za0h.b", AArch64::ZAB0)
2892 .
Case(
"za0v.q", AArch64::ZAQ0)
2893 .
Case(
"za1v.q", AArch64::ZAQ1)
2894 .
Case(
"za2v.q", AArch64::ZAQ2)
2895 .
Case(
"za3v.q", AArch64::ZAQ3)
2896 .
Case(
"za4v.q", AArch64::ZAQ4)
2897 .
Case(
"za5v.q", AArch64::ZAQ5)
2898 .
Case(
"za6v.q", AArch64::ZAQ6)
2899 .
Case(
"za7v.q", AArch64::ZAQ7)
2900 .
Case(
"za8v.q", AArch64::ZAQ8)
2901 .
Case(
"za9v.q", AArch64::ZAQ9)
2902 .
Case(
"za10v.q", AArch64::ZAQ10)
2903 .
Case(
"za11v.q", AArch64::ZAQ11)
2904 .
Case(
"za12v.q", AArch64::ZAQ12)
2905 .
Case(
"za13v.q", AArch64::ZAQ13)
2906 .
Case(
"za14v.q", AArch64::ZAQ14)
2907 .
Case(
"za15v.q", AArch64::ZAQ15)
2908 .
Case(
"za0v.d", AArch64::ZAD0)
2909 .
Case(
"za1v.d", AArch64::ZAD1)
2910 .
Case(
"za2v.d", AArch64::ZAD2)
2911 .
Case(
"za3v.d", AArch64::ZAD3)
2912 .
Case(
"za4v.d", AArch64::ZAD4)
2913 .
Case(
"za5v.d", AArch64::ZAD5)
2914 .
Case(
"za6v.d", AArch64::ZAD6)
2915 .
Case(
"za7v.d", AArch64::ZAD7)
2916 .
Case(
"za0v.s", AArch64::ZAS0)
2917 .
Case(
"za1v.s", AArch64::ZAS1)
2918 .
Case(
"za2v.s", AArch64::ZAS2)
2919 .
Case(
"za3v.s", AArch64::ZAS3)
2920 .
Case(
"za0v.h", AArch64::ZAH0)
2921 .
Case(
"za1v.h", AArch64::ZAH1)
2922 .
Case(
"za0v.b", AArch64::ZAB0)
2926bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2928 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2931ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2933 StartLoc = getLoc();
2934 ParseStatus Res = tryParseScalarRegister(
Reg);
2940MCRegister AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2942 MCRegister
Reg = MCRegister();
2944 return Kind == RegKind::SVEDataVector ?
Reg : MCRegister();
2947 return Kind == RegKind::SVEPredicateVector ?
Reg : MCRegister();
2950 return Kind == RegKind::SVEPredicateAsCounter ?
Reg : MCRegister();
2953 return Kind == RegKind::NeonVector ?
Reg : MCRegister();
2956 return Kind == RegKind::Matrix ?
Reg : MCRegister();
2958 if (
Name.equals_insensitive(
"zt0"))
2959 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
2963 return (Kind == RegKind::Scalar) ?
Reg : MCRegister();
2967 if (MCRegister
Reg = StringSwitch<unsigned>(
Name.lower())
2968 .Case(
"fp", AArch64::FP)
2969 .Case(
"lr", AArch64::LR)
2970 .Case(
"x31", AArch64::XZR)
2971 .Case(
"w31", AArch64::WZR)
2973 return Kind == RegKind::Scalar ?
Reg : MCRegister();
2979 if (Entry == RegisterReqs.
end())
2980 return MCRegister();
2983 if (Kind ==
Entry->getValue().first)
2989unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2991 case RegKind::Scalar:
2992 case RegKind::NeonVector:
2993 case RegKind::SVEDataVector:
2995 case RegKind::Matrix:
2996 case RegKind::SVEPredicateVector:
2997 case RegKind::SVEPredicateAsCounter:
2999 case RegKind::LookupTable:
3008ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3009 const AsmToken &Tok = getTok();
3014 MCRegister
Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3024ParseStatus AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
3028 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3031 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3032 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3036 if (BadNum || CRNum > 15)
3037 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3041 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3046ParseStatus AArch64AsmParser::tryParseRPRFMOperand(
OperandVector &Operands) {
3048 const AsmToken &Tok = getTok();
3050 unsigned MaxVal = 63;
3055 const MCExpr *ImmVal;
3056 if (getParser().parseExpression(ImmVal))
3061 return TokError(
"immediate value expected for prefetch operand");
3064 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3067 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3068 Operands.
push_back(AArch64Operand::CreatePrefetch(
3069 prfop, RPRFM ? AArch64RPRFM::getRPRFMStr(RPRFM->Name) :
"", S,
3075 return TokError(
"prefetch hint expected");
3077 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3079 return TokError(
"prefetch hint expected");
3081 Operands.
push_back(AArch64Operand::CreatePrefetch(
3088template <
bool IsSVEPrefetch>
3089ParseStatus AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
3091 const AsmToken &Tok = getTok();
3093 auto LookupByName = [](StringRef
N) {
3094 if (IsSVEPrefetch) {
3095 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3096 return std::optional<unsigned>(Res->Encoding);
3097 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3098 return std::optional<unsigned>(Res->Encoding);
3099 return std::optional<unsigned>();
3102 auto LookupByEncoding = [](
unsigned E) {
3103 if (IsSVEPrefetch) {
3104 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3105 return std::optional<StringRef>(
3106 AArch64SVEPRFM::getSVEPRFMStr(Res->Name));
3107 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3108 return std::optional<StringRef>(AArch64PRFM::getPRFMStr(Res->Name));
3109 return std::optional<StringRef>();
3111 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3117 const MCExpr *ImmVal;
3118 if (getParser().parseExpression(ImmVal))
3123 return TokError(
"immediate value expected for prefetch operand");
3126 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3129 auto PRFM = LookupByEncoding(MCE->
getValue());
3130 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3136 return TokError(
"prefetch hint expected");
3138 auto PRFM = LookupByName(Tok.
getString());
3140 return TokError(
"prefetch hint expected");
3142 Operands.
push_back(AArch64Operand::CreatePrefetch(
3148ParseStatus AArch64AsmParser::tryParseSyspXzrPair(
OperandVector &Operands) {
3149 SMLoc StartLoc = getLoc();
3155 auto RegTok = getTok();
3156 if (!tryParseScalarRegister(RegNum).isSuccess())
3159 if (RegNum != AArch64::XZR) {
3160 getLexer().UnLex(RegTok);
3167 if (!tryParseScalarRegister(RegNum).isSuccess())
3168 return TokError(
"expected register operand");
3170 if (RegNum != AArch64::XZR)
3171 return TokError(
"xzr must be followed by xzr");
3175 Operands.
push_back(AArch64Operand::CreateReg(
3176 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3182ParseStatus AArch64AsmParser::tryParseTIndexHint(
OperandVector &Operands) {
3184 const AsmToken &Tok = getTok();
3186 return TokError(
"invalid operand for instruction");
3188 auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.
getString());
3190 return TokError(
"invalid operand for instruction");
3192 Operands.
push_back(AArch64Operand::CreateTIndexHint(
3200ParseStatus AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
3202 const MCExpr *Expr =
nullptr;
3208 if (parseSymbolicImmVal(Expr))
3214 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3223 return Error(S,
"gotpage label reference not allowed an addend");
3235 return Error(S,
"page or gotpage label reference expected");
3250ParseStatus AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
3252 const MCExpr *Expr =
nullptr;
3261 if (parseSymbolicImmVal(Expr))
3267 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3279 return Error(S,
"unexpected adr label");
3289template <
bool AddFPZeroAsLiteral>
3290ParseStatus AArch64AsmParser::tryParseFPImm(
OperandVector &Operands) {
3298 const AsmToken &Tok = getTok();
3302 return TokError(
"invalid floating point immediate");
3307 if (Tok.
getIntVal() > 255 || isNegative)
3308 return TokError(
"encoded floating point value out of range");
3312 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3315 APFloat RealVal(APFloat::IEEEdouble());
3317 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3319 return TokError(
"invalid floating point representation");
3322 RealVal.changeSign();
3324 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3328 Operands.
push_back(AArch64Operand::CreateFPImm(
3329 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3340AArch64AsmParser::tryParseImmWithOptionalShift(
OperandVector &Operands) {
3351 return tryParseImmRange(Operands);
3353 const MCExpr *
Imm =
nullptr;
3354 if (parseSymbolicImmVal(Imm))
3358 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3365 if (!parseOptionalVGOperand(Operands, VecGroup)) {
3367 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3369 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3375 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3376 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3384 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3386 int64_t ShiftAmount = getTok().getIntVal();
3388 if (ShiftAmount < 0)
3389 return Error(getLoc(),
"positive shift amount required");
3393 if (ShiftAmount == 0 && Imm !=
nullptr) {
3395 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3399 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3407AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3441 Suggestion =
"nfrst";
3447bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
3448 bool invertCondCode) {
3450 const AsmToken &Tok = getTok();
3454 std::string Suggestion;
3457 std::string
Msg =
"invalid condition code";
3458 if (!Suggestion.empty())
3459 Msg +=
", did you mean " + Suggestion +
"?";
3460 return TokError(
Msg);
3464 if (invertCondCode) {
3466 return TokError(
"condition codes AL and NV are invalid for this instruction");
3471 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3475ParseStatus AArch64AsmParser::tryParseSVCR(
OperandVector &Operands) {
3476 const AsmToken &Tok = getTok();
3480 return TokError(
"invalid operand for instruction");
3482 unsigned PStateImm = -1;
3483 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3486 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3487 PStateImm = SVCR->Encoding;
3495ParseStatus AArch64AsmParser::tryParseMatrixRegister(
OperandVector &Operands) {
3496 const AsmToken &Tok = getTok();
3501 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3503 unsigned ElementWidth = 0;
3504 auto DotPosition =
Name.find(
'.');
3506 const auto &KindRes =
3510 "Expected the register to be followed by element width suffix");
3511 ElementWidth = KindRes->second;
3513 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3514 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3519 if (parseOperand(Operands,
false,
false))
3526 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3530 size_t DotPosition =
Name.find(
'.');
3533 StringRef Head =
Name.take_front(DotPosition);
3534 StringRef
Tail =
Name.drop_front(DotPosition);
3535 StringRef RowOrColumn = Head.
take_back();
3537 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3538 .Case(
"h", MatrixKind::Row)
3539 .Case(
"v", MatrixKind::Col)
3540 .Default(MatrixKind::Tile);
3546 "Expected the register to be followed by element width suffix");
3547 unsigned ElementWidth = KindRes->second;
3551 Operands.
push_back(AArch64Operand::CreateMatrixRegister(
3557 if (parseOperand(Operands,
false,
false))
3566AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
3567 const AsmToken &Tok = getTok();
3570 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3599 return TokError(
"expected #imm after shift specifier");
3605 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3614 return Error(
E,
"expected integer shift amount");
3616 const MCExpr *ImmVal;
3617 if (getParser().parseExpression(ImmVal))
3622 return Error(
E,
"expected constant '#imm' after shift specifier");
3625 Operands.
push_back(AArch64Operand::CreateShiftExtend(
3631 {{
"crc"}, {AArch64::FeatureCRC}},
3632 {{
"sm4"}, {AArch64::FeatureSM4}},
3633 {{
"sha3"}, {AArch64::FeatureSHA3}},
3634 {{
"sha2"}, {AArch64::FeatureSHA2}},
3635 {{
"aes"}, {AArch64::FeatureAES}},
3636 {{
"crypto"}, {AArch64::FeatureCrypto}},
3637 {{
"fp"}, {AArch64::FeatureFPARMv8}},
3638 {{
"simd"}, {AArch64::FeatureNEON}},
3639 {{
"ras"}, {AArch64::FeatureRAS}},
3640 {{
"rasv2"}, {AArch64::FeatureRASv2}},
3641 {{
"lse"}, {AArch64::FeatureLSE}},
3642 {{
"predres"}, {AArch64::FeaturePredRes}},
3643 {{
"predres2"}, {AArch64::FeatureSPECRES2}},
3644 {{
"ccdp"}, {AArch64::FeatureCacheDeepPersist}},
3645 {{
"mte"}, {AArch64::FeatureMTE}},
3646 {{
"memtag"}, {AArch64::FeatureMTE}},
3647 {{
"tlb-rmi"}, {AArch64::FeatureTLB_RMI}},
3648 {{
"pan"}, {AArch64::FeaturePAN}},
3649 {{
"pan-rwv"}, {AArch64::FeaturePAN_RWV}},
3650 {{
"ccpp"}, {AArch64::FeatureCCPP}},
3651 {{
"rcpc"}, {AArch64::FeatureRCPC}},
3652 {{
"rng"}, {AArch64::FeatureRandGen}},
3653 {{
"sve"}, {AArch64::FeatureSVE}},
3654 {{
"sve-b16b16"}, {AArch64::FeatureSVEB16B16}},
3655 {{
"sve2"}, {AArch64::FeatureSVE2}},
3656 {{
"sve-aes"}, {AArch64::FeatureSVEAES}},
3657 {{
"sve2-aes"}, {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3658 {{
"sve-sm4"}, {AArch64::FeatureSVESM4}},
3659 {{
"sve2-sm4"}, {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3660 {{
"sve-sha3"}, {AArch64::FeatureSVESHA3}},
3661 {{
"sve2-sha3"}, {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3662 {{
"sve-bitperm"}, {AArch64::FeatureSVEBitPerm}},
3664 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3665 AArch64::FeatureSVE2}},
3666 {{
"sve2p1"}, {AArch64::FeatureSVE2p1}},
3667 {{
"ls64"}, {AArch64::FeatureLS64}},
3668 {{
"xs"}, {AArch64::FeatureXS}},
3669 {{
"pauth"}, {AArch64::FeaturePAuth}},
3670 {{
"flagm"}, {AArch64::FeatureFlagM}},
3671 {{
"rme"}, {AArch64::FeatureRME}},
3672 {{
"sme"}, {AArch64::FeatureSME}},
3673 {{
"sme-f64f64"}, {AArch64::FeatureSMEF64F64}},
3674 {{
"sme-f16f16"}, {AArch64::FeatureSMEF16F16}},
3675 {{
"sme-i16i64"}, {AArch64::FeatureSMEI16I64}},
3676 {{
"sme2"}, {AArch64::FeatureSME2}},
3677 {{
"sme2p1"}, {AArch64::FeatureSME2p1}},
3678 {{
"sme-b16b16"}, {AArch64::FeatureSMEB16B16}},
3679 {{
"hbc"}, {AArch64::FeatureHBC}},
3680 {{
"mops"}, {AArch64::FeatureMOPS}},
3681 {{
"mec"}, {AArch64::FeatureMEC}},
3682 {{
"the"}, {AArch64::FeatureTHE}},
3683 {{
"d128"}, {AArch64::FeatureD128}},
3684 {{
"lse128"}, {AArch64::FeatureLSE128}},
3685 {{
"ite"}, {AArch64::FeatureITE}},
3686 {{
"cssc"}, {AArch64::FeatureCSSC}},
3687 {{
"rcpc3"}, {AArch64::FeatureRCPC3}},
3688 {{
"gcs"}, {AArch64::FeatureGCS}},
3689 {{
"bf16"}, {AArch64::FeatureBF16}},
3690 {{
"compnum"}, {AArch64::FeatureComplxNum}},
3691 {{
"dotprod"}, {AArch64::FeatureDotProd}},
3692 {{
"f32mm"}, {AArch64::FeatureMatMulFP32}},
3693 {{
"f64mm"}, {AArch64::FeatureMatMulFP64}},
3694 {{
"fp16"}, {AArch64::FeatureFullFP16}},
3695 {{
"fp16fml"}, {AArch64::FeatureFP16FML}},
3696 {{
"i8mm"}, {AArch64::FeatureMatMulInt8}},
3697 {{
"lor"}, {AArch64::FeatureLOR}},
3698 {{
"profile"}, {AArch64::FeatureSPE}},
3702 {{
"rdm"}, {AArch64::FeatureRDM}},
3703 {{
"rdma"}, {AArch64::FeatureRDM}},
3704 {{
"sb"}, {AArch64::FeatureSB}},
3705 {{
"ssbs"}, {AArch64::FeatureSSBS}},
3706 {{
"fp8"}, {AArch64::FeatureFP8}},
3707 {{
"faminmax"}, {AArch64::FeatureFAMINMAX}},
3708 {{
"fp8fma"}, {AArch64::FeatureFP8FMA}},
3709 {{
"ssve-fp8fma"}, {AArch64::FeatureSSVE_FP8FMA}},
3710 {{
"fp8dot2"}, {AArch64::FeatureFP8DOT2}},
3711 {{
"ssve-fp8dot2"}, {AArch64::FeatureSSVE_FP8DOT2}},
3712 {{
"fp8dot4"}, {AArch64::FeatureFP8DOT4}},
3713 {{
"ssve-fp8dot4"}, {AArch64::FeatureSSVE_FP8DOT4}},
3714 {{
"lut"}, {AArch64::FeatureLUT}},
3715 {{
"sme-lutv2"}, {AArch64::FeatureSME_LUTv2}},
3716 {{
"sme-f8f16"}, {AArch64::FeatureSMEF8F16}},
3717 {{
"sme-f8f32"}, {AArch64::FeatureSMEF8F32}},
3718 {{
"sme-fa64"}, {AArch64::FeatureSMEFA64}},
3719 {{
"cpa"}, {AArch64::FeatureCPA}},
3720 {{
"tlbiw"}, {AArch64::FeatureTLBIW}},
3721 {{
"pops"}, {AArch64::FeaturePoPS}},
3722 {{
"cmpbr"}, {AArch64::FeatureCMPBR}},
3723 {{
"f8f32mm"}, {AArch64::FeatureF8F32MM}},
3724 {{
"f8f16mm"}, {AArch64::FeatureF8F16MM}},
3725 {{
"fprcvt"}, {AArch64::FeatureFPRCVT}},
3726 {{
"lsfe"}, {AArch64::FeatureLSFE}},
3727 {{
"sme2p2"}, {AArch64::FeatureSME2p2}},
3728 {{
"ssve-aes"}, {AArch64::FeatureSSVE_AES}},
3729 {{
"sve2p2"}, {AArch64::FeatureSVE2p2}},
3730 {{
"sve-aes2"}, {AArch64::FeatureSVEAES2}},
3731 {{
"sve-bfscale"}, {AArch64::FeatureSVEBFSCALE}},
3732 {{
"sve-f16f32mm"}, {AArch64::FeatureSVE_F16F32MM}},
3733 {{
"lsui"}, {AArch64::FeatureLSUI}},
3734 {{
"occmo"}, {AArch64::FeatureOCCMO}},
3735 {{
"ssve-bitperm"}, {AArch64::FeatureSSVE_BitPerm}},
3736 {{
"sme-mop4"}, {AArch64::FeatureSME_MOP4}},
3737 {{
"sme-tmop"}, {AArch64::FeatureSME_TMOP}},
3738 {{
"lscp"}, {AArch64::FeatureLSCP}},
3739 {{
"tlbid"}, {AArch64::FeatureTLBID}},
3740 {{
"mtetc"}, {AArch64::FeatureMTETC}},
3741 {{
"gcie"}, {AArch64::FeatureGCIE}},
3742 {{
"sme2p3"}, {AArch64::FeatureSME2p3}},
3743 {{
"sve2p3"}, {AArch64::FeatureSVE2p3}},
3744 {{
"sve-b16mm"}, {AArch64::FeatureSVE_B16MM}},
3745 {{
"f16mm"}, {AArch64::FeatureF16MM}},
3746 {{
"f16f32dot"}, {AArch64::FeatureF16F32DOT}},
3747 {{
"f16f32mm"}, {AArch64::FeatureF16F32MM}},
3748 {{
"mops-go"}, {AArch64::FeatureMOPS_GO}},
3749 {{
"poe2"}, {AArch64::FeatureS1POE2}},
3750 {{
"tev"}, {AArch64::FeatureTEV}},
3751 {{
"btie"}, {AArch64::FeatureBTIE}},
3752 {{
"hinte"}, {AArch64::FeatureHINTE}},
3753 {{
"dit"}, {AArch64::FeatureDIT}},
3754 {{
"brbe"}, {AArch64::FeatureBRBE}},
3755 {{
"bti"}, {AArch64::FeatureBranchTargetId}},
3756 {{
"fcma"}, {AArch64::FeatureComplxNum}},
3757 {{
"jscvt"}, {AArch64::FeatureJS}},
3758 {{
"pauth-lr"}, {AArch64::FeaturePAuthLR}},
3759 {{
"ssve-fexpa"}, {AArch64::FeatureSSVE_FEXPA}},
3760 {{
"wfxt"}, {AArch64::FeatureWFxT}},
3765 if (FBS[AArch64::HasV8_0aOps])
3767 if (FBS[AArch64::HasV8_1aOps])
3769 else if (FBS[AArch64::HasV8_2aOps])
3771 else if (FBS[AArch64::HasV8_3aOps])
3773 else if (FBS[AArch64::HasV8_4aOps])
3775 else if (FBS[AArch64::HasV8_5aOps])
3777 else if (FBS[AArch64::HasV8_6aOps])
3779 else if (FBS[AArch64::HasV8_7aOps])
3781 else if (FBS[AArch64::HasV8_8aOps])
3783 else if (FBS[AArch64::HasV8_9aOps])
3785 else if (FBS[AArch64::HasV9_0aOps])
3787 else if (FBS[AArch64::HasV9_1aOps])
3789 else if (FBS[AArch64::HasV9_2aOps])
3791 else if (FBS[AArch64::HasV9_3aOps])
3793 else if (FBS[AArch64::HasV9_4aOps])
3795 else if (FBS[AArch64::HasV9_5aOps])
3797 else if (FBS[AArch64::HasV9_6aOps])
3799 else if (FBS[AArch64::HasV9_7aOps])
3801 else if (FBS[AArch64::HasV8_0rOps])
3810 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3814void AArch64AsmParser::createSysAlias(uint16_t Encoding,
OperandVector &Operands,
3816 const uint16_t Op2 = Encoding & 7;
3817 const uint16_t Cm = (Encoding & 0x78) >> 3;
3818 const uint16_t Cn = (Encoding & 0x780) >> 7;
3819 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3824 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3826 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3828 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3831 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3837bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3839 if (
Name.contains(
'.'))
3840 return TokError(
"invalid operand");
3845 const AsmToken &Tok = getTok();
3848 bool ExpectRegister =
true;
3849 bool OptionalRegister =
false;
3850 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3851 bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
3853 if (Mnemonic ==
"ic") {
3854 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3856 return TokError(
"invalid operand for IC instruction");
3857 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3858 std::string Str(
"IC " + std::string(AArch64IC::getICStr(IC->
Name)) +
3861 return TokError(Str);
3864 createSysAlias(IC->
Encoding, Operands, S);
3865 }
else if (Mnemonic ==
"dc") {
3866 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3868 return TokError(
"invalid operand for DC instruction");
3869 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3870 std::string Str(
"DC " + std::string(AArch64DC::getDCStr(DC->
Name)) +
3873 return TokError(Str);
3875 createSysAlias(DC->
Encoding, Operands, S);
3876 }
else if (Mnemonic ==
"at") {
3877 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3879 return TokError(
"invalid operand for AT instruction");
3880 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3881 std::string Str(
"AT " + std::string(AArch64AT::getATStr(AT->
Name)) +
3884 return TokError(Str);
3886 createSysAlias(AT->
Encoding, Operands, S);
3887 }
else if (Mnemonic ==
"tlbi") {
3888 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3890 return TokError(
"invalid operand for TLBI instruction");
3891 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3892 std::string Str(
"TLBI " +
3893 std::string(AArch64TLBI::getTLBIStr(TLBI->
Name)) +
3896 return TokError(Str);
3898 ExpectRegister = TLBI->
RegUse == REG_REQUIRED;
3899 if (hasAll || hasTLBID)
3900 OptionalRegister = TLBI->
RegUse == REG_OPTIONAL;
3901 createSysAlias(TLBI->
Encoding, Operands, S);
3902 }
else if (Mnemonic ==
"gic") {
3903 const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(
Op);
3905 return TokError(
"invalid operand for GIC instruction");
3906 else if (!GIC->
haveFeatures(getSTI().getFeatureBits())) {
3907 std::string Str(
"GIC " + std::string(AArch64GIC::getGICStr(GIC->
Name)) +
3910 return TokError(Str);
3913 createSysAlias(GIC->
Encoding, Operands, S);
3914 }
else if (Mnemonic ==
"gsb") {
3915 const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(
Op);
3917 return TokError(
"invalid operand for GSB instruction");
3918 else if (!GSB->
haveFeatures(getSTI().getFeatureBits())) {
3919 std::string Str(
"GSB " + std::string(AArch64GSB::getGSBStr(GSB->
Name)) +
3922 return TokError(Str);
3924 ExpectRegister =
false;
3925 createSysAlias(GSB->
Encoding, Operands, S);
3926 }
else if (Mnemonic ==
"plbi") {
3927 const AArch64PLBI::PLBI *PLBI = AArch64PLBI::lookupPLBIByName(
Op);
3929 return TokError(
"invalid operand for PLBI instruction");
3930 else if (!PLBI->
haveFeatures(getSTI().getFeatureBits())) {
3931 std::string Str(
"PLBI " +
3932 std::string(AArch64PLBI::getPLBIStr(PLBI->
Name)) +
3935 return TokError(Str);
3937 ExpectRegister = PLBI->
RegUse == REG_REQUIRED;
3938 if (hasAll || hasTLBID)
3939 OptionalRegister = PLBI->
RegUse == REG_OPTIONAL;
3940 createSysAlias(PLBI->
Encoding, Operands, S);
3941 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" ||
3942 Mnemonic ==
"cosp") {
3944 if (
Op.lower() !=
"rctx")
3945 return TokError(
"invalid operand for prediction restriction instruction");
3947 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3948 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3950 if (Mnemonic ==
"cosp" && !hasSpecres2)
3951 return TokError(
"COSP requires: predres2");
3953 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3955 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3956 : Mnemonic ==
"dvp" ? 0b101
3957 : Mnemonic ==
"cosp" ? 0b110
3958 : Mnemonic ==
"cpp" ? 0b111
3961 "Invalid mnemonic for prediction restriction instruction");
3962 const auto SYS_3_7_3 = 0b01101110011;
3963 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3965 createSysAlias(Encoding, Operands, S);
3970 bool HasRegister =
false;
3975 return TokError(
"expected register operand");
3979 if (!OptionalRegister) {
3980 if (ExpectRegister && !HasRegister)
3981 return TokError(
"specified " + Mnemonic +
" op requires a register");
3982 else if (!ExpectRegister && HasRegister)
3983 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3995bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4000 AArch64Operand::CreateToken(
"sysl", NameLoc,
getContext()));
4003 SMLoc startLoc = getLoc();
4004 const AsmToken ®Tok = getTok();
4006 MCRegister
Reg = matchRegisterNameAlias(reg.
lower(), RegKind::Scalar);
4008 return TokError(
"expected register operand");
4010 Operands.
push_back(AArch64Operand::CreateReg(
4011 Reg, RegKind::Scalar, startLoc, getLoc(),
getContext(), EqualsReg));
4018 const AsmToken &operandTok = getTok();
4020 SMLoc S2 = operandTok.
getLoc();
4023 if (Mnemonic ==
"gicr") {
4024 const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(
Op);
4026 return Error(S2,
"invalid operand for GICR instruction");
4027 else if (!GICR->
haveFeatures(getSTI().getFeatureBits())) {
4028 std::string Str(
"GICR " +
4029 std::string(AArch64GICR::getGICRStr(GICR->
Name)) +
4032 return Error(S2, Str);
4034 createSysAlias(GICR->
Encoding, Operands, S2);
4045bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4047 if (
Name.contains(
'.'))
4048 return TokError(
"invalid operand");
4052 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4054 const AsmToken &Tok = getTok();
4058 if (Mnemonic ==
"tlbip") {
4059 const AArch64TLBIP::TLBIP *TLBIP = AArch64TLBIP::lookupTLBIPByName(
Op);
4061 return TokError(
"invalid operand for TLBIP instruction");
4064 std::string Str(
"instruction requires: ");
4066 return TokError(Str);
4068 createSysAlias(TLBIP->
Encoding, Operands, S);
4077 return TokError(
"expected register identifier");
4078 auto Result = tryParseSyspXzrPair(Operands);
4080 Result = tryParseGPRSeqPair(Operands);
4082 return TokError(
"specified " + Mnemonic +
4083 " op requires a pair of registers");
4091ParseStatus AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
4092 MCAsmParser &Parser = getParser();
4093 const AsmToken &Tok = getTok();
4097 const MCExpr *ImmVal;
4098 SMLoc ExprLoc = getLoc();
4099 AsmToken IntTok = Tok;
4100 if (getParser().parseExpression(ImmVal))
4104 return Error(ExprLoc,
"immediate value expected for barrier operand");
4106 if (Mnemonic ==
"dsb" &&
Value > 15) {
4114 return Error(ExprLoc,
"barrier operand out of range");
4115 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4116 StringRef DBStr =
DB ? AArch64DB::getDBStr(
DB->Name) :
"";
4117 Operands.
push_back(AArch64Operand::CreateBarrier(
4123 return TokError(
"invalid operand for instruction");
4126 auto DB = AArch64DB::lookupDBByName(Operand);
4128 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4129 return TokError(
"'sy' or #imm operand expected");
4131 if (Mnemonic ==
"dsb") {
4136 return TokError(
"invalid barrier option name");
4140 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4148AArch64AsmParser::tryParseBarriernXSOperand(
OperandVector &Operands) {
4149 const AsmToken &Tok = getTok();
4151 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4152 if (Mnemonic !=
"dsb")
4157 const MCExpr *ImmVal;
4158 SMLoc ExprLoc = getLoc();
4159 if (getParser().parseExpression(ImmVal))
4163 return Error(ExprLoc,
"immediate value expected for barrier operand");
4168 return Error(ExprLoc,
"barrier operand out of range");
4169 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4170 StringRef DBName = AArch64DBnXS::getDBnXSStr(
DB->Name);
4171 Operands.
push_back(AArch64Operand::CreateBarrier(
4177 return TokError(
"invalid operand for instruction");
4180 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4183 return TokError(
"invalid barrier option name");
4186 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4193ParseStatus AArch64AsmParser::tryParseSysReg(
OperandVector &Operands) {
4194 const AsmToken &Tok = getTok();
4199 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4203 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4204 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4205 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4206 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4210 unsigned PStateImm = -1;
4211 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4212 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4213 PStateImm = PState15->Encoding;
4215 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4216 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4217 PStateImm = PState1->Encoding;
4221 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4229bool AArch64AsmParser::tryParseNeonVectorRegister(
OperandVector &Operands) {
4237 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4245 unsigned ElementWidth = KindRes->second;
4247 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4255 return tryParseVectorIndex(Operands).isFailure();
4258ParseStatus AArch64AsmParser::tryParseVectorIndex(
OperandVector &Operands) {
4259 SMLoc SIdx = getLoc();
4261 const MCExpr *ImmVal;
4262 if (getParser().parseExpression(ImmVal))
4266 return TokError(
"immediate value expected for vector index");
4284ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4286 RegKind MatchKind) {
4287 const AsmToken &Tok = getTok();
4296 StringRef Head =
Name.slice(Start,
Next);
4297 MCRegister RegNum = matchRegisterNameAlias(Head, MatchKind);
4303 return TokError(
"invalid vector kind qualifier");
4314ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4316 ParseStatus Status =
4317 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(Operands);
4319 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(Operands);
4324template <RegKind RK>
4326AArch64AsmParser::tryParseSVEPredicateVector(
OperandVector &Operands) {
4328 const SMLoc S = getLoc();
4331 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4339 unsigned ElementWidth = KindRes->second;
4340 Operands.
push_back(AArch64Operand::CreateVectorReg(
4341 RegNum, RK, ElementWidth, S,
4345 if (RK == RegKind::SVEPredicateAsCounter) {
4346 ParseStatus ResIndex = tryParseVectorIndex(Operands);
4352 if (parseOperand(Operands,
false,
false))
4363 return Error(S,
"not expecting size suffix");
4371 auto Pred = getTok().getString().lower();
4372 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4373 return Error(getLoc(),
"expecting 'z' predication");
4375 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4376 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4379 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4387bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
4389 if (!tryParseNeonVectorRegister(Operands))
4392 if (tryParseZTOperand(Operands).isSuccess())
4396 if (tryParseGPROperand<false>(Operands).isSuccess())
4402bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4403 bool HasELFModifier =
false;
4405 SMLoc Loc = getLexer().getLoc();
4407 HasELFModifier =
true;
4410 return TokError(
"expect relocation specifier in operand after ':'");
4412 std::string LowerCase = getTok().getIdentifier().lower();
4413 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4468 return TokError(
"expect relocation specifier in operand after ':'");
4472 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4476 if (getParser().parseExpression(ImmVal))
4483 if (
getContext().getAsmInfo().hasSubsectionsViaSymbols()) {
4484 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4494 if (getParser().parsePrimaryExpr(Term, EndLoc))
4502ParseStatus AArch64AsmParser::tryParseMatrixTileList(
OperandVector &Operands) {
4506 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4507 unsigned &ElementWidth) -> ParseStatus {
4508 StringRef
Name = getTok().getString();
4509 size_t DotPosition =
Name.find(
'.');
4517 StringRef
Tail =
Name.drop_front(DotPosition);
4518 const std::optional<std::pair<int, int>> &KindRes =
4522 "Expected the register to be followed by element width suffix");
4523 ElementWidth = KindRes->second;
4530 auto LCurly = getTok();
4535 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4541 if (getTok().getString().equals_insensitive(
"za")) {
4547 Operands.
push_back(AArch64Operand::CreateMatrixTileList(
4552 SMLoc TileLoc = getLoc();
4554 unsigned FirstReg, ElementWidth;
4555 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4556 if (!ParseRes.isSuccess()) {
4557 getLexer().UnLex(LCurly);
4561 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4563 unsigned PrevReg = FirstReg;
4565 SmallSet<unsigned, 8> DRegs;
4566 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4568 SmallSet<unsigned, 8> SeenRegs;
4569 SeenRegs.
insert(FirstReg);
4573 unsigned Reg, NextElementWidth;
4574 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4575 if (!ParseRes.isSuccess())
4579 if (ElementWidth != NextElementWidth)
4580 return Error(TileLoc,
"mismatched register size suffix");
4583 Warning(TileLoc,
"tile list not in ascending order");
4586 Warning(TileLoc,
"duplicate tile in list");
4589 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4598 unsigned RegMask = 0;
4599 for (
auto Reg : DRegs)
4603 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4608template <RegKind VectorKind>
4609ParseStatus AArch64AsmParser::tryParseVectorList(
OperandVector &Operands,
4611 MCAsmParser &Parser = getParser();
4616 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4617 bool NoMatchIsError) -> ParseStatus {
4618 auto RegTok = getTok();
4619 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4620 if (ParseRes.isSuccess()) {
4627 RegTok.getString().equals_insensitive(
"zt0"))
4631 (ParseRes.isNoMatch() && NoMatchIsError &&
4632 !RegTok.getString().starts_with_insensitive(
"za")))
4633 return Error(Loc,
"vector register expected");
4638 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4640 auto LCurly = getTok();
4644 MCRegister FirstReg;
4645 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4649 if (ParseRes.isNoMatch())
4652 if (!ParseRes.isSuccess())
4655 MCRegister PrevReg = FirstReg;
4658 unsigned Stride = 1;
4660 SMLoc Loc = getLoc();
4664 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4665 if (!ParseRes.isSuccess())
4669 if (Kind != NextKind)
4670 return Error(Loc,
"mismatched register size suffix");
4673 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4675 if (Space == 0 || Space > 3)
4676 return Error(Loc,
"invalid number of vectors");
4681 bool HasCalculatedStride =
false;
4683 SMLoc Loc = getLoc();
4686 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4687 if (!ParseRes.isSuccess())
4691 if (Kind != NextKind)
4692 return Error(Loc,
"mismatched register size suffix");
4694 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4695 unsigned PrevRegVal =
4696 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4697 if (!HasCalculatedStride) {
4698 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4699 : (NumRegs - (PrevRegVal - RegVal));
4700 HasCalculatedStride =
true;
4704 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4705 return Error(Loc,
"registers must have the same sequential stride");
4716 return Error(S,
"invalid number of vectors");
4718 unsigned NumElements = 0;
4719 unsigned ElementWidth = 0;
4720 if (!
Kind.empty()) {
4722 std::tie(NumElements, ElementWidth) = *VK;
4725 Operands.
push_back(AArch64Operand::CreateVectorList(
4726 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4730 ParseStatus Res = tryParseVectorIndex(Operands);
4740bool AArch64AsmParser::parseNeonVectorList(
OperandVector &Operands) {
4741 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands,
true);
4742 if (!ParseRes.isSuccess())
4745 return tryParseVectorIndex(Operands).isFailure();
4748ParseStatus AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
4749 SMLoc StartLoc = getLoc();
4752 ParseStatus Res = tryParseScalarRegister(RegNum);
4757 Operands.
push_back(AArch64Operand::CreateReg(
4758 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4765 return Error(getLoc(),
"index must be absent or #0");
4767 const MCExpr *ImmVal;
4770 return Error(getLoc(),
"index must be absent or #0");
4772 Operands.
push_back(AArch64Operand::CreateReg(
4773 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4777ParseStatus AArch64AsmParser::tryParseZTOperand(
OperandVector &Operands) {
4778 SMLoc StartLoc = getLoc();
4779 const AsmToken &Tok = getTok();
4782 MCRegister
Reg = matchRegisterNameAlias(Name, RegKind::LookupTable);
4787 Operands.
push_back(AArch64Operand::CreateReg(
4788 Reg, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4794 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4795 const MCExpr *ImmVal;
4796 if (getParser().parseExpression(ImmVal))
4800 return TokError(
"immediate value expected for vector index");
4801 Operands.
push_back(AArch64Operand::CreateImm(
4805 if (parseOptionalMulOperand(Operands))
4810 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4815template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4816ParseStatus AArch64AsmParser::tryParseGPROperand(
OperandVector &Operands) {
4817 SMLoc StartLoc = getLoc();
4820 ParseStatus Res = tryParseScalarRegister(RegNum);
4826 Operands.
push_back(AArch64Operand::CreateReg(
4827 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4836 Res = tryParseOptionalShiftExtend(ExtOpnd);
4840 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4841 Operands.
push_back(AArch64Operand::CreateReg(
4842 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(),
getContext(), EqTy,
4843 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
4844 Ext->hasShiftExtendAmount()));
4849bool AArch64AsmParser::parseOptionalMulOperand(
OperandVector &Operands) {
4850 MCAsmParser &Parser = getParser();
4858 if (!getTok().getString().equals_insensitive(
"mul") ||
4859 !(NextIsVL || NextIsHash))
4863 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4868 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4878 const MCExpr *ImmVal;
4881 Operands.
push_back(AArch64Operand::CreateImm(
4888 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4891bool AArch64AsmParser::parseOptionalVGOperand(
OperandVector &Operands,
4892 StringRef &VecGroup) {
4893 MCAsmParser &Parser = getParser();
4894 auto Tok = Parser.
getTok();
4899 .Case(
"vgx2",
"vgx2")
4900 .Case(
"vgx4",
"vgx4")
4911bool AArch64AsmParser::parseKeywordOperand(
OperandVector &Operands) {
4912 auto Tok = getTok();
4919 .Case(
"csync",
"csync")
4922 .Case(
"keep",
"keep")
4926 .Case(
"strm",
"strm")
4938bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
4939 bool invertCondCode) {
4940 MCAsmParser &Parser = getParser();
4943 MatchOperandParserImpl(Operands, Mnemonic,
true);
4957 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4959 ParseStatus Res = tryParseOptionalShiftExtend(Operands);
4962 getLexer().UnLex(SavedTok);
4966 switch (getLexer().getKind()) {
4970 if (parseSymbolicImmVal(Expr))
4971 return Error(S,
"invalid operand");
4975 return parseOptionalShiftExtend(getTok());
4979 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4984 return parseOperand(Operands,
false,
false);
4987 if (!parseNeonVectorList(Operands))
4991 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
4996 return parseOperand(Operands,
false,
false);
5001 if (!parseOptionalVGOperand(Operands, VecGroup)) {
5003 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
5011 if (!parseRegister(Operands)) {
5013 AsmToken SavedTok = getTok();
5018 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic,
5022 Res = tryParseOptionalShiftExtend(Operands);
5025 getLexer().UnLex(SavedTok);
5032 if (!parseOptionalMulOperand(Operands))
5037 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5038 Mnemonic ==
"gcsb" || Mnemonic ==
"bti" || Mnemonic ==
"stshh" ||
5039 Mnemonic ==
"psb" || Mnemonic ==
"tsb" || Mnemonic ==
"shuh")
5040 return parseKeywordOperand(Operands);
5044 const MCExpr *IdVal, *
Term;
5046 if (getParser().parseExpression(IdVal))
5048 if (getParser().parseAtSpecifier(IdVal,
E))
5050 std::optional<MCBinaryExpr::Opcode> Opcode;
5056 if (getParser().parsePrimaryExpr(Term,
E))
5063 return parseOptionalShiftExtend(getTok());
5074 bool isNegative =
false;
5086 const AsmToken &Tok = getTok();
5089 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5090 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5091 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5092 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5093 return TokError(
"unexpected floating point literal");
5094 else if (IntVal != 0 || isNegative)
5095 return TokError(
"expected floating-point constant #0.0");
5103 const MCExpr *ImmVal;
5104 if (parseSymbolicImmVal(ImmVal))
5111 return parseOptionalShiftExtend(Tok);
5114 SMLoc Loc = getLoc();
5115 if (Mnemonic !=
"ldr")
5116 return TokError(
"unexpected token in operand");
5118 const MCExpr *SubExprVal;
5119 if (getParser().parseExpression(SubExprVal))
5122 if (Operands.
size() < 2 ||
5123 !
static_cast<AArch64Operand &
>(*Operands[1]).isScalarReg())
5124 return Error(Loc,
"Only valid when first operand is register");
5126 bool IsXReg = getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
5127 .contains(Operands[1]->
getReg());
5134 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5139 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5140 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5141 Operands.
push_back(AArch64Operand::CreateImm(
5145 ShiftAmt,
true, S,
E, Ctx));
5148 APInt Simm = APInt(64, Imm << ShiftAmt);
5151 return Error(Loc,
"Immediate too large for register");
5154 const MCExpr *CPLoc =
5155 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5156 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5162bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5163 const MCExpr *Expr =
nullptr;
5165 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5168 if (check(!
Value, L,
"expected constant expression"))
5170 Out =
Value->getValue();
5174bool AArch64AsmParser::parseComma() {
5182bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5186 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5191 unsigned RangeEnd =
Last;
5192 if (
Base == AArch64::X0) {
5193 if (
Last == AArch64::FP) {
5194 RangeEnd = AArch64::X28;
5195 if (
Reg == AArch64::FP) {
5200 if (
Last == AArch64::LR) {
5201 RangeEnd = AArch64::X28;
5202 if (
Reg == AArch64::FP) {
5205 }
else if (
Reg == AArch64::LR) {
5213 Twine(
"expected register in range ") +
5221bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5222 const MCParsedAsmOperand &Op2)
const {
5223 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5224 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5226 if (AOp1.isVectorList() && AOp2.isVectorList())
5227 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5228 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5229 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5231 if (!AOp1.isReg() || !AOp2.isReg())
5234 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5235 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5238 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5239 "Testing equality of non-scalar registers not supported");
5242 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5244 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5246 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5248 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5255bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
5256 StringRef Name, SMLoc NameLoc,
5258 Name = StringSwitch<StringRef>(
Name.lower())
5259 .Case(
"beq",
"b.eq")
5260 .Case(
"bne",
"b.ne")
5261 .Case(
"bhs",
"b.hs")
5262 .Case(
"bcs",
"b.cs")
5263 .Case(
"blo",
"b.lo")
5264 .Case(
"bcc",
"b.cc")
5265 .Case(
"bmi",
"b.mi")
5266 .Case(
"bpl",
"b.pl")
5267 .Case(
"bvs",
"b.vs")
5268 .Case(
"bvc",
"b.vc")
5269 .Case(
"bhi",
"b.hi")
5270 .Case(
"bls",
"b.ls")
5271 .Case(
"bge",
"b.ge")
5272 .Case(
"blt",
"b.lt")
5273 .Case(
"bgt",
"b.gt")
5274 .Case(
"ble",
"b.le")
5275 .Case(
"bal",
"b.al")
5276 .Case(
"bnv",
"b.nv")
5281 getTok().getIdentifier().lower() ==
".req") {
5282 parseDirectiveReq(Name, NameLoc);
5290 StringRef Head =
Name.slice(Start,
Next);
5294 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5295 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp" ||
5296 Head ==
"plbi" || Head ==
"gic" || Head ==
"gsb")
5297 return parseSysAlias(Head, NameLoc, Operands);
5301 return parseSyslAlias(Head, NameLoc, Operands);
5304 if (Head ==
"tlbip")
5305 return parseSyspAlias(Head, NameLoc, Operands);
5314 Head =
Name.slice(Start + 1,
Next);
5318 std::string Suggestion;
5321 std::string
Msg =
"invalid condition code";
5322 if (!Suggestion.empty())
5323 Msg +=
", did you mean " + Suggestion +
"?";
5329 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5339 Operands.
push_back(AArch64Operand::CreateToken(
5345 bool condCodeFourthOperand =
5346 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5347 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5348 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5356 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5357 bool condCodeThirdOperand =
5358 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5366 if (parseOperand(Operands, (
N == 4 && condCodeFourthOperand) ||
5367 (
N == 3 && condCodeThirdOperand) ||
5368 (
N == 2 && condCodeSecondOperand),
5369 condCodeSecondOperand || condCodeThirdOperand)) {
5389 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5392 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5395 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5408 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5409 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5410 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5411 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5412 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5413 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5414 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5426bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5427 SmallVectorImpl<SMLoc> &Loc) {
5428 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5435 PrefixInfo
Prefix = NextPrefix;
5436 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5447 return Error(IDLoc,
"instruction is unpredictable when following a"
5448 " movprfx, suggest replacing movprfx with mov");
5452 return Error(Loc[0],
"instruction is unpredictable when following a"
5453 " movprfx writing to a different destination");
5460 return Error(Loc[0],
"instruction is unpredictable when following a"
5461 " movprfx and destination also used as non-destructive"
5465 const auto &PPRRegClass = getAArch64MCRegisterClass(AArch64::PPRRegClassID);
5466 if (
Prefix.isPredicated()) {
5480 return Error(IDLoc,
"instruction is unpredictable when following a"
5481 " predicated movprfx, suggest using unpredicated movprfx");
5485 return Error(IDLoc,
"instruction is unpredictable when following a"
5486 " predicated movprfx using a different general predicate");
5490 return Error(IDLoc,
"instruction is unpredictable when following a"
5491 " predicated movprfx with a different element size");
5497 if (IsWindowsArm64EC) {
5503 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5504 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5505 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5506 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5507 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5508 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5509 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5510 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5511 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5512 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5514 " is disallowed on ARM64EC.");
5524 case AArch64::LDPSWpre:
5525 case AArch64::LDPWpost:
5526 case AArch64::LDPWpre:
5527 case AArch64::LDPXpost:
5528 case AArch64::LDPXpre: {
5533 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5534 "is also a destination");
5536 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5537 "is also a destination");
5540 case AArch64::LDR_ZA:
5541 case AArch64::STR_ZA: {
5544 return Error(Loc[1],
5545 "unpredictable instruction, immediate and offset mismatch.");
5548 case AArch64::LDPDi:
5549 case AArch64::LDPQi:
5550 case AArch64::LDPSi:
5551 case AArch64::LDPSWi:
5552 case AArch64::LDPWi:
5553 case AArch64::LDPXi: {
5557 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5560 case AArch64::LDPDpost:
5561 case AArch64::LDPDpre:
5562 case AArch64::LDPQpost:
5563 case AArch64::LDPQpre:
5564 case AArch64::LDPSpost:
5565 case AArch64::LDPSpre:
5566 case AArch64::LDPSWpost: {
5570 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5573 case AArch64::STPDpost:
5574 case AArch64::STPDpre:
5575 case AArch64::STPQpost:
5576 case AArch64::STPQpre:
5577 case AArch64::STPSpost:
5578 case AArch64::STPSpre:
5579 case AArch64::STPWpost:
5580 case AArch64::STPWpre:
5581 case AArch64::STPXpost:
5582 case AArch64::STPXpre: {
5587 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5588 "is also a source");
5590 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5591 "is also a source");
5594 case AArch64::LDRBBpre:
5595 case AArch64::LDRBpre:
5596 case AArch64::LDRHHpre:
5597 case AArch64::LDRHpre:
5598 case AArch64::LDRSBWpre:
5599 case AArch64::LDRSBXpre:
5600 case AArch64::LDRSHWpre:
5601 case AArch64::LDRSHXpre:
5602 case AArch64::LDRSWpre:
5603 case AArch64::LDRWpre:
5604 case AArch64::LDRXpre:
5605 case AArch64::LDRBBpost:
5606 case AArch64::LDRBpost:
5607 case AArch64::LDRHHpost:
5608 case AArch64::LDRHpost:
5609 case AArch64::LDRSBWpost:
5610 case AArch64::LDRSBXpost:
5611 case AArch64::LDRSHWpost:
5612 case AArch64::LDRSHXpost:
5613 case AArch64::LDRSWpost:
5614 case AArch64::LDRWpost:
5615 case AArch64::LDRXpost: {
5619 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5620 "is also a source");
5623 case AArch64::STRBBpost:
5624 case AArch64::STRBpost:
5625 case AArch64::STRHHpost:
5626 case AArch64::STRHpost:
5627 case AArch64::STRWpost:
5628 case AArch64::STRXpost:
5629 case AArch64::STRBBpre:
5630 case AArch64::STRBpre:
5631 case AArch64::STRHHpre:
5632 case AArch64::STRHpre:
5633 case AArch64::STRWpre:
5634 case AArch64::STRXpre: {
5638 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5639 "is also a source");
5642 case AArch64::STXRB:
5643 case AArch64::STXRH:
5644 case AArch64::STXRW:
5645 case AArch64::STXRX:
5646 case AArch64::STLXRB:
5647 case AArch64::STLXRH:
5648 case AArch64::STLXRW:
5649 case AArch64::STLXRX: {
5655 return Error(Loc[0],
5656 "unpredictable STXR instruction, status is also a source");
5659 case AArch64::STXPW:
5660 case AArch64::STXPX:
5661 case AArch64::STLXPW:
5662 case AArch64::STLXPX: {
5669 return Error(Loc[0],
5670 "unpredictable STXP instruction, status is also a source");
5673 case AArch64::LDRABwriteback:
5674 case AArch64::LDRAAwriteback: {
5678 return Error(Loc[0],
5679 "unpredictable LDRA instruction, writeback base"
5680 " is also a destination");
5687 case AArch64::CPYFP:
5688 case AArch64::CPYFPWN:
5689 case AArch64::CPYFPRN:
5690 case AArch64::CPYFPN:
5691 case AArch64::CPYFPWT:
5692 case AArch64::CPYFPWTWN:
5693 case AArch64::CPYFPWTRN:
5694 case AArch64::CPYFPWTN:
5695 case AArch64::CPYFPRT:
5696 case AArch64::CPYFPRTWN:
5697 case AArch64::CPYFPRTRN:
5698 case AArch64::CPYFPRTN:
5699 case AArch64::CPYFPT:
5700 case AArch64::CPYFPTWN:
5701 case AArch64::CPYFPTRN:
5702 case AArch64::CPYFPTN:
5703 case AArch64::CPYFM:
5704 case AArch64::CPYFMWN:
5705 case AArch64::CPYFMRN:
5706 case AArch64::CPYFMN:
5707 case AArch64::CPYFMWT:
5708 case AArch64::CPYFMWTWN:
5709 case AArch64::CPYFMWTRN:
5710 case AArch64::CPYFMWTN:
5711 case AArch64::CPYFMRT:
5712 case AArch64::CPYFMRTWN:
5713 case AArch64::CPYFMRTRN:
5714 case AArch64::CPYFMRTN:
5715 case AArch64::CPYFMT:
5716 case AArch64::CPYFMTWN:
5717 case AArch64::CPYFMTRN:
5718 case AArch64::CPYFMTN:
5719 case AArch64::CPYFE:
5720 case AArch64::CPYFEWN:
5721 case AArch64::CPYFERN:
5722 case AArch64::CPYFEN:
5723 case AArch64::CPYFEWT:
5724 case AArch64::CPYFEWTWN:
5725 case AArch64::CPYFEWTRN:
5726 case AArch64::CPYFEWTN:
5727 case AArch64::CPYFERT:
5728 case AArch64::CPYFERTWN:
5729 case AArch64::CPYFERTRN:
5730 case AArch64::CPYFERTN:
5731 case AArch64::CPYFET:
5732 case AArch64::CPYFETWN:
5733 case AArch64::CPYFETRN:
5734 case AArch64::CPYFETN:
5736 case AArch64::CPYPWN:
5737 case AArch64::CPYPRN:
5738 case AArch64::CPYPN:
5739 case AArch64::CPYPWT:
5740 case AArch64::CPYPWTWN:
5741 case AArch64::CPYPWTRN:
5742 case AArch64::CPYPWTN:
5743 case AArch64::CPYPRT:
5744 case AArch64::CPYPRTWN:
5745 case AArch64::CPYPRTRN:
5746 case AArch64::CPYPRTN:
5747 case AArch64::CPYPT:
5748 case AArch64::CPYPTWN:
5749 case AArch64::CPYPTRN:
5750 case AArch64::CPYPTN:
5752 case AArch64::CPYMWN:
5753 case AArch64::CPYMRN:
5754 case AArch64::CPYMN:
5755 case AArch64::CPYMWT:
5756 case AArch64::CPYMWTWN:
5757 case AArch64::CPYMWTRN:
5758 case AArch64::CPYMWTN:
5759 case AArch64::CPYMRT:
5760 case AArch64::CPYMRTWN:
5761 case AArch64::CPYMRTRN:
5762 case AArch64::CPYMRTN:
5763 case AArch64::CPYMT:
5764 case AArch64::CPYMTWN:
5765 case AArch64::CPYMTRN:
5766 case AArch64::CPYMTN:
5768 case AArch64::CPYEWN:
5769 case AArch64::CPYERN:
5770 case AArch64::CPYEN:
5771 case AArch64::CPYEWT:
5772 case AArch64::CPYEWTWN:
5773 case AArch64::CPYEWTRN:
5774 case AArch64::CPYEWTN:
5775 case AArch64::CPYERT:
5776 case AArch64::CPYERTWN:
5777 case AArch64::CPYERTRN:
5778 case AArch64::CPYERTN:
5779 case AArch64::CPYET:
5780 case AArch64::CPYETWN:
5781 case AArch64::CPYETRN:
5782 case AArch64::CPYETN: {
5793 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5794 " registers are the same");
5796 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5797 " registers are the same");
5799 return Error(Loc[0],
"invalid CPY instruction, source and size"
5800 " registers are the same");
5804 case AArch64::SETPT:
5805 case AArch64::SETPN:
5806 case AArch64::SETPTN:
5808 case AArch64::SETMT:
5809 case AArch64::SETMN:
5810 case AArch64::SETMTN:
5812 case AArch64::SETET:
5813 case AArch64::SETEN:
5814 case AArch64::SETETN:
5815 case AArch64::SETGP:
5816 case AArch64::SETGPT:
5817 case AArch64::SETGPN:
5818 case AArch64::SETGPTN:
5819 case AArch64::SETGM:
5820 case AArch64::SETGMT:
5821 case AArch64::SETGMN:
5822 case AArch64::SETGMTN:
5823 case AArch64::MOPSSETGE:
5824 case AArch64::MOPSSETGET:
5825 case AArch64::MOPSSETGEN:
5826 case AArch64::MOPSSETGETN: {
5836 return Error(Loc[0],
"invalid SET instruction, destination and size"
5837 " registers are the same");
5839 return Error(Loc[0],
"invalid SET instruction, destination and source"
5840 " registers are the same");
5842 return Error(Loc[0],
"invalid SET instruction, source and size"
5843 " registers are the same");
5846 case AArch64::SETGOP:
5847 case AArch64::SETGOPT:
5848 case AArch64::SETGOPN:
5849 case AArch64::SETGOPTN:
5850 case AArch64::SETGOM:
5851 case AArch64::SETGOMT:
5852 case AArch64::SETGOMN:
5853 case AArch64::SETGOMTN:
5854 case AArch64::SETGOE:
5855 case AArch64::SETGOET:
5856 case AArch64::SETGOEN:
5857 case AArch64::SETGOETN: {
5866 return Error(Loc[0],
"invalid SET instruction, destination and size"
5867 " registers are the same");
5876 case AArch64::ADDSWri:
5877 case AArch64::ADDSXri:
5878 case AArch64::ADDWri:
5879 case AArch64::ADDXri:
5880 case AArch64::SUBSWri:
5881 case AArch64::SUBSXri:
5882 case AArch64::SUBWri:
5883 case AArch64::SUBXri: {
5891 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5916 return Error(Loc.
back(),
"invalid immediate expression");
5929 unsigned VariantID = 0);
5931bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5935 case Match_InvalidTiedOperand: {
5936 auto &
Op =
static_cast<const AArch64Operand &
>(*Operands[
ErrorInfo]);
5937 if (
Op.isVectorList())
5938 return Error(
Loc,
"operand must match destination register list");
5940 assert(
Op.isReg() &&
"Unexpected operand type");
5941 switch (
Op.getRegEqualityTy()) {
5942 case RegConstraintEqualityTy::EqualsSubReg:
5943 return Error(
Loc,
"operand must be 64-bit form of destination register");
5944 case RegConstraintEqualityTy::EqualsSuperReg:
5945 return Error(
Loc,
"operand must be 32-bit form of destination register");
5946 case RegConstraintEqualityTy::EqualsReg:
5947 return Error(
Loc,
"operand must match destination register");
5951 case Match_MissingFeature:
5953 "instruction requires a CPU feature not currently enabled");
5954 case Match_InvalidOperand:
5955 return Error(Loc,
"invalid operand for instruction");
5956 case Match_InvalidSuffix:
5957 return Error(Loc,
"invalid type suffix for instruction");
5958 case Match_InvalidCondCode:
5959 return Error(Loc,
"expected AArch64 condition code");
5960 case Match_AddSubRegExtendSmall:
5962 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5963 case Match_AddSubRegExtendLarge:
5965 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5966 case Match_AddSubSecondSource:
5968 "expected compatible register, symbol or integer in range [0, 4095]");
5969 case Match_LogicalSecondSource:
5970 return Error(Loc,
"expected compatible register or logical immediate");
5971 case Match_InvalidMovImm32Shift:
5972 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5973 case Match_InvalidMovImm64Shift:
5974 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5975 case Match_AddSubRegShift32:
5977 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5978 case Match_AddSubRegShift64:
5980 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5981 case Match_InvalidFPImm:
5983 "expected compatible register or floating-point constant");
5984 case Match_InvalidMemoryIndexedSImm6:
5985 return Error(Loc,
"index must be an integer in range [-32, 31].");
5986 case Match_InvalidMemoryIndexedSImm5:
5987 return Error(Loc,
"index must be an integer in range [-16, 15].");
5988 case Match_InvalidMemoryIndexed1SImm4:
5989 return Error(Loc,
"index must be an integer in range [-8, 7].");
5990 case Match_InvalidMemoryIndexed2SImm4:
5991 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5992 case Match_InvalidMemoryIndexed3SImm4:
5993 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5994 case Match_InvalidMemoryIndexed4SImm4:
5995 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5996 case Match_InvalidMemoryIndexed16SImm4:
5997 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5998 case Match_InvalidMemoryIndexed32SImm4:
5999 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
6000 case Match_InvalidMemoryIndexed1SImm6:
6001 return Error(Loc,
"index must be an integer in range [-32, 31].");
6002 case Match_InvalidMemoryIndexedSImm8:
6003 return Error(Loc,
"index must be an integer in range [-128, 127].");
6004 case Match_InvalidMemoryIndexedSImm9:
6005 return Error(Loc,
"index must be an integer in range [-256, 255].");
6006 case Match_InvalidMemoryIndexed16SImm9:
6007 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
6008 case Match_InvalidMemoryIndexed8SImm10:
6009 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
6010 case Match_InvalidMemoryIndexed4SImm7:
6011 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
6012 case Match_InvalidMemoryIndexed8SImm7:
6013 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
6014 case Match_InvalidMemoryIndexed16SImm7:
6015 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
6016 case Match_InvalidMemoryIndexed8UImm5:
6017 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
6018 case Match_InvalidMemoryIndexed8UImm3:
6019 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
6020 case Match_InvalidMemoryIndexed4UImm5:
6021 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
6022 case Match_InvalidMemoryIndexed2UImm5:
6023 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
6024 case Match_InvalidMemoryIndexed8UImm6:
6025 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
6026 case Match_InvalidMemoryIndexed16UImm6:
6027 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
6028 case Match_InvalidMemoryIndexed4UImm6:
6029 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
6030 case Match_InvalidMemoryIndexed2UImm6:
6031 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
6032 case Match_InvalidMemoryIndexed1UImm6:
6033 return Error(Loc,
"index must be in range [0, 63].");
6034 case Match_InvalidMemoryWExtend8:
6036 "expected 'uxtw' or 'sxtw' with optional shift of #0");
6037 case Match_InvalidMemoryWExtend16:
6039 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
6040 case Match_InvalidMemoryWExtend32:
6042 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
6043 case Match_InvalidMemoryWExtend64:
6045 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
6046 case Match_InvalidMemoryWExtend128:
6048 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6049 case Match_InvalidMemoryXExtend8:
6051 "expected 'lsl' or 'sxtx' with optional shift of #0");
6052 case Match_InvalidMemoryXExtend16:
6054 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6055 case Match_InvalidMemoryXExtend32:
6057 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6058 case Match_InvalidMemoryXExtend64:
6060 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6061 case Match_InvalidMemoryXExtend128:
6063 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6064 case Match_InvalidMemoryIndexed1:
6065 return Error(Loc,
"index must be an integer in range [0, 4095].");
6066 case Match_InvalidMemoryIndexed2:
6067 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6068 case Match_InvalidMemoryIndexed4:
6069 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6070 case Match_InvalidMemoryIndexed8:
6071 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6072 case Match_InvalidMemoryIndexed16:
6073 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6074 case Match_InvalidImm0_0:
6075 return Error(Loc,
"immediate must be 0.");
6076 case Match_InvalidImm0_1:
6077 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6078 case Match_InvalidImm0_3:
6079 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6080 case Match_InvalidImm0_7:
6081 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6082 case Match_InvalidImm0_15:
6083 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6084 case Match_InvalidImm0_31:
6085 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6086 case Match_InvalidImm0_63:
6087 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6088 case Match_InvalidImm0_127:
6089 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6090 case Match_InvalidImm0_255:
6091 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6092 case Match_InvalidImm0_65535:
6093 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6094 case Match_InvalidHinteUImm16:
6096 "immediate must be an integer in range [0, 65535], excluding "
6097 "values in range [12319, 16383] where (value - 12319) is a "
6099 case Match_InvalidImm1_8:
6100 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6101 case Match_InvalidImm1_16:
6102 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6103 case Match_InvalidImm1_32:
6104 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6105 case Match_InvalidImm1_64:
6106 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6107 case Match_InvalidImmM1_62:
6108 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6109 case Match_InvalidMemoryIndexedRange2UImm0:
6110 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6111 case Match_InvalidMemoryIndexedRange2UImm1:
6112 return Error(Loc,
"vector select offset must be an immediate range of the "
6113 "form <immf>:<imml>, where the first "
6114 "immediate is a multiple of 2 in the range [0, 2], and "
6115 "the second immediate is immf + 1.");
6116 case Match_InvalidMemoryIndexedRange2UImm2:
6117 case Match_InvalidMemoryIndexedRange2UImm3:
6120 "vector select offset must be an immediate range of the form "
6122 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6124 "depending on the instruction, and the second immediate is immf + 1.");
6125 case Match_InvalidMemoryIndexedRange4UImm0:
6126 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6127 case Match_InvalidMemoryIndexedRange4UImm1:
6128 case Match_InvalidMemoryIndexedRange4UImm2:
6131 "vector select offset must be an immediate range of the form "
6133 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6135 "depending on the instruction, and the second immediate is immf + 3.");
6136 case Match_InvalidSVEAddSubImm8:
6137 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6138 " with a shift amount of 0");
6139 case Match_InvalidSVEAddSubImm16:
6140 case Match_InvalidSVEAddSubImm32:
6141 case Match_InvalidSVEAddSubImm64:
6142 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6143 "multiple of 256 in range [256, 65280]");
6144 case Match_InvalidSVECpyImm8:
6145 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6146 " with a shift amount of 0");
6147 case Match_InvalidSVECpyImm16:
6148 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6149 "multiple of 256 in range [-32768, 65280]");
6150 case Match_InvalidSVECpyImm32:
6151 case Match_InvalidSVECpyImm64:
6152 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6153 "multiple of 256 in range [-32768, 32512]");
6154 case Match_InvalidIndexRange0_0:
6155 return Error(Loc,
"expected lane specifier '[0]'");
6156 case Match_InvalidIndexRange1_1:
6157 return Error(Loc,
"expected lane specifier '[1]'");
6158 case Match_InvalidIndexRange0_15:
6159 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6160 case Match_InvalidIndexRange0_7:
6161 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6162 case Match_InvalidIndexRange0_3:
6163 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6164 case Match_InvalidIndexRange0_1:
6165 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6166 case Match_InvalidSVEIndexRange0_63:
6167 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6168 case Match_InvalidSVEIndexRange0_31:
6169 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6170 case Match_InvalidSVEIndexRange0_15:
6171 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6172 case Match_InvalidSVEIndexRange0_7:
6173 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6174 case Match_InvalidSVEIndexRange0_3:
6175 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6176 case Match_InvalidLabel:
6177 return Error(Loc,
"expected label or encodable integer pc offset");
6179 return Error(Loc,
"expected readable system register");
6181 case Match_InvalidSVCR:
6182 return Error(Loc,
"expected writable system register or pstate");
6183 case Match_InvalidComplexRotationEven:
6184 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6185 case Match_InvalidComplexRotationOdd:
6186 return Error(Loc,
"complex rotation must be 90 or 270.");
6187 case Match_MnemonicFail: {
6189 ((AArch64Operand &)*Operands[0]).
getToken(),
6190 ComputeAvailableFeatures(STI->getFeatureBits()));
6191 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6193 case Match_InvalidGPR64shifted8:
6194 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6195 case Match_InvalidGPR64shifted16:
6196 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6197 case Match_InvalidGPR64shifted32:
6198 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6199 case Match_InvalidGPR64shifted64:
6200 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6201 case Match_InvalidGPR64shifted128:
6203 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6204 case Match_InvalidGPR64NoXZRshifted8:
6205 return Error(Loc,
"register must be x0..x30 without shift");
6206 case Match_InvalidGPR64NoXZRshifted16:
6207 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6208 case Match_InvalidGPR64NoXZRshifted32:
6209 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6210 case Match_InvalidGPR64NoXZRshifted64:
6211 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6212 case Match_InvalidGPR64NoXZRshifted128:
6213 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6214 case Match_InvalidZPR32UXTW8:
6215 case Match_InvalidZPR32SXTW8:
6216 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6217 case Match_InvalidZPR32UXTW16:
6218 case Match_InvalidZPR32SXTW16:
6219 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6220 case Match_InvalidZPR32UXTW32:
6221 case Match_InvalidZPR32SXTW32:
6222 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6223 case Match_InvalidZPR32UXTW64:
6224 case Match_InvalidZPR32SXTW64:
6225 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6226 case Match_InvalidZPR64UXTW8:
6227 case Match_InvalidZPR64SXTW8:
6228 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6229 case Match_InvalidZPR64UXTW16:
6230 case Match_InvalidZPR64SXTW16:
6231 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6232 case Match_InvalidZPR64UXTW32:
6233 case Match_InvalidZPR64SXTW32:
6234 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6235 case Match_InvalidZPR64UXTW64:
6236 case Match_InvalidZPR64SXTW64:
6237 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6238 case Match_InvalidZPR32LSL8:
6239 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6240 case Match_InvalidZPR32LSL16:
6241 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6242 case Match_InvalidZPR32LSL32:
6243 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6244 case Match_InvalidZPR32LSL64:
6245 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6246 case Match_InvalidZPR64LSL8:
6247 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6248 case Match_InvalidZPR64LSL16:
6249 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6250 case Match_InvalidZPR64LSL32:
6251 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6252 case Match_InvalidZPR64LSL64:
6253 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6254 case Match_InvalidZPR0:
6255 return Error(Loc,
"expected register without element width suffix");
6256 case Match_InvalidZPR8:
6257 case Match_InvalidZPR16:
6258 case Match_InvalidZPR32:
6259 case Match_InvalidZPR64:
6260 case Match_InvalidZPR128:
6261 return Error(Loc,
"invalid element width");
6262 case Match_InvalidZPR_3b8:
6263 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6264 case Match_InvalidZPR_3b16:
6265 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6266 case Match_InvalidZPR_3b32:
6267 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6268 case Match_InvalidZPR_4b8:
6270 "Invalid restricted vector register, expected z0.b..z15.b");
6271 case Match_InvalidZPR_4b16:
6272 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6273 case Match_InvalidZPR_4b32:
6274 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6275 case Match_InvalidZPR_4b64:
6276 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6277 case Match_InvalidZPRMul2_Lo8:
6278 return Error(Loc,
"Invalid restricted vector register, expected even "
6279 "register in z0.b..z14.b");
6280 case Match_InvalidZPRMul2_Hi8:
6281 return Error(Loc,
"Invalid restricted vector register, expected even "
6282 "register in z16.b..z30.b");
6283 case Match_InvalidZPRMul2_Lo16:
6284 return Error(Loc,
"Invalid restricted vector register, expected even "
6285 "register in z0.h..z14.h");
6286 case Match_InvalidZPRMul2_Hi16:
6287 return Error(Loc,
"Invalid restricted vector register, expected even "
6288 "register in z16.h..z30.h");
6289 case Match_InvalidZPRMul2_Lo32:
6290 return Error(Loc,
"Invalid restricted vector register, expected even "
6291 "register in z0.s..z14.s");
6292 case Match_InvalidZPRMul2_Hi32:
6293 return Error(Loc,
"Invalid restricted vector register, expected even "
6294 "register in z16.s..z30.s");
6295 case Match_InvalidZPRMul2_Lo64:
6296 return Error(Loc,
"Invalid restricted vector register, expected even "
6297 "register in z0.d..z14.d");
6298 case Match_InvalidZPRMul2_Hi64:
6299 return Error(Loc,
"Invalid restricted vector register, expected even "
6300 "register in z16.d..z30.d");
6301 case Match_InvalidZPR_K0:
6302 return Error(Loc,
"invalid restricted vector register, expected register "
6303 "in z20..z23 or z28..z31");
6304 case Match_InvalidSVEPattern:
6305 return Error(Loc,
"invalid predicate pattern");
6306 case Match_InvalidSVEPPRorPNRAnyReg:
6307 case Match_InvalidSVEPPRorPNRBReg:
6308 case Match_InvalidSVEPredicateAnyReg:
6309 case Match_InvalidSVEPredicateBReg:
6310 case Match_InvalidSVEPredicateHReg:
6311 case Match_InvalidSVEPredicateSReg:
6312 case Match_InvalidSVEPredicateDReg:
6313 return Error(Loc,
"invalid predicate register.");
6314 case Match_InvalidSVEPredicate3bAnyReg:
6315 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6316 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6317 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6318 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6319 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6320 return Error(Loc,
"Invalid predicate register, expected PN in range "
6321 "pn8..pn15 with element suffix.");
6322 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6323 return Error(Loc,
"invalid restricted predicate-as-counter register "
6324 "expected pn8..pn15");
6325 case Match_InvalidSVEPNPredicateBReg:
6326 case Match_InvalidSVEPNPredicateHReg:
6327 case Match_InvalidSVEPNPredicateSReg:
6328 case Match_InvalidSVEPNPredicateDReg:
6329 return Error(Loc,
"Invalid predicate register, expected PN in range "
6330 "pn0..pn15 with element suffix.");
6331 case Match_InvalidSVEVecLenSpecifier:
6332 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6333 case Match_InvalidSVEPredicateListMul2x8:
6334 case Match_InvalidSVEPredicateListMul2x16:
6335 case Match_InvalidSVEPredicateListMul2x32:
6336 case Match_InvalidSVEPredicateListMul2x64:
6337 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6338 "predicate registers, where the first vector is a multiple of 2 "
6339 "and with correct element type");
6340 case Match_InvalidSVEExactFPImmOperandHalfOne:
6341 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6342 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6343 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6344 case Match_InvalidSVEExactFPImmOperandZeroOne:
6345 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6346 case Match_InvalidMatrixTileVectorH8:
6347 case Match_InvalidMatrixTileVectorV8:
6348 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6349 case Match_InvalidMatrixTileVectorH16:
6350 case Match_InvalidMatrixTileVectorV16:
6352 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6353 case Match_InvalidMatrixTileVectorH32:
6354 case Match_InvalidMatrixTileVectorV32:
6356 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6357 case Match_InvalidMatrixTileVectorH64:
6358 case Match_InvalidMatrixTileVectorV64:
6360 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6361 case Match_InvalidMatrixTileVectorH128:
6362 case Match_InvalidMatrixTileVectorV128:
6364 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6365 case Match_InvalidMatrixTile16:
6366 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6367 case Match_InvalidMatrixTile32:
6368 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6369 case Match_InvalidMatrixTile64:
6370 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6371 case Match_InvalidMatrix:
6372 return Error(Loc,
"invalid matrix operand, expected za");
6373 case Match_InvalidMatrix8:
6374 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6375 case Match_InvalidMatrix16:
6376 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6377 case Match_InvalidMatrix32:
6378 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6379 case Match_InvalidMatrix64:
6380 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6381 case Match_InvalidMatrixIndexGPR32_12_15:
6382 return Error(Loc,
"operand must be a register in range [w12, w15]");
6383 case Match_InvalidMatrixIndexGPR32_8_11:
6384 return Error(Loc,
"operand must be a register in range [w8, w11]");
6385 case Match_InvalidSVEVectorList2x8Mul2:
6386 case Match_InvalidSVEVectorList2x16Mul2:
6387 case Match_InvalidSVEVectorList2x32Mul2:
6388 case Match_InvalidSVEVectorList2x64Mul2:
6389 case Match_InvalidSVEVectorList2x128Mul2:
6390 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6391 "SVE vectors, where the first vector is a multiple of 2 "
6392 "and with matching element types");
6393 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6394 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6395 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6396 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6397 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6398 "SVE vectors in the range z0-z14, where the first vector "
6399 "is a multiple of 2 "
6400 "and with matching element types");
6401 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6402 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6403 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6404 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6406 "Invalid vector list, expected list with 2 consecutive "
6407 "SVE vectors in the range z16-z30, where the first vector "
6408 "is a multiple of 2 "
6409 "and with matching element types");
6410 case Match_InvalidSVEVectorList4x8Mul4:
6411 case Match_InvalidSVEVectorList4x16Mul4:
6412 case Match_InvalidSVEVectorList4x32Mul4:
6413 case Match_InvalidSVEVectorList4x64Mul4:
6414 case Match_InvalidSVEVectorList4x128Mul4:
6415 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6416 "SVE vectors, where the first vector is a multiple of 4 "
6417 "and with matching element types");
6418 case Match_InvalidSVEVectorList3x0_3b:
6419 return Error(Loc,
"Invalid vector list, expected list with 3 consecutive "
6420 "SVE vectors starting at z0-z7");
6421 case Match_InvalidLookupTable:
6422 return Error(Loc,
"Invalid lookup table, expected zt0");
6423 case Match_InvalidSVEVectorListStrided2x8:
6424 case Match_InvalidSVEVectorListStrided2x16:
6425 case Match_InvalidSVEVectorListStrided2x32:
6426 case Match_InvalidSVEVectorListStrided2x64:
6429 "Invalid vector list, expected list with each SVE vector in the list "
6430 "8 registers apart, and the first register in the range [z0, z7] or "
6431 "[z16, z23] and with correct element type");
6432 case Match_InvalidSVEVectorListStrided4x8:
6433 case Match_InvalidSVEVectorListStrided4x16:
6434 case Match_InvalidSVEVectorListStrided4x32:
6435 case Match_InvalidSVEVectorListStrided4x64:
6438 "Invalid vector list, expected list with each SVE vector in the list "
6439 "4 registers apart, and the first register in the range [z0, z3] or "
6440 "[z16, z19] and with correct element type");
6441 case Match_AddSubLSLImm3ShiftLarge:
6443 "expected 'lsl' with optional integer in range [0, 7]");
6451bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6455 bool MatchingInlineAsm) {
6456 assert(!Operands.
empty() &&
"Unexpected empty operand list!");
6457 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[0]);
6458 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6461 unsigned NumOperands = Operands.
size();
6463 if (NumOperands == 4 && Tok ==
"lsl") {
6464 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6465 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6466 if (Op2.isScalarReg() && Op3.isImm()) {
6472 if (getAArch64MCRegisterClass(AArch64::GPR32allRegClassID)
6474 NewOp3Val = (32 - Op3Val) & 0x1f;
6475 NewOp4Val = 31 - Op3Val;
6477 NewOp3Val = (64 - Op3Val) & 0x3f;
6478 NewOp4Val = 63 - Op3Val;
6485 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6486 Operands.
push_back(AArch64Operand::CreateImm(
6487 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6488 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6492 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6494 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6495 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
6496 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
6498 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6502 if (LSBCE && WidthCE) {
6504 uint64_t Width = WidthCE->
getValue();
6506 uint64_t RegWidth = 0;
6507 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6513 if (LSB >= RegWidth)
6514 return Error(LSBOp.getStartLoc(),
6515 "expected integer in range [0, 31]");
6516 if (Width < 1 || Width > RegWidth)
6517 return Error(WidthOp.getStartLoc(),
6518 "expected integer in range [1, 32]");
6522 ImmR = (32 - LSB) & 0x1f;
6524 ImmR = (64 - LSB) & 0x3f;
6526 uint64_t ImmS = Width - 1;
6528 if (ImmR != 0 && ImmS >= ImmR)
6529 return Error(WidthOp.getStartLoc(),
6530 "requested insert overflows register");
6535 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6536 Operands[2] = AArch64Operand::CreateReg(
6537 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6539 Operands[3] = AArch64Operand::CreateImm(
6540 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6542 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6546 }
else if (NumOperands == 5) {
6549 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6550 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6551 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6552 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6554 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6558 if (Op3CE && Op4CE) {
6559 uint64_t Op3Val = Op3CE->
getValue();
6560 uint64_t Op4Val = Op4CE->
getValue();
6562 uint64_t RegWidth = 0;
6563 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6569 if (Op3Val >= RegWidth)
6570 return Error(Op3.getStartLoc(),
6571 "expected integer in range [0, 31]");
6572 if (Op4Val < 1 || Op4Val > RegWidth)
6573 return Error(Op4.getStartLoc(),
6574 "expected integer in range [1, 32]");
6576 uint64_t NewOp3Val = 0;
6578 NewOp3Val = (32 - Op3Val) & 0x1f;
6580 NewOp3Val = (64 - Op3Val) & 0x3f;
6582 uint64_t NewOp4Val = Op4Val - 1;
6584 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6585 return Error(Op4.getStartLoc(),
6586 "requested insert overflows register");
6588 const MCExpr *NewOp3 =
6590 const MCExpr *NewOp4 =
6592 Operands[3] = AArch64Operand::CreateImm(
6593 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6594 Operands[4] = AArch64Operand::CreateImm(
6595 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6597 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6599 else if (Tok ==
"sbfiz")
6600 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6602 else if (Tok ==
"ubfiz")
6603 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6612 }
else if (NumOperands == 5 &&
6613 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6614 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6615 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6616 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
6618 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6622 if (Op3CE && Op4CE) {
6623 uint64_t Op3Val = Op3CE->
getValue();
6624 uint64_t Op4Val = Op4CE->
getValue();
6626 uint64_t RegWidth = 0;
6627 if (getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6633 if (Op3Val >= RegWidth)
6634 return Error(Op3.getStartLoc(),
6635 "expected integer in range [0, 31]");
6636 if (Op4Val < 1 || Op4Val > RegWidth)
6637 return Error(Op4.getStartLoc(),
6638 "expected integer in range [1, 32]");
6640 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6642 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6643 return Error(Op4.getStartLoc(),
6644 "requested extract overflows register");
6646 const MCExpr *NewOp4 =
6648 Operands[4] = AArch64Operand::CreateImm(
6649 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6651 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6653 else if (Tok ==
"sbfx")
6654 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6656 else if (Tok ==
"ubfx")
6657 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6670 if (getSTI().
hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6671 NumOperands == 4 && Tok ==
"movi") {
6672 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
6673 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
6674 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
6675 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6676 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6677 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6678 if (Suffix.
lower() ==
".2d" &&
6680 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6681 " correctly on this CPU, converting to equivalent movi.16b");
6683 unsigned Idx = Op1.isToken() ? 1 : 2;
6685 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6693 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6696 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6697 if (
Op.isScalarReg()) {
6699 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6700 Op.getStartLoc(),
Op.getEndLoc(),
6705 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6706 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6707 if (
Op.isScalarReg() &&
6708 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6712 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[2]);
6713 if (
Op.isScalarReg()) {
6715 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6722 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6723 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6724 if (
Op.isScalarReg() &&
6725 getAArch64MCRegisterClass(AArch64::GPR64allRegClassID)
6729 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*Operands[1]);
6730 if (
Op.isScalarReg()) {
6732 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6740 FeatureBitset MissingFeatures;
6743 unsigned MatchResult =
6744 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6745 MatchingInlineAsm, 1);
6749 if (MatchResult != Match_Success) {
6752 auto ShortFormNEONErrorInfo = ErrorInfo;
6753 auto ShortFormNEONMatchResult = MatchResult;
6754 auto ShortFormNEONMissingFeatures = MissingFeatures;
6757 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
6758 MatchingInlineAsm, 0);
6763 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6764 Operands.
size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
6765 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
6766 MatchResult = ShortFormNEONMatchResult;
6767 ErrorInfo = ShortFormNEONErrorInfo;
6768 MissingFeatures = ShortFormNEONMissingFeatures;
6772 switch (MatchResult) {
6773 case Match_Success: {
6776 NumOperands = Operands.
size();
6777 for (
unsigned i = 1; i < NumOperands; ++i)
6778 OperandLocs.
push_back(Operands[i]->getStartLoc());
6779 if (validateInstruction(Inst, IDLoc, OperandLocs))
6786 case Match_MissingFeature: {
6787 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6790 std::string
Msg =
"instruction requires:";
6791 for (
unsigned Feature : MissingFeatures) {
6797 case Match_MnemonicFail:
6798 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
6799 case Match_InvalidOperand: {
6800 SMLoc ErrorLoc = IDLoc;
6802 if (ErrorInfo != ~0ULL) {
6803 if (ErrorInfo >= Operands.
size())
6804 return Error(IDLoc,
"too few operands for instruction",
6805 SMRange(IDLoc, getTok().getLoc()));
6807 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
6808 if (ErrorLoc == SMLoc())
6813 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
6814 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
6815 MatchResult = Match_InvalidSuffix;
6817 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
6819 case Match_InvalidTiedOperand:
6820 case Match_InvalidMemoryIndexed1:
6821 case Match_InvalidMemoryIndexed2:
6822 case Match_InvalidMemoryIndexed4:
6823 case Match_InvalidMemoryIndexed8:
6824 case Match_InvalidMemoryIndexed16:
6825 case Match_InvalidCondCode:
6826 case Match_AddSubLSLImm3ShiftLarge:
6827 case Match_AddSubRegExtendSmall:
6828 case Match_AddSubRegExtendLarge:
6829 case Match_AddSubSecondSource:
6830 case Match_LogicalSecondSource:
6831 case Match_AddSubRegShift32:
6832 case Match_AddSubRegShift64:
6833 case Match_InvalidMovImm32Shift:
6834 case Match_InvalidMovImm64Shift:
6835 case Match_InvalidFPImm:
6836 case Match_InvalidMemoryWExtend8:
6837 case Match_InvalidMemoryWExtend16:
6838 case Match_InvalidMemoryWExtend32:
6839 case Match_InvalidMemoryWExtend64:
6840 case Match_InvalidMemoryWExtend128:
6841 case Match_InvalidMemoryXExtend8:
6842 case Match_InvalidMemoryXExtend16:
6843 case Match_InvalidMemoryXExtend32:
6844 case Match_InvalidMemoryXExtend64:
6845 case Match_InvalidMemoryXExtend128:
6846 case Match_InvalidMemoryIndexed1SImm4:
6847 case Match_InvalidMemoryIndexed2SImm4:
6848 case Match_InvalidMemoryIndexed3SImm4:
6849 case Match_InvalidMemoryIndexed4SImm4:
6850 case Match_InvalidMemoryIndexed1SImm6:
6851 case Match_InvalidMemoryIndexed16SImm4:
6852 case Match_InvalidMemoryIndexed32SImm4:
6853 case Match_InvalidMemoryIndexed4SImm7:
6854 case Match_InvalidMemoryIndexed8SImm7:
6855 case Match_InvalidMemoryIndexed16SImm7:
6856 case Match_InvalidMemoryIndexed8UImm5:
6857 case Match_InvalidMemoryIndexed8UImm3:
6858 case Match_InvalidMemoryIndexed4UImm5:
6859 case Match_InvalidMemoryIndexed2UImm5:
6860 case Match_InvalidMemoryIndexed1UImm6:
6861 case Match_InvalidMemoryIndexed2UImm6:
6862 case Match_InvalidMemoryIndexed4UImm6:
6863 case Match_InvalidMemoryIndexed8UImm6:
6864 case Match_InvalidMemoryIndexed16UImm6:
6865 case Match_InvalidMemoryIndexedSImm6:
6866 case Match_InvalidMemoryIndexedSImm5:
6867 case Match_InvalidMemoryIndexedSImm8:
6868 case Match_InvalidMemoryIndexedSImm9:
6869 case Match_InvalidMemoryIndexed16SImm9:
6870 case Match_InvalidMemoryIndexed8SImm10:
6871 case Match_InvalidImm0_0:
6872 case Match_InvalidImm0_1:
6873 case Match_InvalidImm0_3:
6874 case Match_InvalidImm0_7:
6875 case Match_InvalidImm0_15:
6876 case Match_InvalidImm0_31:
6877 case Match_InvalidImm0_63:
6878 case Match_InvalidImm0_127:
6879 case Match_InvalidImm0_255:
6880 case Match_InvalidImm0_65535:
6881 case Match_InvalidHinteUImm16:
6882 case Match_InvalidImm1_8:
6883 case Match_InvalidImm1_16:
6884 case Match_InvalidImm1_32:
6885 case Match_InvalidImm1_64:
6886 case Match_InvalidImmM1_62:
6887 case Match_InvalidMemoryIndexedRange2UImm0:
6888 case Match_InvalidMemoryIndexedRange2UImm1:
6889 case Match_InvalidMemoryIndexedRange2UImm2:
6890 case Match_InvalidMemoryIndexedRange2UImm3:
6891 case Match_InvalidMemoryIndexedRange4UImm0:
6892 case Match_InvalidMemoryIndexedRange4UImm1:
6893 case Match_InvalidMemoryIndexedRange4UImm2:
6894 case Match_InvalidSVEAddSubImm8:
6895 case Match_InvalidSVEAddSubImm16:
6896 case Match_InvalidSVEAddSubImm32:
6897 case Match_InvalidSVEAddSubImm64:
6898 case Match_InvalidSVECpyImm8:
6899 case Match_InvalidSVECpyImm16:
6900 case Match_InvalidSVECpyImm32:
6901 case Match_InvalidSVECpyImm64:
6902 case Match_InvalidIndexRange0_0:
6903 case Match_InvalidIndexRange1_1:
6904 case Match_InvalidIndexRange0_15:
6905 case Match_InvalidIndexRange0_7:
6906 case Match_InvalidIndexRange0_3:
6907 case Match_InvalidIndexRange0_1:
6908 case Match_InvalidSVEIndexRange0_63:
6909 case Match_InvalidSVEIndexRange0_31:
6910 case Match_InvalidSVEIndexRange0_15:
6911 case Match_InvalidSVEIndexRange0_7:
6912 case Match_InvalidSVEIndexRange0_3:
6913 case Match_InvalidLabel:
6914 case Match_InvalidComplexRotationEven:
6915 case Match_InvalidComplexRotationOdd:
6916 case Match_InvalidGPR64shifted8:
6917 case Match_InvalidGPR64shifted16:
6918 case Match_InvalidGPR64shifted32:
6919 case Match_InvalidGPR64shifted64:
6920 case Match_InvalidGPR64shifted128:
6921 case Match_InvalidGPR64NoXZRshifted8:
6922 case Match_InvalidGPR64NoXZRshifted16:
6923 case Match_InvalidGPR64NoXZRshifted32:
6924 case Match_InvalidGPR64NoXZRshifted64:
6925 case Match_InvalidGPR64NoXZRshifted128:
6926 case Match_InvalidZPR32UXTW8:
6927 case Match_InvalidZPR32UXTW16:
6928 case Match_InvalidZPR32UXTW32:
6929 case Match_InvalidZPR32UXTW64:
6930 case Match_InvalidZPR32SXTW8:
6931 case Match_InvalidZPR32SXTW16:
6932 case Match_InvalidZPR32SXTW32:
6933 case Match_InvalidZPR32SXTW64:
6934 case Match_InvalidZPR64UXTW8:
6935 case Match_InvalidZPR64SXTW8:
6936 case Match_InvalidZPR64UXTW16:
6937 case Match_InvalidZPR64SXTW16:
6938 case Match_InvalidZPR64UXTW32:
6939 case Match_InvalidZPR64SXTW32:
6940 case Match_InvalidZPR64UXTW64:
6941 case Match_InvalidZPR64SXTW64:
6942 case Match_InvalidZPR32LSL8:
6943 case Match_InvalidZPR32LSL16:
6944 case Match_InvalidZPR32LSL32:
6945 case Match_InvalidZPR32LSL64:
6946 case Match_InvalidZPR64LSL8:
6947 case Match_InvalidZPR64LSL16:
6948 case Match_InvalidZPR64LSL32:
6949 case Match_InvalidZPR64LSL64:
6950 case Match_InvalidZPR0:
6951 case Match_InvalidZPR8:
6952 case Match_InvalidZPR16:
6953 case Match_InvalidZPR32:
6954 case Match_InvalidZPR64:
6955 case Match_InvalidZPR128:
6956 case Match_InvalidZPR_3b8:
6957 case Match_InvalidZPR_3b16:
6958 case Match_InvalidZPR_3b32:
6959 case Match_InvalidZPR_4b8:
6960 case Match_InvalidZPR_4b16:
6961 case Match_InvalidZPR_4b32:
6962 case Match_InvalidZPR_4b64:
6963 case Match_InvalidSVEPPRorPNRAnyReg:
6964 case Match_InvalidSVEPPRorPNRBReg:
6965 case Match_InvalidSVEPredicateAnyReg:
6966 case Match_InvalidSVEPattern:
6967 case Match_InvalidSVEVecLenSpecifier:
6968 case Match_InvalidSVEPredicateBReg:
6969 case Match_InvalidSVEPredicateHReg:
6970 case Match_InvalidSVEPredicateSReg:
6971 case Match_InvalidSVEPredicateDReg:
6972 case Match_InvalidSVEPredicate3bAnyReg:
6973 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6974 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6975 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6976 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6977 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6978 case Match_InvalidSVEPNPredicateBReg:
6979 case Match_InvalidSVEPNPredicateHReg:
6980 case Match_InvalidSVEPNPredicateSReg:
6981 case Match_InvalidSVEPNPredicateDReg:
6982 case Match_InvalidSVEPredicateListMul2x8:
6983 case Match_InvalidSVEPredicateListMul2x16:
6984 case Match_InvalidSVEPredicateListMul2x32:
6985 case Match_InvalidSVEPredicateListMul2x64:
6986 case Match_InvalidSVEExactFPImmOperandHalfOne:
6987 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6988 case Match_InvalidSVEExactFPImmOperandZeroOne:
6989 case Match_InvalidMatrixTile16:
6990 case Match_InvalidMatrixTile32:
6991 case Match_InvalidMatrixTile64:
6992 case Match_InvalidMatrix:
6993 case Match_InvalidMatrix8:
6994 case Match_InvalidMatrix16:
6995 case Match_InvalidMatrix32:
6996 case Match_InvalidMatrix64:
6997 case Match_InvalidMatrixTileVectorH8:
6998 case Match_InvalidMatrixTileVectorH16:
6999 case Match_InvalidMatrixTileVectorH32:
7000 case Match_InvalidMatrixTileVectorH64:
7001 case Match_InvalidMatrixTileVectorH128:
7002 case Match_InvalidMatrixTileVectorV8:
7003 case Match_InvalidMatrixTileVectorV16:
7004 case Match_InvalidMatrixTileVectorV32:
7005 case Match_InvalidMatrixTileVectorV64:
7006 case Match_InvalidMatrixTileVectorV128:
7007 case Match_InvalidSVCR:
7008 case Match_InvalidMatrixIndexGPR32_12_15:
7009 case Match_InvalidMatrixIndexGPR32_8_11:
7010 case Match_InvalidLookupTable:
7011 case Match_InvalidZPRMul2_Lo8:
7012 case Match_InvalidZPRMul2_Hi8:
7013 case Match_InvalidZPRMul2_Lo16:
7014 case Match_InvalidZPRMul2_Hi16:
7015 case Match_InvalidZPRMul2_Lo32:
7016 case Match_InvalidZPRMul2_Hi32:
7017 case Match_InvalidZPRMul2_Lo64:
7018 case Match_InvalidZPRMul2_Hi64:
7019 case Match_InvalidZPR_K0:
7020 case Match_InvalidSVEVectorList2x8Mul2:
7021 case Match_InvalidSVEVectorList2x16Mul2:
7022 case Match_InvalidSVEVectorList2x32Mul2:
7023 case Match_InvalidSVEVectorList2x64Mul2:
7024 case Match_InvalidSVEVectorList2x128Mul2:
7025 case Match_InvalidSVEVectorList4x8Mul4:
7026 case Match_InvalidSVEVectorList4x16Mul4:
7027 case Match_InvalidSVEVectorList4x32Mul4:
7028 case Match_InvalidSVEVectorList4x64Mul4:
7029 case Match_InvalidSVEVectorList4x128Mul4:
7030 case Match_InvalidSVEVectorList2x8Mul2_Lo:
7031 case Match_InvalidSVEVectorList2x16Mul2_Lo:
7032 case Match_InvalidSVEVectorList2x32Mul2_Lo:
7033 case Match_InvalidSVEVectorList2x64Mul2_Lo:
7034 case Match_InvalidSVEVectorList2x8Mul2_Hi:
7035 case Match_InvalidSVEVectorList2x16Mul2_Hi:
7036 case Match_InvalidSVEVectorList2x32Mul2_Hi:
7037 case Match_InvalidSVEVectorList2x64Mul2_Hi:
7038 case Match_InvalidSVEVectorList3x0_3b:
7039 case Match_InvalidSVEVectorListStrided2x8:
7040 case Match_InvalidSVEVectorListStrided2x16:
7041 case Match_InvalidSVEVectorListStrided2x32:
7042 case Match_InvalidSVEVectorListStrided2x64:
7043 case Match_InvalidSVEVectorListStrided4x8:
7044 case Match_InvalidSVEVectorListStrided4x16:
7045 case Match_InvalidSVEVectorListStrided4x32:
7046 case Match_InvalidSVEVectorListStrided4x64:
7049 if (ErrorInfo >= Operands.
size())
7050 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*Operands.
back()).getEndLoc()));
7053 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
7054 if (ErrorLoc == SMLoc())
7056 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
7064bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7071 SMLoc Loc = DirectiveID.
getLoc();
7072 if (IDVal ==
".arch")
7073 parseDirectiveArch(Loc);
7074 else if (IDVal ==
".cpu")
7075 parseDirectiveCPU(Loc);
7076 else if (IDVal ==
".tlsdesccall")
7077 parseDirectiveTLSDescCall(Loc);
7078 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7079 parseDirectiveLtorg(Loc);
7080 else if (IDVal ==
".unreq")
7081 parseDirectiveUnreq(Loc);
7082 else if (IDVal ==
".inst")
7083 parseDirectiveInst(Loc);
7084 else if (IDVal ==
".cfi_negate_ra_state")
7085 parseDirectiveCFINegateRAState();
7086 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7087 parseDirectiveCFINegateRAStateWithPC();
7088 else if (IDVal ==
".cfi_set_ra_state")
7089 parseDirectiveCFILLVMSetRAState();
7090 else if (IDVal ==
".cfi_b_key_frame")
7091 parseDirectiveCFIBKeyFrame();
7092 else if (IDVal ==
".cfi_mte_tagged_frame")
7093 parseDirectiveCFIMTETaggedFrame();
7094 else if (IDVal ==
".arch_extension")
7095 parseDirectiveArchExtension(Loc);
7096 else if (IDVal ==
".variant_pcs")
7097 parseDirectiveVariantPCS(Loc);
7100 parseDirectiveLOH(IDVal, Loc);
7103 }
else if (IsCOFF) {
7104 if (IDVal ==
".seh_stackalloc")
7105 parseDirectiveSEHAllocStack(Loc);
7106 else if (IDVal ==
".seh_endprologue")
7107 parseDirectiveSEHPrologEnd(Loc);
7108 else if (IDVal ==
".seh_save_r19r20_x")
7109 parseDirectiveSEHSaveR19R20X(Loc);
7110 else if (IDVal ==
".seh_save_fplr")
7111 parseDirectiveSEHSaveFPLR(Loc);
7112 else if (IDVal ==
".seh_save_fplr_x")
7113 parseDirectiveSEHSaveFPLRX(Loc);
7114 else if (IDVal ==
".seh_save_reg")
7115 parseDirectiveSEHSaveReg(Loc);
7116 else if (IDVal ==
".seh_save_reg_x")
7117 parseDirectiveSEHSaveRegX(Loc);
7118 else if (IDVal ==
".seh_save_regp")
7119 parseDirectiveSEHSaveRegP(Loc);
7120 else if (IDVal ==
".seh_save_regp_x")
7121 parseDirectiveSEHSaveRegPX(Loc);
7122 else if (IDVal ==
".seh_save_lrpair")
7123 parseDirectiveSEHSaveLRPair(Loc);
7124 else if (IDVal ==
".seh_save_freg")
7125 parseDirectiveSEHSaveFReg(Loc);
7126 else if (IDVal ==
".seh_save_freg_x")
7127 parseDirectiveSEHSaveFRegX(Loc);
7128 else if (IDVal ==
".seh_save_fregp")
7129 parseDirectiveSEHSaveFRegP(Loc);
7130 else if (IDVal ==
".seh_save_fregp_x")
7131 parseDirectiveSEHSaveFRegPX(Loc);
7132 else if (IDVal ==
".seh_set_fp")
7133 parseDirectiveSEHSetFP(Loc);
7134 else if (IDVal ==
".seh_add_fp")
7135 parseDirectiveSEHAddFP(Loc);
7136 else if (IDVal ==
".seh_nop")
7137 parseDirectiveSEHNop(Loc);
7138 else if (IDVal ==
".seh_save_next")
7139 parseDirectiveSEHSaveNext(Loc);
7140 else if (IDVal ==
".seh_startepilogue")
7141 parseDirectiveSEHEpilogStart(Loc);
7142 else if (IDVal ==
".seh_endepilogue")
7143 parseDirectiveSEHEpilogEnd(Loc);
7144 else if (IDVal ==
".seh_trap_frame")
7145 parseDirectiveSEHTrapFrame(Loc);
7146 else if (IDVal ==
".seh_pushframe")
7147 parseDirectiveSEHMachineFrame(Loc);
7148 else if (IDVal ==
".seh_context")
7149 parseDirectiveSEHContext(Loc);
7150 else if (IDVal ==
".seh_ec_context")
7151 parseDirectiveSEHECContext(Loc);
7152 else if (IDVal ==
".seh_clear_unwound_to_call")
7153 parseDirectiveSEHClearUnwoundToCall(Loc);
7154 else if (IDVal ==
".seh_pac_sign_lr")
7155 parseDirectiveSEHPACSignLR(Loc);
7156 else if (IDVal ==
".seh_save_any_reg")
7157 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7158 else if (IDVal ==
".seh_save_any_reg_p")
7159 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7160 else if (IDVal ==
".seh_save_any_reg_x")
7161 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7162 else if (IDVal ==
".seh_save_any_reg_px")
7163 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7164 else if (IDVal ==
".seh_allocz")
7165 parseDirectiveSEHAllocZ(Loc);
7166 else if (IDVal ==
".seh_save_zreg")
7167 parseDirectiveSEHSaveZReg(Loc);
7168 else if (IDVal ==
".seh_save_preg")
7169 parseDirectiveSEHSavePReg(Loc);
7173 if (IDVal ==
".aeabi_subsection")
7174 parseDirectiveAeabiSubSectionHeader(Loc);
7175 else if (IDVal ==
".aeabi_attribute")
7176 parseDirectiveAeabiAArch64Attr(Loc);
7189 if (!NoCrypto && Crypto) {
7192 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7193 ArchInfo == AArch64::ARMV8_3A) {
7197 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7198 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7199 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7200 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7201 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7202 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7208 }
else if (NoCrypto) {
7211 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7212 ArchInfo == AArch64::ARMV8_3A) {
7213 RequestedExtensions.
push_back(
"nosha2");
7216 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7217 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7218 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7219 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7220 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7221 ArchInfo == AArch64::ARMV9_4A) {
7223 RequestedExtensions.
push_back(
"nosha3");
7224 RequestedExtensions.
push_back(
"nosha2");
7236bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7237 SMLoc CurLoc = getLoc();
7239 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7240 StringRef Arch, ExtensionString;
7241 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7245 return Error(CurLoc,
"unknown arch name");
7251 std::vector<StringRef> AArch64Features;
7252 AArch64Features.push_back(AArch64::StrTab[ArchInfo->
ArchFeature]);
7255 MCSubtargetInfo &STI = copySTI();
7256 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7258 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7261 if (!ExtensionString.
empty())
7262 ExtensionString.
split(RequestedExtensions,
'+');
7267 for (
auto Name : RequestedExtensions) {
7271 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7278 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7286 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7287 setAvailableFeatures(Features);
7289 getTargetStreamer().emitDirectiveArch(Name);
7295bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7296 SMLoc ExtLoc = getLoc();
7298 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7303 bool EnableFeature =
true;
7304 StringRef
Name = FullName;
7305 if (
Name.starts_with_insensitive(
"no")) {
7306 EnableFeature =
false;
7315 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7317 MCSubtargetInfo &STI = copySTI();
7322 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7323 setAvailableFeatures(Features);
7325 getTargetStreamer().emitDirectiveArchExtension(FullName);
7331bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7332 SMLoc CurLoc = getLoc();
7334 StringRef CPU, ExtensionString;
7335 std::tie(CPU, ExtensionString) =
7336 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7342 if (!ExtensionString.
empty())
7343 ExtensionString.
split(RequestedExtensions,
'+');
7347 Error(CurLoc,
"unknown CPU name");
7352 MCSubtargetInfo &STI = copySTI();
7356 for (
auto Name : RequestedExtensions) {
7360 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7367 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7375 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7376 setAvailableFeatures(Features);
7382bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7384 return Error(Loc,
"expected expression following '.inst' directive");
7386 auto parseOp = [&]() ->
bool {
7388 const MCExpr *Expr =
nullptr;
7389 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7392 if (check(!
Value, L,
"expected constant expression"))
7394 getTargetStreamer().emitInst(
Value->getValue());
7398 return parseMany(parseOp);
7403bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7405 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7417 getParser().getStreamer().emitInstruction(Inst, getSTI());
7423bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7427 return TokError(
"expected an identifier or a number in directive");
7430 int64_t
Id = getTok().getIntVal();
7432 return TokError(
"invalid numeric identifier in directive");
7435 StringRef
Name = getTok().getIdentifier();
7441 return TokError(
"invalid identifier in directive");
7449 assert(NbArgs != -1 &&
"Invalid number of arguments");
7452 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7454 if (getParser().parseIdentifier(Name))
7455 return TokError(
"expected identifier in directive");
7458 if (Idx + 1 == NbArgs)
7466 getStreamer().emitLOHDirective(Kind, Args);
7472bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7475 getTargetStreamer().emitCurrentConstantPool();
7481bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7483 SMLoc SRegLoc = getLoc();
7484 RegKind RegisterKind = RegKind::Scalar;
7486 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7490 RegisterKind = RegKind::NeonVector;
7491 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7497 return Error(SRegLoc,
"vector register without type specifier expected");
7502 RegisterKind = RegKind::SVEDataVector;
7504 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7510 return Error(SRegLoc,
7511 "sve vector register without type specifier expected");
7516 RegisterKind = RegKind::SVEPredicateVector;
7517 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7523 return Error(SRegLoc,
7524 "sve predicate register without type specifier expected");
7528 return Error(SRegLoc,
"register name or alias expected");
7534 auto pair = std::make_pair(RegisterKind, RegNum);
7535 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7536 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7543bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7545 return TokError(
"unexpected input in .unreq directive.");
7546 RegisterReqs.
erase(getTok().getIdentifier().lower());
7551bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7554 getStreamer().emitCFINegateRAState();
7558bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7561 getStreamer().emitCFINegateRAStateWithPC();
7568bool AArch64AsmParser::parseDirectiveCFILLVMSetRAState() {
7570 if (getParser().parseAbsoluteExpression(State))
7575 SMLoc ExprLoc = getLoc();
7576 if (getParser().parseExpression(Expr))
7581 getStreamer().emitCFILLVMSetRAState(
7582 (
unsigned)State,
const_cast<MCSymbol *
>(&SymRef->getSymbol()));
7584 getStreamer().emitCFILLVMSetRAState((
unsigned)State,
CE->getValue());
7588 "expected an integer offset or a symbol for .cfi_set_ra_state");
7595bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7598 getStreamer().emitCFIBKeyFrame();
7604bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7607 getStreamer().emitCFIMTETaggedFrame();
7613bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7615 if (getParser().parseIdentifier(Name))
7616 return TokError(
"expected symbol name");
7619 getTargetStreamer().emitDirectiveVariantPCS(
7626bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7628 if (parseImmExpr(
Size))
7630 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7636bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7637 getTargetStreamer().emitARM64WinCFIPrologEnd();
7643bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7645 if (parseImmExpr(
Offset))
7647 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7653bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7655 if (parseImmExpr(
Offset))
7657 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7663bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7665 if (parseImmExpr(
Offset))
7667 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7673bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7676 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7677 parseComma() || parseImmExpr(
Offset))
7679 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7685bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7688 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7689 parseComma() || parseImmExpr(
Offset))
7691 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7697bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7700 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7701 parseComma() || parseImmExpr(
Offset))
7703 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7709bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7712 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7713 parseComma() || parseImmExpr(
Offset))
7715 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7721bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7725 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7726 parseComma() || parseImmExpr(
Offset))
7728 if (check(((
Reg - 19) % 2 != 0), L,
7729 "expected register with even offset from x19"))
7731 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7737bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7740 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7741 parseComma() || parseImmExpr(
Offset))
7743 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7749bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7752 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7753 parseComma() || parseImmExpr(
Offset))
7755 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7761bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7764 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7765 parseComma() || parseImmExpr(
Offset))
7767 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7773bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7776 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7777 parseComma() || parseImmExpr(
Offset))
7779 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7785bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7786 getTargetStreamer().emitARM64WinCFISetFP();
7792bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7794 if (parseImmExpr(
Size))
7796 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7802bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7803 getTargetStreamer().emitARM64WinCFINop();
7809bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7810 getTargetStreamer().emitARM64WinCFISaveNext();
7816bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7817 getTargetStreamer().emitARM64WinCFIEpilogStart();
7823bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7824 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7830bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7831 getTargetStreamer().emitARM64WinCFITrapFrame();
7837bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7838 getTargetStreamer().emitARM64WinCFIMachineFrame();
7844bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7845 getTargetStreamer().emitARM64WinCFIContext();
7851bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7852 getTargetStreamer().emitARM64WinCFIECContext();
7858bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7859 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7865bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7866 getTargetStreamer().emitARM64WinCFIPACSignLR();
7875bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7880 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7881 parseComma() || parseImmExpr(
Offset))
7884 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7885 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7886 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7887 return Error(L,
"invalid save_any_reg offset");
7888 unsigned EncodedReg;
7889 if (
Reg == AArch64::FP)
7891 else if (
Reg == AArch64::LR)
7894 EncodedReg =
Reg - AArch64::X0;
7896 if (
Reg == AArch64::LR)
7897 return Error(Start,
"lr cannot be paired with another register");
7899 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7901 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7904 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7906 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7908 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7909 unsigned EncodedReg =
Reg - AArch64::D0;
7910 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7911 return Error(L,
"invalid save_any_reg offset");
7913 if (
Reg == AArch64::D31)
7914 return Error(Start,
"d31 cannot be paired with another register");
7916 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7918 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7921 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7923 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7925 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7926 unsigned EncodedReg =
Reg - AArch64::Q0;
7928 return Error(L,
"invalid save_any_reg offset");
7930 if (
Reg == AArch64::Q31)
7931 return Error(Start,
"q31 cannot be paired with another register");
7933 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7935 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7938 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7940 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7943 return Error(Start,
"save_any_reg register must be x, q or d register");
7950bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7952 if (parseImmExpr(
Offset))
7954 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7960bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
7965 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7968 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
7969 "expected register in range z8 to z23"))
7971 if (parseComma() || parseImmExpr(
Offset))
7973 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
7979bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
7984 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7987 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
7988 "expected register in range p4 to p15"))
7990 if (parseComma() || parseImmExpr(
Offset))
7992 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
7996bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
8002 MCAsmParser &Parser = getParser();
8005 StringRef SubsectionName;
8016 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
8017 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
8022 if (SubsectionExists) {
8023 getTargetStreamer().emitAttributesSubsection(
8026 SubsectionExists->IsOptional),
8028 SubsectionExists->ParameterType));
8034 "Could not switch to subsection '" + SubsectionName +
8035 "' using subsection name, subsection has not been defined");
8058 if (SubsectionExists) {
8059 if (IsOptional != SubsectionExists->IsOptional) {
8061 "optionality mismatch! subsection '" + SubsectionName +
8062 "' already exists with optionality defined as '" +
8064 SubsectionExists->IsOptional) +
8072 "optionality parameter not found, expected required|optional");
8079 "aeabi_feature_and_bits must be marked as optional");
8086 "aeabi_pauthabi must be marked as required");
8106 if (SubsectionExists) {
8107 if (
Type != SubsectionExists->ParameterType) {
8109 "type mismatch! subsection '" + SubsectionName +
8110 "' already exists with type defined as '" +
8112 SubsectionExists->ParameterType) +
8120 "type parameter not found, expected uleb128|ntbs");
8128 SubsectionName +
" must be marked as ULEB128");
8137 "attributes subsection header directive");
8141 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8146bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8150 MCAsmParser &Parser = getParser();
8152 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8153 getTargetStreamer().getActiveAttributesSubsection();
8154 if (
nullptr == ActiveSubsection) {
8156 "no active subsection, build attribute can not be added");
8159 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8160 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8168 ActiveSubsectionName)
8171 StringRef TagStr =
"";
8174 Tag = getTok().getIntVal();
8177 switch (ActiveSubsectionID) {
8182 "' \nExcept for public subsections, "
8183 "tags have to be an unsigned int.");
8190 TagStr +
"' for subsection '" +
8191 ActiveSubsectionName +
"'");
8199 TagStr +
"' for subsection '" +
8200 ActiveSubsectionName +
"'");
8218 unsigned ValueInt = unsigned(-1);
8219 std::string ValueStr =
"";
8224 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8227 ValueInt = getTok().getIntVal();
8232 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8240 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8251 if (0 != ValueInt && 1 != ValueInt) {
8253 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8254 "' options are 0|1");
8263 "unexpected token for AArch64 build attributes tag and value "
8264 "attribute directive");
8268 if (
unsigned(-1) != ValueInt) {
8269 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8271 if (
"" != ValueStr) {
8272 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8278bool AArch64AsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
8279 SMLoc Loc = getLoc();
8281 return TokError(
"expected '%' relocation specifier");
8282 StringRef
Identifier = getParser().getTok().getIdentifier();
8285 return TokError(
"invalid relocation specifier");
8291 const MCExpr *SubExpr;
8292 if (getParser().parseParenExpression(SubExpr,
E))
8299bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8302 return parseExprWithSpecifier(Res, EndLoc);
8304 if (getParser().parseExpression(Res))
8306 MCAsmParser &Parser = getParser();
8310 return Error(getLoc(),
"expected relocation specifier");
8313 SMLoc Loc = getLoc();
8315 if (Identifier ==
"auth")
8316 return parseAuthExpr(Res, EndLoc);
8320 if (Identifier ==
"got")
8324 return Error(Loc,
"invalid relocation specifier");
8329 return Error(Loc,
"@ specifier only allowed after a symbol");
8332 std::optional<MCBinaryExpr::Opcode> Opcode;
8340 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8351bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8352 MCAsmParser &Parser = getParser();
8354 AsmToken Tok = Parser.
getTok();
8361 return TokError(
"expected key name");
8366 return TokError(
"invalid key '" + KeyStr +
"'");
8373 return TokError(
"expected integer discriminator");
8377 return TokError(
"integer discriminator " + Twine(Discriminator) +
8378 " out of range [0, 0xFFFF]");
8381 bool UseAddressDiversity =
false;
8386 return TokError(
"expected 'addr'");
8387 UseAddressDiversity =
true;
8396 UseAddressDiversity, Ctx, Res->
getLoc());
8400bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8409 ELFSpec = AE->getSpecifier();
8410 Expr = AE->getSubExpr();
8450#define GET_REGISTER_MATCHER
8451#define GET_SUBTARGET_FEATURE_NAME
8452#define GET_MATCHER_IMPLEMENTATION
8453#define GET_MNEMONIC_SPELL_CHECKER
8454#include "AArch64GenAsmMatcher.inc"
8460 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8462 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8464 return Match_InvalidOperand;
8467 return Match_InvalidOperand;
8468 if (CE->getValue() == ExpectedVal)
8469 return Match_Success;
8470 return Match_InvalidOperand;
8475 return Match_InvalidOperand;
8481 if (
Op.isTokenEqual(
"za"))
8482 return Match_Success;
8483 return Match_InvalidOperand;
8489#define MATCH_HASH(N) \
8490 case MCK__HASH_##N: \
8491 return MatchesOpImmediate(N);
8517#define MATCH_HASH_MINUS(N) \
8518 case MCK__HASH__MINUS_##N: \
8519 return MatchesOpImmediate(-N);
8523#undef MATCH_HASH_MINUS
8527ParseStatus AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
8532 return Error(S,
"expected register");
8534 MCRegister FirstReg;
8535 ParseStatus Res = tryParseScalarRegister(FirstReg);
8537 return Error(S,
"expected first even register of a consecutive same-size "
8538 "even/odd register pair");
8540 const MCRegisterClass &WRegClass =
8541 getAArch64MCRegisterClass(AArch64::GPR32RegClassID);
8542 const MCRegisterClass &XRegClass =
8543 getAArch64MCRegisterClass(AArch64::GPR64RegClassID);
8545 bool isXReg = XRegClass.
contains(FirstReg),
8546 isWReg = WRegClass.
contains(FirstReg);
8547 if (!isXReg && !isWReg)
8548 return Error(S,
"expected first even register of a consecutive same-size "
8549 "even/odd register pair");
8551 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8554 if (FirstEncoding & 0x1)
8555 return Error(S,
"expected first even register of a consecutive same-size "
8556 "even/odd register pair");
8559 return Error(getLoc(),
"expected comma");
8564 MCRegister SecondReg;
8565 Res = tryParseScalarRegister(SecondReg);
8567 return Error(
E,
"expected second odd register of a consecutive same-size "
8568 "even/odd register pair");
8571 (isXReg && !XRegClass.
contains(SecondReg)) ||
8572 (isWReg && !WRegClass.
contains(SecondReg)))
8573 return Error(
E,
"expected second odd register of a consecutive same-size "
8574 "even/odd register pair");
8579 FirstReg, AArch64::sube64,
8580 &getAArch64MCRegisterClass(AArch64::XSeqPairsClassRegClassID));
8583 FirstReg, AArch64::sube32,
8584 &getAArch64MCRegisterClass(AArch64::WSeqPairsClassRegClassID));
8587 Operands.
push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8593template <
bool ParseShiftExtend,
bool ParseSuffix>
8594ParseStatus AArch64AsmParser::tryParseSVEDataVector(
OperandVector &Operands) {
8595 const SMLoc S = getLoc();
8601 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8606 if (ParseSuffix &&
Kind.empty())
8613 unsigned ElementWidth = KindRes->second;
8617 Operands.
push_back(AArch64Operand::CreateVectorReg(
8618 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8620 ParseStatus Res = tryParseVectorIndex(Operands);
8631 Res = tryParseOptionalShiftExtend(ExtOpnd);
8635 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8636 Operands.
push_back(AArch64Operand::CreateVectorReg(
8637 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
8638 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
8639 Ext->hasShiftExtendAmount()));
8644ParseStatus AArch64AsmParser::tryParseSVEPattern(
OperandVector &Operands) {
8645 MCAsmParser &Parser = getParser();
8647 SMLoc
SS = getLoc();
8648 const AsmToken &TokE = getTok();
8659 const MCExpr *ImmVal;
8666 return TokError(
"invalid operand for instruction");
8671 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8676 Pattern = Pat->Encoding;
8677 assert(Pattern >= 0 && Pattern < 32);
8688AArch64AsmParser::tryParseSVEVecLenSpecifier(
OperandVector &Operands) {
8690 SMLoc
SS = getLoc();
8691 const AsmToken &TokE = getTok();
8693 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8699 Pattern = Pat->Encoding;
8700 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8709ParseStatus AArch64AsmParser::tryParseGPR64x8(
OperandVector &Operands) {
8710 SMLoc
SS = getLoc();
8713 if (!tryParseScalarRegister(XReg).isSuccess())
8719 XReg, AArch64::x8sub_0,
8720 &getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID));
8723 "expected an even-numbered x-register in the range [x0,x22]");
8726 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8730ParseStatus AArch64AsmParser::tryParseImmRange(
OperandVector &Operands) {
8740 if (getParser().parseExpression(ImmF))
8750 SMLoc
E = getTok().getLoc();
8752 if (getParser().parseExpression(ImmL))
8759 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8764ParseStatus AArch64AsmParser::tryParseAdjImm0_63(
OperandVector &Operands) {
8774 if (getParser().parseExpression(Ex))
8784 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8791 Operands.
push_back(AArch64Operand::CreateImm(
static bool isGPR64(unsigned Reg, unsigned SubReg, const MachineRegisterInfo *MRI)
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(MCRegister ZReg, MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (elements, element-width) if Suffix is a valid vector kind.
constexpr EnumStringDef< FeatureBitset > ExtensionDefs[]
static unsigned matchMatrixRegName(StringRef Name)
static bool isMovPrfxable(unsigned TSFlags)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
constexpr auto ExtensionMap
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
static AArch64CC::CondCode parseCondCode(ArrayRef< MachineOperand > Cond)
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
#define BUILD_ENUM_STRINGS(Tab)
Value * getPointer(Value *Ptr)
static constexpr Value * getValue(Ty &ValueOrUse)
loop data Loop Data Prefetch
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
APInt bitcastToAPInt() const
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
void UnLex(AsmToken const &Token)
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Container class for subtarget features.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
const MCRegisterDesc & get(MCRegister Reg) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
VariantKind getKind() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
const MCSymbol * getAddSym() const
int64_t getConstant() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
LLVM_ABI std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
LLVM_ABI std::string lower() const
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI SubsectionType getTypeID(StringRef Type)
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
LLVM_ABI StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
LLVM_ABI StringRef getSubsectionTypeUnknownError()
LLVM_ABI SubsectionOptional getOptionalID(StringRef Optional)
LLVM_ABI StringRef getSubsectionOptionalUnknownError()
LLVM_ABI FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
LLVM_ABI VendorID getVendorID(StringRef const Vendor)
LLVM_ABI PauthABITags getPauthABITagsID(StringRef PauthABITag)
LLVM_ABI StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
uint32_t parseGenericRegister(StringRef Name)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static bool isSVEAddSubImm(int64_t Imm)
Returns true if Imm is valid for ADD/SUB.
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static bool isSVECpyImm(int64_t Imm)
Returns true if Imm is valid for CPY/DUP.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
Specifier parsePercentSpecifierName(StringRef)
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static int MCLOHNameToId(StringRef Name)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
std::string utostr(uint64_t X, bool isNeg=false)
static bool isValidMCLOHType(unsigned Kind)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
static MCRegister getXRegFromWReg(MCRegister Reg)
MCLOHType
Linker Optimization Hint Type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getWRegFromXReg(MCRegister Reg)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
StringTable::Offset ArchFeature
AArch64::ExtensionBitset DefaultExts
Compile-time data representation of enum entries.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
bool haveFeatures(FeatureBitset ActiveFeatures) const