72 SVEPredicateAsCounter,
78enum class MatrixKind { Array, Tile, Row, Col };
80enum RegConstraintEqualityTy {
91 StringMap<std::pair<RegKind, unsigned>> RegisterReqs;
95 static PrefixInfo CreateFromInst(
const MCInst &Inst, uint64_t TSFlags) {
98 case AArch64::MOVPRFX_ZZ:
102 case AArch64::MOVPRFX_ZPmZ_B:
103 case AArch64::MOVPRFX_ZPmZ_H:
104 case AArch64::MOVPRFX_ZPmZ_S:
105 case AArch64::MOVPRFX_ZPmZ_D:
110 "No destructive element size set for movprfx");
114 case AArch64::MOVPRFX_ZPzZ_B:
115 case AArch64::MOVPRFX_ZPzZ_H:
116 case AArch64::MOVPRFX_ZPzZ_S:
117 case AArch64::MOVPRFX_ZPzZ_D:
122 "No destructive element size set for movprfx");
133 PrefixInfo() =
default;
134 bool isActive()
const {
return Active; }
136 unsigned getElementSize()
const {
140 MCRegister getDstReg()
const {
return Dst; }
141 MCRegister getPgReg()
const {
148 bool Predicated =
false;
149 unsigned ElementSize;
154 AArch64TargetStreamer &getTargetStreamer() {
155 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
156 return static_cast<AArch64TargetStreamer &
>(TS);
159 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
165 std::string &Suggestion);
167 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
169 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
175 bool invertCondCode);
176 bool parseImmExpr(int64_t &Out);
178 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
181 bool showMatchError(SMLoc Loc,
unsigned ErrCode, uint64_t ErrorInfo,
184 bool parseDataExpr(
const MCExpr *&Res)
override;
185 bool parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc);
187 bool parseDirectiveArch(SMLoc L);
188 bool parseDirectiveArchExtension(SMLoc L);
189 bool parseDirectiveCPU(SMLoc L);
190 bool parseDirectiveInst(SMLoc L);
192 bool parseDirectiveTLSDescCall(SMLoc L);
194 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
195 bool parseDirectiveLtorg(SMLoc L);
197 bool parseDirectiveReq(StringRef Name, SMLoc L);
198 bool parseDirectiveUnreq(SMLoc L);
199 bool parseDirectiveCFINegateRAState();
200 bool parseDirectiveCFINegateRAStateWithPC();
201 bool parseDirectiveCFIBKeyFrame();
202 bool parseDirectiveCFIMTETaggedFrame();
204 bool parseDirectiveVariantPCS(SMLoc L);
206 bool parseDirectiveSEHAllocStack(SMLoc L);
207 bool parseDirectiveSEHPrologEnd(SMLoc L);
208 bool parseDirectiveSEHSaveR19R20X(SMLoc L);
209 bool parseDirectiveSEHSaveFPLR(SMLoc L);
210 bool parseDirectiveSEHSaveFPLRX(SMLoc L);
211 bool parseDirectiveSEHSaveReg(SMLoc L);
212 bool parseDirectiveSEHSaveRegX(SMLoc L);
213 bool parseDirectiveSEHSaveRegP(SMLoc L);
214 bool parseDirectiveSEHSaveRegPX(SMLoc L);
215 bool parseDirectiveSEHSaveLRPair(SMLoc L);
216 bool parseDirectiveSEHSaveFReg(SMLoc L);
217 bool parseDirectiveSEHSaveFRegX(SMLoc L);
218 bool parseDirectiveSEHSaveFRegP(SMLoc L);
219 bool parseDirectiveSEHSaveFRegPX(SMLoc L);
220 bool parseDirectiveSEHSetFP(SMLoc L);
221 bool parseDirectiveSEHAddFP(SMLoc L);
222 bool parseDirectiveSEHNop(SMLoc L);
223 bool parseDirectiveSEHSaveNext(SMLoc L);
224 bool parseDirectiveSEHEpilogStart(SMLoc L);
225 bool parseDirectiveSEHEpilogEnd(SMLoc L);
226 bool parseDirectiveSEHTrapFrame(SMLoc L);
227 bool parseDirectiveSEHMachineFrame(SMLoc L);
228 bool parseDirectiveSEHContext(SMLoc L);
229 bool parseDirectiveSEHECContext(SMLoc L);
230 bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
231 bool parseDirectiveSEHPACSignLR(SMLoc L);
232 bool parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
bool Writeback);
233 bool parseDirectiveSEHAllocZ(SMLoc L);
234 bool parseDirectiveSEHSaveZReg(SMLoc L);
235 bool parseDirectiveSEHSavePReg(SMLoc L);
236 bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
237 bool parseDirectiveAeabiAArch64Attr(SMLoc L);
239 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
240 SmallVectorImpl<SMLoc> &Loc);
241 unsigned getNumRegsForRegKind(RegKind K);
242 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
245 bool MatchingInlineAsm)
override;
249#define GET_ASSEMBLER_HEADER
250#include "AArch64GenAsmMatcher.inc"
264 template <
bool IsSVEPrefetch = false>
271 template <
bool AddFPZeroAsLiteral>
279 template <
bool ParseShiftExtend,
280 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
283 template <
bool ParseShiftExtend,
bool ParseSuffix>
285 template <RegKind RK>
289 template <RegKind VectorKind>
291 bool ExpectMatch =
false);
301 enum AArch64MatchResultTy {
302 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
303#define GET_OPERAND_DIAGNOSTIC_TYPES
304#include "AArch64GenAsmMatcher.inc"
307 bool IsWindowsArm64EC;
309 AArch64AsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
310 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
311 : MCTargetAsmParser(
Options, STI, MII) {
315 MCStreamer &S = getParser().getStreamer();
317 new AArch64TargetStreamer(S);
329 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
332 bool areEqualRegs(
const MCParsedAsmOperand &Op1,
333 const MCParsedAsmOperand &Op2)
const override;
334 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
336 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
337 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
338 SMLoc &EndLoc)
override;
339 bool ParseDirective(AsmToken DirectiveID)
override;
340 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
341 unsigned Kind)
override;
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;
506 unsigned PStateField;
512 struct MatrixRegOp MatrixReg;
513 struct MatrixTileListOp MatrixTileList;
514 struct VectorListOp VectorList;
515 struct VectorIndexOp VectorIndex;
517 struct ShiftedImmOp ShiftedImm;
518 struct ImmRangeOp ImmRange;
520 struct FPImmOp FPImm;
522 struct SysRegOp SysReg;
523 struct SysCRImmOp SysCRImm;
525 struct PSBHintOp PSBHint;
526 struct PHintOp PHint;
527 struct BTIHintOp BTIHint;
528 struct ShiftExtendOp ShiftExtend;
537 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(
K), Ctx(Ctx) {}
539 AArch64Operand(
const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(
o.Ctx) {
541 StartLoc =
o.StartLoc;
551 ShiftedImm =
o.ShiftedImm;
554 ImmRange =
o.ImmRange;
568 case k_MatrixRegister:
569 MatrixReg =
o.MatrixReg;
571 case k_MatrixTileList:
572 MatrixTileList =
o.MatrixTileList;
575 VectorList =
o.VectorList;
578 VectorIndex =
o.VectorIndex;
584 SysCRImm =
o.SysCRImm;
599 ShiftExtend =
o.ShiftExtend;
608 SMLoc getStartLoc()
const override {
return StartLoc; }
610 SMLoc getEndLoc()
const override {
return EndLoc; }
613 assert(Kind == k_Token &&
"Invalid access!");
614 return StringRef(Tok.Data, Tok.Length);
617 bool isTokenSuffix()
const {
618 assert(Kind == k_Token &&
"Invalid access!");
622 const MCExpr *
getImm()
const {
623 assert(Kind == k_Immediate &&
"Invalid access!");
627 const MCExpr *getShiftedImmVal()
const {
628 assert(Kind == k_ShiftedImm &&
"Invalid access!");
629 return ShiftedImm.Val;
632 unsigned getShiftedImmShift()
const {
633 assert(Kind == k_ShiftedImm &&
"Invalid access!");
634 return ShiftedImm.ShiftAmount;
637 unsigned getFirstImmVal()
const {
638 assert(Kind == k_ImmRange &&
"Invalid access!");
639 return ImmRange.First;
642 unsigned getLastImmVal()
const {
643 assert(Kind == k_ImmRange &&
"Invalid access!");
644 return ImmRange.Last;
648 assert(Kind == k_CondCode &&
"Invalid access!");
653 assert (Kind == k_FPImm &&
"Invalid access!");
654 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val,
true));
657 bool getFPImmIsExact()
const {
658 assert (Kind == k_FPImm &&
"Invalid access!");
659 return FPImm.IsExact;
662 unsigned getBarrier()
const {
663 assert(Kind == k_Barrier &&
"Invalid access!");
667 StringRef getBarrierName()
const {
668 assert(Kind == k_Barrier &&
"Invalid access!");
672 bool getBarriernXSModifier()
const {
673 assert(Kind == k_Barrier &&
"Invalid access!");
677 MCRegister
getReg()
const override {
678 assert(Kind == k_Register &&
"Invalid access!");
682 unsigned getMatrixReg()
const {
683 assert(Kind == k_MatrixRegister &&
"Invalid access!");
684 return MatrixReg.RegNum;
687 unsigned getMatrixElementWidth()
const {
688 assert(Kind == k_MatrixRegister &&
"Invalid access!");
689 return MatrixReg.ElementWidth;
692 MatrixKind getMatrixKind()
const {
693 assert(Kind == k_MatrixRegister &&
"Invalid access!");
694 return MatrixReg.Kind;
697 unsigned getMatrixTileListRegMask()
const {
698 assert(isMatrixTileList() &&
"Invalid access!");
699 return MatrixTileList.RegMask;
702 RegConstraintEqualityTy getRegEqualityTy()
const {
703 assert(Kind == k_Register &&
"Invalid access!");
704 return Reg.EqualityTy;
707 unsigned getVectorListStart()
const {
708 assert(Kind == k_VectorList &&
"Invalid access!");
709 return VectorList.RegNum;
712 unsigned getVectorListCount()
const {
713 assert(Kind == k_VectorList &&
"Invalid access!");
714 return VectorList.Count;
717 unsigned getVectorListStride()
const {
718 assert(Kind == k_VectorList &&
"Invalid access!");
719 return VectorList.Stride;
722 int getVectorIndex()
const {
723 assert(Kind == k_VectorIndex &&
"Invalid access!");
724 return VectorIndex.Val;
727 StringRef getSysReg()
const {
728 assert(Kind == k_SysReg &&
"Invalid access!");
729 return StringRef(SysReg.Data, SysReg.Length);
732 unsigned getSysCR()
const {
733 assert(Kind == k_SysCR &&
"Invalid access!");
737 unsigned getPrefetch()
const {
738 assert(Kind == k_Prefetch &&
"Invalid access!");
742 unsigned getPSBHint()
const {
743 assert(Kind == k_PSBHint &&
"Invalid access!");
747 unsigned getPHint()
const {
748 assert(Kind == k_PHint &&
"Invalid access!");
752 StringRef getPSBHintName()
const {
753 assert(Kind == k_PSBHint &&
"Invalid access!");
754 return StringRef(PSBHint.Data, PSBHint.Length);
757 StringRef getPHintName()
const {
758 assert(Kind == k_PHint &&
"Invalid access!");
759 return StringRef(PHint.Data, PHint.Length);
762 unsigned getBTIHint()
const {
763 assert(Kind == k_BTIHint &&
"Invalid access!");
767 StringRef getBTIHintName()
const {
768 assert(Kind == k_BTIHint &&
"Invalid access!");
769 return StringRef(BTIHint.Data, BTIHint.Length);
772 StringRef getSVCR()
const {
773 assert(Kind == k_SVCR &&
"Invalid access!");
774 return StringRef(SVCR.Data, SVCR.Length);
777 StringRef getPrefetchName()
const {
778 assert(Kind == k_Prefetch &&
"Invalid access!");
783 if (Kind == k_ShiftExtend)
784 return ShiftExtend.Type;
785 if (Kind == k_Register)
786 return Reg.ShiftExtend.Type;
790 unsigned getShiftExtendAmount()
const {
791 if (Kind == k_ShiftExtend)
792 return ShiftExtend.Amount;
793 if (Kind == k_Register)
794 return Reg.ShiftExtend.Amount;
798 bool hasShiftExtendAmount()
const {
799 if (Kind == k_ShiftExtend)
800 return ShiftExtend.HasExplicitAmount;
801 if (Kind == k_Register)
802 return Reg.ShiftExtend.HasExplicitAmount;
806 bool isImm()
const override {
return Kind == k_Immediate; }
807 bool isMem()
const override {
return false; }
809 bool isUImm6()
const {
816 return (Val >= 0 && Val < 64);
819 template <
int W
idth>
bool isSImm()
const {
820 return bool(isSImmScaled<Width, 1>());
823 template <
int Bits,
int Scale> DiagnosticPredicate isSImmScaled()
const {
824 return isImmScaled<Bits, Scale>(
true);
827 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
828 DiagnosticPredicate isUImmScaled()
const {
829 if (IsRange && isImmRange() &&
830 (getLastImmVal() != getFirstImmVal() +
Offset))
833 return isImmScaled<Bits, Scale, IsRange>(
false);
836 template <
int Bits,
int Scale,
bool IsRange = false>
837 DiagnosticPredicate isImmScaled(
bool Signed)
const {
838 if ((!isImm() && !isImmRange()) || (isImm() && IsRange) ||
839 (isImmRange() && !IsRange))
844 Val = getFirstImmVal();
852 int64_t MinVal, MaxVal;
854 int64_t Shift =
Bits - 1;
855 MinVal = (int64_t(1) << Shift) * -Scale;
856 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
859 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
862 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
868 DiagnosticPredicate isSVEPattern()
const {
875 if (Val >= 0 && Val < 32)
880 DiagnosticPredicate isSVEVecLenSpecifier()
const {
887 if (Val >= 0 && Val <= 1)
892 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
896 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
925 template <
int Scale>
bool isUImm12Offset()
const {
931 return isSymbolicUImm12Offset(
getImm());
934 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
937 template <
int N,
int M>
938 bool isImmInRange()
const {
945 return (Val >=
N && Val <= M);
950 template <
typename T>
951 bool isLogicalImm()
const {
960 uint64_t
Upper = UINT64_C(-1) << (
sizeof(
T) * 4) << (
sizeof(
T) * 4);
968 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
970 bool isImmRange()
const {
return Kind == k_ImmRange; }
975 template <
unsigned W
idth>
976 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
977 if (isShiftedImm() && Width == getShiftedImmShift())
979 return std::make_pair(
CE->getValue(), Width);
983 int64_t Val =
CE->getValue();
984 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
985 return std::make_pair(Val >> Width, Width);
987 return std::make_pair(Val, 0u);
993 bool isAddSubImm()
const {
994 if (!isShiftedImm() && !isImm())
1000 if (isShiftedImm()) {
1001 unsigned Shift = ShiftedImm.ShiftAmount;
1002 Expr = ShiftedImm.Val;
1003 if (Shift != 0 && Shift != 12)
1012 if (AArch64AsmParser::classifySymbolRef(Expr, ELFSpec, DarwinSpec,
1028 if (
auto ShiftedVal = getShiftedVal<12>())
1029 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1036 bool isAddSubImmNeg()
const {
1037 if (!isShiftedImm() && !isImm())
1041 if (
auto ShiftedVal = getShiftedVal<12>())
1042 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1052 template <
typename T>
1053 DiagnosticPredicate isSVECpyImm()
const {
1057 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1058 std::is_same<int8_t, T>::value;
1059 if (
auto ShiftedImm = getShiftedVal<8>())
1060 if (!(IsByte && ShiftedImm->second) &&
1062 << ShiftedImm->second))
1071 template <
typename T> DiagnosticPredicate isSVEAddSubImm()
const {
1075 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>::value ||
1076 std::is_same<int8_t, T>::value;
1077 if (
auto ShiftedImm = getShiftedVal<8>())
1078 if (!(IsByte && ShiftedImm->second) &&
1080 << ShiftedImm->second))
1086 template <
typename T> DiagnosticPredicate isSVEPreferredLogicalImm()
const {
1087 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1092 bool isCondCode()
const {
return Kind == k_CondCode; }
1094 bool isSIMDImmType10()
const {
1104 bool isBranchTarget()
const {
1113 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1114 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1124 if (!AArch64AsmParser::classifySymbolRef(
getImm(), ELFSpec, DarwinSpec,
1134 bool isMovWSymbolG3()
const {
1138 bool isMovWSymbolG2()
const {
1145 bool isMovWSymbolG1()
const {
1153 bool isMovWSymbolG0()
const {
1161 template<
int RegW
idth,
int Shift>
1162 bool isMOVZMovAlias()
const {
1163 if (!isImm())
return false;
1167 uint64_t
Value =
CE->getValue();
1176 template<
int RegW
idth,
int Shift>
1177 bool isMOVNMovAlias()
const {
1178 if (!isImm())
return false;
1181 if (!CE)
return false;
1182 uint64_t
Value =
CE->getValue();
1187 bool isFPImm()
const {
1188 return Kind == k_FPImm &&
1192 bool isBarrier()
const {
1193 return Kind == k_Barrier && !getBarriernXSModifier();
1195 bool isBarriernXS()
const {
1196 return Kind == k_Barrier && getBarriernXSModifier();
1198 bool isSysReg()
const {
return Kind == k_SysReg; }
1200 bool isMRSSystemRegister()
const {
1201 if (!isSysReg())
return false;
1203 return SysReg.MRSReg != -1U;
1206 bool isMSRSystemRegister()
const {
1207 if (!isSysReg())
return false;
1208 return SysReg.MSRReg != -1U;
1211 bool isSystemPStateFieldWithImm0_1()
const {
1212 if (!isSysReg())
return false;
1213 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1216 bool isSystemPStateFieldWithImm0_15()
const {
1219 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1222 bool isSVCR()
const {
1225 return SVCR.PStateField != -1U;
1228 bool isReg()
const override {
1229 return Kind == k_Register;
1232 bool isVectorList()
const {
return Kind == k_VectorList; }
1234 bool isScalarReg()
const {
1235 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1238 bool isNeonVectorReg()
const {
1239 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1242 bool isNeonVectorRegLo()
const {
1243 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1244 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1246 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1250 bool isNeonVectorReg0to7()
const {
1251 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1252 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1256 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1257 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1259 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
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::SVEPredicateAsCounter;
1274 return (Kind == k_Register &&
Reg.Kind == RK) &&
1275 AArch64MCRegisterClasses[
Class].contains(
getReg());
1278 template <
unsigned Class>
bool isSVEVectorReg()
const {
1281 case AArch64::ZPRRegClassID:
1282 case AArch64::ZPR_3bRegClassID:
1283 case AArch64::ZPR_4bRegClassID:
1284 case AArch64::ZPRMul2_LoRegClassID:
1285 case AArch64::ZPRMul2_HiRegClassID:
1286 case AArch64::ZPR_KRegClassID:
1287 RK = RegKind::SVEDataVector;
1289 case AArch64::PPRRegClassID:
1290 case AArch64::PPR_3bRegClassID:
1291 case AArch64::PPR_p8to15RegClassID:
1292 case AArch64::PNRRegClassID:
1293 case AArch64::PNR_p8to15RegClassID:
1294 case AArch64::PPRorPNRRegClassID:
1295 RK = RegKind::SVEPredicateVector;
1301 return (Kind == k_Register &&
Reg.Kind == RK) &&
1302 AArch64MCRegisterClasses[
Class].contains(
getReg());
1305 template <
unsigned Class>
bool isFPRasZPR()
const {
1306 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1307 AArch64MCRegisterClasses[
Class].contains(
getReg());
1310 template <
int ElementW
idth,
unsigned Class>
1311 DiagnosticPredicate isSVEPredicateVectorRegOfWidth()
const {
1312 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1315 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1321 template <
int ElementW
idth,
unsigned Class>
1322 DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth()
const {
1323 if (Kind != k_Register || (
Reg.Kind != RegKind::SVEPredicateAsCounter &&
1324 Reg.Kind != RegKind::SVEPredicateVector))
1327 if ((isSVEPredicateAsCounterReg<Class>() ||
1328 isSVEPredicateVectorRegOfWidth<ElementWidth, Class>()) &&
1329 Reg.ElementWidth == ElementWidth)
1335 template <
int ElementW
idth,
unsigned Class>
1336 DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth()
const {
1337 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1340 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1346 template <
int ElementW
idth,
unsigned Class>
1347 DiagnosticPredicate isSVEDataVectorRegOfWidth()
const {
1348 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1351 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1357 template <
int ElementWidth,
unsigned Class,
1359 bool ShiftWidthAlwaysSame>
1360 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend()
const {
1361 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1362 if (!VectorMatch.isMatch())
1368 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1371 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1374 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1380 bool isGPR32as64()
const {
1381 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1382 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1385 bool isGPR64as32()
const {
1386 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1387 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1390 bool isGPR64x8()
const {
1391 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1392 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1396 bool isWSeqPair()
const {
1397 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1398 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1402 bool isXSeqPair()
const {
1403 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1404 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1408 bool isSyspXzrPair()
const {
1409 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1412 template<
int64_t Angle,
int64_t Remainder>
1413 DiagnosticPredicate isComplexRotation()
const {
1420 uint64_t
Value =
CE->getValue();
1422 if (
Value % Angle == Remainder &&
Value <= 270)
1427 template <
unsigned RegClassID>
bool isGPR64()
const {
1428 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1429 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1432 template <
unsigned RegClassID,
int ExtW
idth>
1433 DiagnosticPredicate isGPR64WithShiftExtend()
const {
1434 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1437 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1438 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1445 template <RegKind VectorKind,
unsigned NumRegs,
bool IsConsecutive = false>
1446 bool isImplicitlyTypedVectorList()
const {
1447 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1448 VectorList.NumElements == 0 &&
1449 VectorList.RegisterKind == VectorKind &&
1450 (!IsConsecutive || (VectorList.Stride == 1));
1453 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1454 unsigned ElementWidth,
unsigned Stride = 1>
1455 bool isTypedVectorList()
const {
1456 if (Kind != k_VectorList)
1458 if (VectorList.Count != NumRegs)
1460 if (VectorList.RegisterKind != VectorKind)
1462 if (VectorList.ElementWidth != ElementWidth)
1464 if (VectorList.Stride != Stride)
1466 return VectorList.NumElements == NumElements;
1469 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1470 unsigned ElementWidth,
unsigned RegClass>
1471 DiagnosticPredicate isTypedVectorListMultiple()
const {
1473 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1476 if (!AArch64MCRegisterClasses[RegClass].
contains(VectorList.RegNum))
1481 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1482 unsigned ElementWidth>
1483 DiagnosticPredicate isTypedVectorListStrided()
const {
1484 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1485 ElementWidth, Stride>();
1488 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1489 ((VectorList.RegNum >= AArch64::Z16) &&
1490 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1495 template <
int Min,
int Max>
1496 DiagnosticPredicate isVectorIndex()
const {
1497 if (Kind != k_VectorIndex)
1499 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1504 bool isToken()
const override {
return Kind == k_Token; }
1506 bool isTokenEqual(StringRef Str)
const {
1507 return Kind == k_Token &&
getToken() == Str;
1509 bool isSysCR()
const {
return Kind == k_SysCR; }
1510 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1511 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1512 bool isPHint()
const {
return Kind == k_PHint; }
1513 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1514 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1515 bool isShifter()
const {
1516 if (!isShiftExtend())
1525 template <
unsigned ImmEnum> DiagnosticPredicate isExactFPImm()
const {
1526 if (Kind != k_FPImm)
1529 if (getFPImmIsExact()) {
1531 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1535 APFloat RealVal(APFloat::IEEEdouble());
1537 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1538 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1541 if (
getFPImm().bitwiseIsEqual(RealVal))
1548 template <
unsigned ImmA,
unsigned ImmB>
1549 DiagnosticPredicate isExactFPImm()
const {
1551 if ((Res = isExactFPImm<ImmA>()))
1553 if ((Res = isExactFPImm<ImmB>()))
1558 bool isExtend()
const {
1559 if (!isShiftExtend())
1568 getShiftExtendAmount() <= 4;
1571 bool isExtend64()
const {
1581 bool isExtendLSL64()
const {
1587 getShiftExtendAmount() <= 4;
1590 bool isLSLImm3Shift()
const {
1591 if (!isShiftExtend())
1597 template<
int W
idth>
bool isMemXExtend()
const {
1602 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1603 getShiftExtendAmount() == 0);
1606 template<
int W
idth>
bool isMemWExtend()
const {
1611 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1612 getShiftExtendAmount() == 0);
1615 template <
unsigned w
idth>
1616 bool isArithmeticShifter()
const {
1626 template <
unsigned w
idth>
1627 bool isLogicalShifter()
const {
1635 getShiftExtendAmount() < width;
1638 bool isMovImm32Shifter()
const {
1646 uint64_t Val = getShiftExtendAmount();
1647 return (Val == 0 || Val == 16);
1650 bool isMovImm64Shifter()
const {
1658 uint64_t Val = getShiftExtendAmount();
1659 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1662 bool isLogicalVecShifter()
const {
1667 unsigned Shift = getShiftExtendAmount();
1669 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1672 bool isLogicalVecHalfWordShifter()
const {
1673 if (!isLogicalVecShifter())
1677 unsigned Shift = getShiftExtendAmount();
1679 (Shift == 0 || Shift == 8);
1682 bool isMoveVecShifter()
const {
1683 if (!isShiftExtend())
1687 unsigned Shift = getShiftExtendAmount();
1689 (Shift == 8 || Shift == 16);
1698 bool isSImm9OffsetFB()
const {
1699 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1702 bool isAdrpLabel()
const {
1709 int64_t Val =
CE->getValue();
1710 int64_t Min = - (4096 * (1LL << (21 - 1)));
1711 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1712 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1718 bool isAdrLabel()
const {
1725 int64_t Val =
CE->getValue();
1726 int64_t Min = - (1LL << (21 - 1));
1727 int64_t
Max = ((1LL << (21 - 1)) - 1);
1728 return Val >= Min && Val <=
Max;
1734 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1735 DiagnosticPredicate isMatrixRegOperand()
const {
1738 if (getMatrixKind() != Kind ||
1739 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1740 EltSize != getMatrixElementWidth())
1745 bool isPAuthPCRelLabel16Operand()
const {
1757 return (Val <= 0) && (Val > -(1 << 18));
1760 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
1770 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1771 assert(
N == 1 &&
"Invalid number of operands!");
1775 void addMatrixOperands(MCInst &Inst,
unsigned N)
const {
1776 assert(
N == 1 &&
"Invalid number of operands!");
1780 void addGPR32as64Operands(MCInst &Inst,
unsigned N)
const {
1781 assert(
N == 1 &&
"Invalid number of operands!");
1783 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1785 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1792 void addGPR64as32Operands(MCInst &Inst,
unsigned N)
const {
1793 assert(
N == 1 &&
"Invalid number of operands!");
1795 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1797 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1804 template <
int W
idth>
1805 void addFPRasZPRRegOperands(MCInst &Inst,
unsigned N)
const {
1808 case 8:
Base = AArch64::B0;
break;
1809 case 16:
Base = AArch64::H0;
break;
1810 case 32:
Base = AArch64::S0;
break;
1811 case 64:
Base = AArch64::D0;
break;
1812 case 128:
Base = AArch64::Q0;
break;
1819 void addPPRorPNRRegOperands(MCInst &Inst,
unsigned N)
const {
1820 assert(
N == 1 &&
"Invalid number of operands!");
1823 if (
Reg >= AArch64::PN0 &&
Reg <= AArch64::PN15)
1824 Reg =
Reg - AArch64::PN0 + AArch64::P0;
1828 void addPNRasPPRRegOperands(MCInst &Inst,
unsigned N)
const {
1829 assert(
N == 1 &&
"Invalid number of operands!");
1834 void addVectorReg64Operands(MCInst &Inst,
unsigned N)
const {
1835 assert(
N == 1 &&
"Invalid number of operands!");
1837 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1841 void addVectorReg128Operands(MCInst &Inst,
unsigned N)
const {
1842 assert(
N == 1 &&
"Invalid number of operands!");
1844 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1848 void addVectorRegLoOperands(MCInst &Inst,
unsigned N)
const {
1849 assert(
N == 1 &&
"Invalid number of operands!");
1853 void addVectorReg0to7Operands(MCInst &Inst,
unsigned N)
const {
1854 assert(
N == 1 &&
"Invalid number of operands!");
1858 enum VecListIndexType {
1859 VecListIdx_DReg = 0,
1860 VecListIdx_QReg = 1,
1861 VecListIdx_ZReg = 2,
1862 VecListIdx_PReg = 3,
1865 template <VecListIndexType RegTy,
unsigned NumRegs,
1866 bool IsConsecutive =
false>
1867 void addVectorListOperands(MCInst &Inst,
unsigned N)
const {
1868 assert(
N == 1 &&
"Invalid number of operands!");
1869 assert((!IsConsecutive || (getVectorListStride() == 1)) &&
1870 "Expected consecutive registers");
1871 static const unsigned FirstRegs[][5] = {
1873 AArch64::D0, AArch64::D0_D1,
1874 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1876 AArch64::Q0, AArch64::Q0_Q1,
1877 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1879 AArch64::Z0, AArch64::Z0_Z1,
1880 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1882 AArch64::P0, AArch64::P0_P1 }
1885 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1886 " NumRegs must be <= 4 for ZRegs");
1888 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1889 " NumRegs must be <= 2 for PRegs");
1891 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1893 FirstRegs[(
unsigned)RegTy][0]));
1896 template <
unsigned NumRegs>
1897 void addStridedVectorListOperands(MCInst &Inst,
unsigned N)
const {
1898 assert(
N == 1 &&
"Invalid number of operands!");
1899 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1903 if (getVectorListStart() < AArch64::Z16) {
1904 assert((getVectorListStart() < AArch64::Z8) &&
1905 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1907 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1909 assert((getVectorListStart() < AArch64::Z24) &&
1910 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1912 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1916 if (getVectorListStart() < AArch64::Z16) {
1917 assert((getVectorListStart() < AArch64::Z4) &&
1918 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1920 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1922 assert((getVectorListStart() < AArch64::Z20) &&
1923 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1925 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1933 void addMatrixTileListOperands(MCInst &Inst,
unsigned N)
const {
1934 assert(
N == 1 &&
"Invalid number of operands!");
1935 unsigned RegMask = getMatrixTileListRegMask();
1936 assert(RegMask <= 0xFF &&
"Invalid mask!");
1940 void addVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
1941 assert(
N == 1 &&
"Invalid number of operands!");
1945 template <
unsigned ImmIs0,
unsigned ImmIs1>
1946 void addExactFPImmOperands(MCInst &Inst,
unsigned N)
const {
1947 assert(
N == 1 &&
"Invalid number of operands!");
1948 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1952 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1953 assert(
N == 1 &&
"Invalid number of operands!");
1960 template <
int Shift>
1961 void addImmWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1962 assert(
N == 2 &&
"Invalid number of operands!");
1963 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1966 }
else if (isShiftedImm()) {
1967 addExpr(Inst, getShiftedImmVal());
1975 template <
int Shift>
1976 void addImmNegWithOptionalShiftOperands(MCInst &Inst,
unsigned N)
const {
1977 assert(
N == 2 &&
"Invalid number of operands!");
1978 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1985 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
1986 assert(
N == 1 &&
"Invalid number of operands!");
1990 void addAdrpLabelOperands(MCInst &Inst,
unsigned N)
const {
1991 assert(
N == 1 &&
"Invalid number of operands!");
1999 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2000 addImmOperands(Inst,
N);
2004 void addUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
2005 assert(
N == 1 &&
"Invalid number of operands!");
2015 void addUImm6Operands(MCInst &Inst,
unsigned N)
const {
2016 assert(
N == 1 &&
"Invalid number of operands!");
2021 template <
int Scale>
2022 void addImmScaledOperands(MCInst &Inst,
unsigned N)
const {
2023 assert(
N == 1 &&
"Invalid number of operands!");
2028 template <
int Scale>
2029 void addImmScaledRangeOperands(MCInst &Inst,
unsigned N)
const {
2030 assert(
N == 1 &&
"Invalid number of operands!");
2034 template <
typename T>
2035 void addLogicalImmOperands(MCInst &Inst,
unsigned N)
const {
2036 assert(
N == 1 &&
"Invalid number of operands!");
2038 std::make_unsigned_t<T> Val = MCE->
getValue();
2043 template <
typename T>
2044 void addLogicalImmNotOperands(MCInst &Inst,
unsigned N)
const {
2045 assert(
N == 1 &&
"Invalid number of operands!");
2047 std::make_unsigned_t<T> Val = ~MCE->getValue();
2052 void addSIMDImmType10Operands(MCInst &Inst,
unsigned N)
const {
2053 assert(
N == 1 &&
"Invalid number of operands!");
2059 void addBranchTarget26Operands(MCInst &Inst,
unsigned N)
const {
2063 assert(
N == 1 &&
"Invalid number of operands!");
2069 assert(MCE &&
"Invalid constant immediate operand!");
2073 void addPAuthPCRelLabel16Operands(MCInst &Inst,
unsigned N)
const {
2077 assert(
N == 1 &&
"Invalid number of operands!");
2086 void addPCRelLabel19Operands(MCInst &Inst,
unsigned N)
const {
2090 assert(
N == 1 &&
"Invalid number of operands!");
2096 assert(MCE &&
"Invalid constant immediate operand!");
2100 void addPCRelLabel9Operands(MCInst &Inst,
unsigned N)
const {
2104 assert(
N == 1 &&
"Invalid number of operands!");
2110 assert(MCE &&
"Invalid constant immediate operand!");
2114 void addBranchTarget14Operands(MCInst &Inst,
unsigned N)
const {
2118 assert(
N == 1 &&
"Invalid number of operands!");
2124 assert(MCE &&
"Invalid constant immediate operand!");
2128 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2129 assert(
N == 1 &&
"Invalid number of operands!");
2134 void addBarrierOperands(MCInst &Inst,
unsigned N)
const {
2135 assert(
N == 1 &&
"Invalid number of operands!");
2139 void addBarriernXSOperands(MCInst &Inst,
unsigned N)
const {
2140 assert(
N == 1 &&
"Invalid number of operands!");
2144 void addMRSSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2145 assert(
N == 1 &&
"Invalid number of operands!");
2150 void addMSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
2151 assert(
N == 1 &&
"Invalid number of operands!");
2156 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst,
unsigned N)
const {
2157 assert(
N == 1 &&
"Invalid number of operands!");
2162 void addSVCROperands(MCInst &Inst,
unsigned N)
const {
2163 assert(
N == 1 &&
"Invalid number of operands!");
2168 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst,
unsigned N)
const {
2169 assert(
N == 1 &&
"Invalid number of operands!");
2174 void addSysCROperands(MCInst &Inst,
unsigned N)
const {
2175 assert(
N == 1 &&
"Invalid number of operands!");
2179 void addPrefetchOperands(MCInst &Inst,
unsigned N)
const {
2180 assert(
N == 1 &&
"Invalid number of operands!");
2184 void addPSBHintOperands(MCInst &Inst,
unsigned N)
const {
2185 assert(
N == 1 &&
"Invalid number of operands!");
2189 void addPHintOperands(MCInst &Inst,
unsigned N)
const {
2190 assert(
N == 1 &&
"Invalid number of operands!");
2194 void addBTIHintOperands(MCInst &Inst,
unsigned N)
const {
2195 assert(
N == 1 &&
"Invalid number of operands!");
2199 void addShifterOperands(MCInst &Inst,
unsigned N)
const {
2200 assert(
N == 1 &&
"Invalid number of operands!");
2206 void addLSLImm3ShifterOperands(MCInst &Inst,
unsigned N)
const {
2207 assert(
N == 1 &&
"Invalid number of operands!");
2208 unsigned Imm = getShiftExtendAmount();
2212 void addSyspXzrPairOperand(MCInst &Inst,
unsigned N)
const {
2213 assert(
N == 1 &&
"Invalid number of operands!");
2218 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2221 if (
Reg != AArch64::XZR)
2227 void addExtendOperands(MCInst &Inst,
unsigned N)
const {
2228 assert(
N == 1 &&
"Invalid number of operands!");
2235 void addExtend64Operands(MCInst &Inst,
unsigned N)
const {
2236 assert(
N == 1 &&
"Invalid number of operands!");
2243 void addMemExtendOperands(MCInst &Inst,
unsigned N)
const {
2244 assert(
N == 2 &&
"Invalid number of operands!");
2255 void addMemExtend8Operands(MCInst &Inst,
unsigned N)
const {
2256 assert(
N == 2 &&
"Invalid number of operands!");
2264 void addMOVZMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2265 assert(
N == 1 &&
"Invalid number of operands!");
2269 uint64_t
Value =
CE->getValue();
2277 void addMOVNMovAliasOperands(MCInst &Inst,
unsigned N)
const {
2278 assert(
N == 1 &&
"Invalid number of operands!");
2281 uint64_t
Value =
CE->getValue();
2285 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
2286 assert(
N == 1 &&
"Invalid number of operands!");
2291 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
2292 assert(
N == 1 &&
"Invalid number of operands!");
2297 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
2299 static std::unique_ptr<AArch64Operand>
2300 CreateToken(StringRef Str, SMLoc S, MCContext &Ctx,
bool IsSuffix =
false) {
2301 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2302 Op->Tok.Data = Str.data();
2303 Op->Tok.Length = Str.size();
2304 Op->Tok.IsSuffix = IsSuffix;
2310 static std::unique_ptr<AArch64Operand>
2311 CreateReg(
unsigned RegNum, RegKind Kind, SMLoc S, SMLoc
E, MCContext &Ctx,
2312 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2314 unsigned ShiftAmount = 0,
2315 unsigned HasExplicitAmount =
false) {
2316 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2317 Op->Reg.RegNum = RegNum;
2318 Op->Reg.Kind = Kind;
2319 Op->Reg.ElementWidth = 0;
2320 Op->Reg.EqualityTy = EqTy;
2321 Op->Reg.ShiftExtend.Type = ExtTy;
2322 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2323 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2329 static std::unique_ptr<AArch64Operand>
2330 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2331 SMLoc S, SMLoc
E, MCContext &Ctx,
2333 unsigned ShiftAmount = 0,
2334 unsigned HasExplicitAmount =
false) {
2335 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2336 Kind == RegKind::SVEPredicateVector ||
2337 Kind == RegKind::SVEPredicateAsCounter) &&
2338 "Invalid vector kind");
2339 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2341 Op->Reg.ElementWidth = ElementWidth;
2345 static std::unique_ptr<AArch64Operand>
2346 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2347 unsigned NumElements,
unsigned ElementWidth,
2348 RegKind RegisterKind, SMLoc S, SMLoc
E, MCContext &Ctx) {
2349 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2350 Op->VectorList.RegNum = RegNum;
2352 Op->VectorList.Stride = Stride;
2353 Op->VectorList.NumElements = NumElements;
2354 Op->VectorList.ElementWidth = ElementWidth;
2355 Op->VectorList.RegisterKind = RegisterKind;
2361 static std::unique_ptr<AArch64Operand>
2362 CreateVectorIndex(
int Idx, SMLoc S, SMLoc
E, MCContext &Ctx) {
2363 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2364 Op->VectorIndex.Val = Idx;
2370 static std::unique_ptr<AArch64Operand>
2371 CreateMatrixTileList(
unsigned RegMask, SMLoc S, SMLoc
E, MCContext &Ctx) {
2372 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2373 Op->MatrixTileList.RegMask = RegMask;
2379 static void ComputeRegsForAlias(
unsigned Reg, SmallSet<unsigned, 8> &OutRegs,
2380 const unsigned ElementWidth) {
2381 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2383 {{0, AArch64::ZAB0},
2384 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2385 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2386 {{8, AArch64::ZAB0},
2387 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2388 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2389 {{16, AArch64::ZAH0},
2390 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2391 {{16, AArch64::ZAH1},
2392 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2393 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2394 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2395 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2396 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2399 if (ElementWidth == 64)
2402 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2403 assert(!Regs.empty() &&
"Invalid tile or element width!");
2408 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val, SMLoc S,
2409 SMLoc
E, MCContext &Ctx) {
2410 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2417 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2418 unsigned ShiftAmount,
2421 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2422 Op->ShiftedImm .Val = Val;
2423 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2429 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2430 unsigned Last, SMLoc S,
2433 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2435 Op->ImmRange.Last =
Last;
2440 static std::unique_ptr<AArch64Operand>
2442 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2443 Op->CondCode.Code =
Code;
2449 static std::unique_ptr<AArch64Operand>
2450 CreateFPImm(APFloat Val,
bool IsExact, SMLoc S, MCContext &Ctx) {
2451 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2453 Op->FPImm.IsExact = IsExact;
2459 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2463 bool HasnXSModifier) {
2464 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2465 Op->Barrier.Val = Val;
2466 Op->Barrier.Data = Str.data();
2467 Op->Barrier.Length = Str.size();
2468 Op->Barrier.HasnXSModifier = HasnXSModifier;
2474 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
2477 uint32_t PStateField,
2479 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2480 Op->SysReg.Data = Str.data();
2481 Op->SysReg.Length = Str.size();
2482 Op->SysReg.MRSReg = MRSReg;
2483 Op->SysReg.MSRReg = MSRReg;
2484 Op->SysReg.PStateField = PStateField;
2490 static std::unique_ptr<AArch64Operand>
2491 CreatePHintInst(
unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
2492 auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
2493 Op->PHint.Val = Val;
2494 Op->PHint.Data = Str.data();
2495 Op->PHint.Length = Str.size();
2501 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val, SMLoc S,
2502 SMLoc
E, MCContext &Ctx) {
2503 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2504 Op->SysCRImm.Val = Val;
2510 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2514 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2515 Op->Prefetch.Val = Val;
2516 Op->Barrier.Data = Str.data();
2517 Op->Barrier.Length = Str.size();
2523 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2527 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2528 Op->PSBHint.Val = Val;
2529 Op->PSBHint.Data = Str.data();
2530 Op->PSBHint.Length = Str.size();
2536 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2540 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2541 Op->BTIHint.Val = Val | 32;
2542 Op->BTIHint.Data = Str.data();
2543 Op->BTIHint.Length = Str.size();
2549 static std::unique_ptr<AArch64Operand>
2550 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2551 SMLoc S, SMLoc
E, MCContext &Ctx) {
2552 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2553 Op->MatrixReg.RegNum = RegNum;
2554 Op->MatrixReg.ElementWidth = ElementWidth;
2555 Op->MatrixReg.Kind = Kind;
2561 static std::unique_ptr<AArch64Operand>
2562 CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
2563 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2564 Op->SVCR.PStateField = PStateField;
2565 Op->SVCR.Data = Str.data();
2566 Op->SVCR.Length = Str.size();
2572 static std::unique_ptr<AArch64Operand>
2574 bool HasExplicitAmount, SMLoc S, SMLoc
E, MCContext &Ctx) {
2575 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2576 Op->ShiftExtend.Type = ShOp;
2577 Op->ShiftExtend.Amount = Val;
2578 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2590 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2591 if (!getFPImmIsExact())
2596 StringRef
Name = getBarrierName();
2598 OS <<
"<barrier " <<
Name <<
">";
2600 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2606 case k_ShiftedImm: {
2607 unsigned Shift = getShiftedImmShift();
2608 OS <<
"<shiftedimm ";
2615 OS << getFirstImmVal();
2616 OS <<
":" << getLastImmVal() <<
">";
2622 case k_VectorList: {
2623 OS <<
"<vectorlist ";
2624 unsigned Reg = getVectorListStart();
2625 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2626 OS <<
Reg + i * getVectorListStride() <<
" ";
2631 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2634 OS <<
"<sysreg: " << getSysReg() <<
'>';
2640 OS <<
"c" << getSysCR();
2643 StringRef
Name = getPrefetchName();
2645 OS <<
"<prfop " <<
Name <<
">";
2647 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2651 OS << getPSBHintName();
2654 OS << getPHintName();
2657 OS << getBTIHintName();
2659 case k_MatrixRegister:
2660 OS <<
"<matrix " << getMatrixReg() <<
">";
2662 case k_MatrixTileList: {
2663 OS <<
"<matrixlist ";
2664 unsigned RegMask = getMatrixTileListRegMask();
2665 unsigned MaxBits = 8;
2666 for (
unsigned I = MaxBits;
I > 0; --
I)
2667 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2676 OS <<
"<register " <<
getReg() <<
">";
2677 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2682 << getShiftExtendAmount();
2683 if (!hasShiftExtendAmount())
2699 .
Case(
"v0", AArch64::Q0)
2700 .
Case(
"v1", AArch64::Q1)
2701 .
Case(
"v2", AArch64::Q2)
2702 .
Case(
"v3", AArch64::Q3)
2703 .
Case(
"v4", AArch64::Q4)
2704 .
Case(
"v5", AArch64::Q5)
2705 .
Case(
"v6", AArch64::Q6)
2706 .
Case(
"v7", AArch64::Q7)
2707 .
Case(
"v8", AArch64::Q8)
2708 .
Case(
"v9", AArch64::Q9)
2709 .
Case(
"v10", AArch64::Q10)
2710 .
Case(
"v11", AArch64::Q11)
2711 .
Case(
"v12", AArch64::Q12)
2712 .
Case(
"v13", AArch64::Q13)
2713 .
Case(
"v14", AArch64::Q14)
2714 .
Case(
"v15", AArch64::Q15)
2715 .
Case(
"v16", AArch64::Q16)
2716 .
Case(
"v17", AArch64::Q17)
2717 .
Case(
"v18", AArch64::Q18)
2718 .
Case(
"v19", AArch64::Q19)
2719 .
Case(
"v20", AArch64::Q20)
2720 .
Case(
"v21", AArch64::Q21)
2721 .
Case(
"v22", AArch64::Q22)
2722 .
Case(
"v23", AArch64::Q23)
2723 .
Case(
"v24", AArch64::Q24)
2724 .
Case(
"v25", AArch64::Q25)
2725 .
Case(
"v26", AArch64::Q26)
2726 .
Case(
"v27", AArch64::Q27)
2727 .
Case(
"v28", AArch64::Q28)
2728 .
Case(
"v29", AArch64::Q29)
2729 .
Case(
"v30", AArch64::Q30)
2730 .
Case(
"v31", AArch64::Q31)
2739 RegKind VectorKind) {
2740 std::pair<int, int> Res = {-1, -1};
2742 switch (VectorKind) {
2743 case RegKind::NeonVector:
2746 .Case(
".1d", {1, 64})
2747 .Case(
".1q", {1, 128})
2749 .Case(
".2h", {2, 16})
2750 .Case(
".2b", {2, 8})
2751 .Case(
".2s", {2, 32})
2752 .Case(
".2d", {2, 64})
2755 .Case(
".4b", {4, 8})
2756 .Case(
".4h", {4, 16})
2757 .Case(
".4s", {4, 32})
2758 .Case(
".8b", {8, 8})
2759 .Case(
".8h", {8, 16})
2760 .Case(
".16b", {16, 8})
2765 .Case(
".h", {0, 16})
2766 .Case(
".s", {0, 32})
2767 .Case(
".d", {0, 64})
2770 case RegKind::SVEPredicateAsCounter:
2771 case RegKind::SVEPredicateVector:
2772 case RegKind::SVEDataVector:
2773 case RegKind::Matrix:
2777 .Case(
".h", {0, 16})
2778 .Case(
".s", {0, 32})
2779 .Case(
".d", {0, 64})
2780 .Case(
".q", {0, 128})
2787 if (Res == std::make_pair(-1, -1))
2788 return std::nullopt;
2790 return std::optional<std::pair<int, int>>(Res);
2799 .
Case(
"z0", AArch64::Z0)
2800 .
Case(
"z1", AArch64::Z1)
2801 .
Case(
"z2", AArch64::Z2)
2802 .
Case(
"z3", AArch64::Z3)
2803 .
Case(
"z4", AArch64::Z4)
2804 .
Case(
"z5", AArch64::Z5)
2805 .
Case(
"z6", AArch64::Z6)
2806 .
Case(
"z7", AArch64::Z7)
2807 .
Case(
"z8", AArch64::Z8)
2808 .
Case(
"z9", AArch64::Z9)
2809 .
Case(
"z10", AArch64::Z10)
2810 .
Case(
"z11", AArch64::Z11)
2811 .
Case(
"z12", AArch64::Z12)
2812 .
Case(
"z13", AArch64::Z13)
2813 .
Case(
"z14", AArch64::Z14)
2814 .
Case(
"z15", AArch64::Z15)
2815 .
Case(
"z16", AArch64::Z16)
2816 .
Case(
"z17", AArch64::Z17)
2817 .
Case(
"z18", AArch64::Z18)
2818 .
Case(
"z19", AArch64::Z19)
2819 .
Case(
"z20", AArch64::Z20)
2820 .
Case(
"z21", AArch64::Z21)
2821 .
Case(
"z22", AArch64::Z22)
2822 .
Case(
"z23", AArch64::Z23)
2823 .
Case(
"z24", AArch64::Z24)
2824 .
Case(
"z25", AArch64::Z25)
2825 .
Case(
"z26", AArch64::Z26)
2826 .
Case(
"z27", AArch64::Z27)
2827 .
Case(
"z28", AArch64::Z28)
2828 .
Case(
"z29", AArch64::Z29)
2829 .
Case(
"z30", AArch64::Z30)
2830 .
Case(
"z31", AArch64::Z31)
2836 .
Case(
"p0", AArch64::P0)
2837 .
Case(
"p1", AArch64::P1)
2838 .
Case(
"p2", AArch64::P2)
2839 .
Case(
"p3", AArch64::P3)
2840 .
Case(
"p4", AArch64::P4)
2841 .
Case(
"p5", AArch64::P5)
2842 .
Case(
"p6", AArch64::P6)
2843 .
Case(
"p7", AArch64::P7)
2844 .
Case(
"p8", AArch64::P8)
2845 .
Case(
"p9", AArch64::P9)
2846 .
Case(
"p10", AArch64::P10)
2847 .
Case(
"p11", AArch64::P11)
2848 .
Case(
"p12", AArch64::P12)
2849 .
Case(
"p13", AArch64::P13)
2850 .
Case(
"p14", AArch64::P14)
2851 .
Case(
"p15", AArch64::P15)
2857 .
Case(
"pn0", AArch64::PN0)
2858 .
Case(
"pn1", AArch64::PN1)
2859 .
Case(
"pn2", AArch64::PN2)
2860 .
Case(
"pn3", AArch64::PN3)
2861 .
Case(
"pn4", AArch64::PN4)
2862 .
Case(
"pn5", AArch64::PN5)
2863 .
Case(
"pn6", AArch64::PN6)
2864 .
Case(
"pn7", AArch64::PN7)
2865 .
Case(
"pn8", AArch64::PN8)
2866 .
Case(
"pn9", AArch64::PN9)
2867 .
Case(
"pn10", AArch64::PN10)
2868 .
Case(
"pn11", AArch64::PN11)
2869 .
Case(
"pn12", AArch64::PN12)
2870 .
Case(
"pn13", AArch64::PN13)
2871 .
Case(
"pn14", AArch64::PN14)
2872 .
Case(
"pn15", AArch64::PN15)
2878 .
Case(
"za0.d", AArch64::ZAD0)
2879 .
Case(
"za1.d", AArch64::ZAD1)
2880 .
Case(
"za2.d", AArch64::ZAD2)
2881 .
Case(
"za3.d", AArch64::ZAD3)
2882 .
Case(
"za4.d", AArch64::ZAD4)
2883 .
Case(
"za5.d", AArch64::ZAD5)
2884 .
Case(
"za6.d", AArch64::ZAD6)
2885 .
Case(
"za7.d", AArch64::ZAD7)
2886 .
Case(
"za0.s", AArch64::ZAS0)
2887 .
Case(
"za1.s", AArch64::ZAS1)
2888 .
Case(
"za2.s", AArch64::ZAS2)
2889 .
Case(
"za3.s", AArch64::ZAS3)
2890 .
Case(
"za0.h", AArch64::ZAH0)
2891 .
Case(
"za1.h", AArch64::ZAH1)
2892 .
Case(
"za0.b", AArch64::ZAB0)
2898 .
Case(
"za", AArch64::ZA)
2899 .
Case(
"za0.q", AArch64::ZAQ0)
2900 .
Case(
"za1.q", AArch64::ZAQ1)
2901 .
Case(
"za2.q", AArch64::ZAQ2)
2902 .
Case(
"za3.q", AArch64::ZAQ3)
2903 .
Case(
"za4.q", AArch64::ZAQ4)
2904 .
Case(
"za5.q", AArch64::ZAQ5)
2905 .
Case(
"za6.q", AArch64::ZAQ6)
2906 .
Case(
"za7.q", AArch64::ZAQ7)
2907 .
Case(
"za8.q", AArch64::ZAQ8)
2908 .
Case(
"za9.q", AArch64::ZAQ9)
2909 .
Case(
"za10.q", AArch64::ZAQ10)
2910 .
Case(
"za11.q", AArch64::ZAQ11)
2911 .
Case(
"za12.q", AArch64::ZAQ12)
2912 .
Case(
"za13.q", AArch64::ZAQ13)
2913 .
Case(
"za14.q", AArch64::ZAQ14)
2914 .
Case(
"za15.q", AArch64::ZAQ15)
2915 .
Case(
"za0.d", AArch64::ZAD0)
2916 .
Case(
"za1.d", AArch64::ZAD1)
2917 .
Case(
"za2.d", AArch64::ZAD2)
2918 .
Case(
"za3.d", AArch64::ZAD3)
2919 .
Case(
"za4.d", AArch64::ZAD4)
2920 .
Case(
"za5.d", AArch64::ZAD5)
2921 .
Case(
"za6.d", AArch64::ZAD6)
2922 .
Case(
"za7.d", AArch64::ZAD7)
2923 .
Case(
"za0.s", AArch64::ZAS0)
2924 .
Case(
"za1.s", AArch64::ZAS1)
2925 .
Case(
"za2.s", AArch64::ZAS2)
2926 .
Case(
"za3.s", AArch64::ZAS3)
2927 .
Case(
"za0.h", AArch64::ZAH0)
2928 .
Case(
"za1.h", AArch64::ZAH1)
2929 .
Case(
"za0.b", AArch64::ZAB0)
2930 .
Case(
"za0h.q", AArch64::ZAQ0)
2931 .
Case(
"za1h.q", AArch64::ZAQ1)
2932 .
Case(
"za2h.q", AArch64::ZAQ2)
2933 .
Case(
"za3h.q", AArch64::ZAQ3)
2934 .
Case(
"za4h.q", AArch64::ZAQ4)
2935 .
Case(
"za5h.q", AArch64::ZAQ5)
2936 .
Case(
"za6h.q", AArch64::ZAQ6)
2937 .
Case(
"za7h.q", AArch64::ZAQ7)
2938 .
Case(
"za8h.q", AArch64::ZAQ8)
2939 .
Case(
"za9h.q", AArch64::ZAQ9)
2940 .
Case(
"za10h.q", AArch64::ZAQ10)
2941 .
Case(
"za11h.q", AArch64::ZAQ11)
2942 .
Case(
"za12h.q", AArch64::ZAQ12)
2943 .
Case(
"za13h.q", AArch64::ZAQ13)
2944 .
Case(
"za14h.q", AArch64::ZAQ14)
2945 .
Case(
"za15h.q", AArch64::ZAQ15)
2946 .
Case(
"za0h.d", AArch64::ZAD0)
2947 .
Case(
"za1h.d", AArch64::ZAD1)
2948 .
Case(
"za2h.d", AArch64::ZAD2)
2949 .
Case(
"za3h.d", AArch64::ZAD3)
2950 .
Case(
"za4h.d", AArch64::ZAD4)
2951 .
Case(
"za5h.d", AArch64::ZAD5)
2952 .
Case(
"za6h.d", AArch64::ZAD6)
2953 .
Case(
"za7h.d", AArch64::ZAD7)
2954 .
Case(
"za0h.s", AArch64::ZAS0)
2955 .
Case(
"za1h.s", AArch64::ZAS1)
2956 .
Case(
"za2h.s", AArch64::ZAS2)
2957 .
Case(
"za3h.s", AArch64::ZAS3)
2958 .
Case(
"za0h.h", AArch64::ZAH0)
2959 .
Case(
"za1h.h", AArch64::ZAH1)
2960 .
Case(
"za0h.b", AArch64::ZAB0)
2961 .
Case(
"za0v.q", AArch64::ZAQ0)
2962 .
Case(
"za1v.q", AArch64::ZAQ1)
2963 .
Case(
"za2v.q", AArch64::ZAQ2)
2964 .
Case(
"za3v.q", AArch64::ZAQ3)
2965 .
Case(
"za4v.q", AArch64::ZAQ4)
2966 .
Case(
"za5v.q", AArch64::ZAQ5)
2967 .
Case(
"za6v.q", AArch64::ZAQ6)
2968 .
Case(
"za7v.q", AArch64::ZAQ7)
2969 .
Case(
"za8v.q", AArch64::ZAQ8)
2970 .
Case(
"za9v.q", AArch64::ZAQ9)
2971 .
Case(
"za10v.q", AArch64::ZAQ10)
2972 .
Case(
"za11v.q", AArch64::ZAQ11)
2973 .
Case(
"za12v.q", AArch64::ZAQ12)
2974 .
Case(
"za13v.q", AArch64::ZAQ13)
2975 .
Case(
"za14v.q", AArch64::ZAQ14)
2976 .
Case(
"za15v.q", AArch64::ZAQ15)
2977 .
Case(
"za0v.d", AArch64::ZAD0)
2978 .
Case(
"za1v.d", AArch64::ZAD1)
2979 .
Case(
"za2v.d", AArch64::ZAD2)
2980 .
Case(
"za3v.d", AArch64::ZAD3)
2981 .
Case(
"za4v.d", AArch64::ZAD4)
2982 .
Case(
"za5v.d", AArch64::ZAD5)
2983 .
Case(
"za6v.d", AArch64::ZAD6)
2984 .
Case(
"za7v.d", AArch64::ZAD7)
2985 .
Case(
"za0v.s", AArch64::ZAS0)
2986 .
Case(
"za1v.s", AArch64::ZAS1)
2987 .
Case(
"za2v.s", AArch64::ZAS2)
2988 .
Case(
"za3v.s", AArch64::ZAS3)
2989 .
Case(
"za0v.h", AArch64::ZAH0)
2990 .
Case(
"za1v.h", AArch64::ZAH1)
2991 .
Case(
"za0v.b", AArch64::ZAB0)
2995bool AArch64AsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2997 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
3000ParseStatus AArch64AsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
3002 StartLoc = getLoc();
3003 ParseStatus Res = tryParseScalarRegister(
Reg);
3009unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
3011 unsigned RegNum = 0;
3013 return Kind == RegKind::SVEDataVector ? RegNum : 0;
3016 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
3019 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
3022 return Kind == RegKind::NeonVector ? RegNum : 0;
3025 return Kind == RegKind::Matrix ? RegNum : 0;
3027 if (
Name.equals_insensitive(
"zt0"))
3028 return Kind == RegKind::LookupTable ? unsigned(AArch64::ZT0) : 0;
3032 return (Kind == RegKind::Scalar) ? RegNum : 0;
3036 if (
auto RegNum = StringSwitch<unsigned>(
Name.lower())
3037 .Case(
"fp", AArch64::FP)
3038 .Case(
"lr", AArch64::LR)
3039 .Case(
"x31", AArch64::XZR)
3040 .Case(
"w31", AArch64::WZR)
3042 return Kind == RegKind::Scalar ? RegNum : 0;
3048 if (Entry == RegisterReqs.
end())
3052 if (Kind ==
Entry->getValue().first)
3053 RegNum =
Entry->getValue().second;
3058unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
3060 case RegKind::Scalar:
3061 case RegKind::NeonVector:
3062 case RegKind::SVEDataVector:
3064 case RegKind::Matrix:
3065 case RegKind::SVEPredicateVector:
3066 case RegKind::SVEPredicateAsCounter:
3068 case RegKind::LookupTable:
3077ParseStatus AArch64AsmParser::tryParseScalarRegister(MCRegister &RegNum) {
3078 const AsmToken &Tok = getTok();
3083 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3097 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3100 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3101 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3105 if (BadNum || CRNum > 15)
3106 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3110 AArch64Operand::CreateSysCR(CRNum, S, getLoc(),
getContext()));
3117 const AsmToken &Tok = getTok();
3119 unsigned MaxVal = 63;
3124 const MCExpr *ImmVal;
3125 if (getParser().parseExpression(ImmVal))
3130 return TokError(
"immediate value expected for prefetch operand");
3133 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3136 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3137 Operands.push_back(AArch64Operand::CreatePrefetch(
3138 prfop, RPRFM ? RPRFM->Name :
"", S,
getContext()));
3143 return TokError(
"prefetch hint expected");
3145 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3147 return TokError(
"prefetch hint expected");
3149 Operands.push_back(AArch64Operand::CreatePrefetch(
3156template <
bool IsSVEPrefetch>
3159 const AsmToken &Tok = getTok();
3161 auto LookupByName = [](StringRef
N) {
3162 if (IsSVEPrefetch) {
3163 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3164 return std::optional<unsigned>(Res->Encoding);
3165 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3166 return std::optional<unsigned>(Res->Encoding);
3167 return std::optional<unsigned>();
3170 auto LookupByEncoding = [](
unsigned E) {
3171 if (IsSVEPrefetch) {
3172 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3173 return std::optional<StringRef>(Res->Name);
3174 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3175 return std::optional<StringRef>(Res->Name);
3176 return std::optional<StringRef>();
3178 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3184 const MCExpr *ImmVal;
3185 if (getParser().parseExpression(ImmVal))
3190 return TokError(
"immediate value expected for prefetch operand");
3193 return TokError(
"prefetch operand out of range, [0," +
utostr(MaxVal) +
3196 auto PRFM = LookupByEncoding(MCE->
getValue());
3197 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3203 return TokError(
"prefetch hint expected");
3205 auto PRFM = LookupByName(Tok.
getString());
3207 return TokError(
"prefetch hint expected");
3209 Operands.push_back(AArch64Operand::CreatePrefetch(
3218 const AsmToken &Tok = getTok();
3220 return TokError(
"invalid operand for instruction");
3222 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3224 return TokError(
"invalid operand for instruction");
3226 Operands.push_back(AArch64Operand::CreatePSBHint(
3233 SMLoc StartLoc = getLoc();
3239 auto RegTok = getTok();
3240 if (!tryParseScalarRegister(RegNum).isSuccess())
3243 if (RegNum != AArch64::XZR) {
3244 getLexer().UnLex(RegTok);
3251 if (!tryParseScalarRegister(RegNum).isSuccess())
3252 return TokError(
"expected register operand");
3254 if (RegNum != AArch64::XZR)
3255 return TokError(
"xzr must be followed by xzr");
3259 Operands.push_back(AArch64Operand::CreateReg(
3260 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
3268 const AsmToken &Tok = getTok();
3270 return TokError(
"invalid operand for instruction");
3272 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3274 return TokError(
"invalid operand for instruction");
3276 Operands.push_back(AArch64Operand::CreateBTIHint(
3286 const MCExpr *Expr =
nullptr;
3292 if (parseSymbolicImmVal(Expr))
3298 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3307 return Error(S,
"gotpage label reference not allowed an addend");
3319 return Error(S,
"page or gotpage label reference expected");
3336 const MCExpr *Expr =
nullptr;
3345 if (parseSymbolicImmVal(Expr))
3351 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
3363 return Error(S,
"unexpected adr label");
3373template <
bool AddFPZeroAsLiteral>
3382 const AsmToken &Tok = getTok();
3386 return TokError(
"invalid floating point immediate");
3391 if (Tok.
getIntVal() > 255 || isNegative)
3392 return TokError(
"encoded floating point value out of range");
3396 AArch64Operand::CreateFPImm(
F,
true, S,
getContext()));
3399 APFloat RealVal(APFloat::IEEEdouble());
3401 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3403 return TokError(
"invalid floating point representation");
3406 RealVal.changeSign();
3408 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3412 Operands.push_back(AArch64Operand::CreateFPImm(
3413 RealVal, *StatusOrErr == APFloat::opOK, S,
getContext()));
3437 const MCExpr *
Imm =
nullptr;
3438 if (parseSymbolicImmVal(Imm))
3442 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3449 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3451 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3453 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
3459 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3460 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3468 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3470 int64_t ShiftAmount = getTok().getIntVal();
3472 if (ShiftAmount < 0)
3473 return Error(getLoc(),
"positive shift amount required");
3477 if (ShiftAmount == 0 && Imm !=
nullptr) {
3479 AArch64Operand::CreateImm(Imm, S, getLoc(),
getContext()));
3483 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3491AArch64AsmParser::parseCondCodeString(StringRef
Cond, std::string &Suggestion) {
3525 Suggestion =
"nfrst";
3532 bool invertCondCode) {
3534 const AsmToken &Tok = getTok();
3538 std::string Suggestion;
3541 std::string Msg =
"invalid condition code";
3542 if (!Suggestion.empty())
3543 Msg +=
", did you mean " + Suggestion +
"?";
3544 return TokError(Msg);
3548 if (invertCondCode) {
3550 return TokError(
"condition codes AL and NV are invalid for this instruction");
3555 AArch64Operand::CreateCondCode(CC, S, getLoc(),
getContext()));
3560 const AsmToken &Tok = getTok();
3564 return TokError(
"invalid operand for instruction");
3566 unsigned PStateImm = -1;
3567 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3570 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3571 PStateImm = SVCR->Encoding;
3580 const AsmToken &Tok = getTok();
3585 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3587 unsigned ElementWidth = 0;
3588 auto DotPosition =
Name.find(
'.');
3590 const auto &KindRes =
3594 "Expected the register to be followed by element width suffix");
3595 ElementWidth = KindRes->second;
3597 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3598 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3603 if (parseOperand(
Operands,
false,
false))
3610 unsigned Reg = matchRegisterNameAlias(Name, RegKind::Matrix);
3614 size_t DotPosition =
Name.find(
'.');
3617 StringRef Head =
Name.take_front(DotPosition);
3618 StringRef
Tail =
Name.drop_front(DotPosition);
3619 StringRef RowOrColumn = Head.
take_back();
3621 MatrixKind
Kind = StringSwitch<MatrixKind>(RowOrColumn.
lower())
3622 .Case(
"h", MatrixKind::Row)
3623 .Case(
"v", MatrixKind::Col)
3624 .Default(MatrixKind::Tile);
3630 "Expected the register to be followed by element width suffix");
3631 unsigned ElementWidth = KindRes->second;
3635 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3641 if (parseOperand(
Operands,
false,
false))
3651 const AsmToken &Tok = getTok();
3654 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
3683 return TokError(
"expected #imm after shift specifier");
3689 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E,
getContext()));
3698 return Error(
E,
"expected integer shift amount");
3700 const MCExpr *ImmVal;
3701 if (getParser().parseExpression(ImmVal))
3706 return Error(
E,
"expected constant '#imm' after shift specifier");
3709 Operands.push_back(AArch64Operand::CreateShiftExtend(
3718 {
"crc", {AArch64::FeatureCRC}},
3719 {
"sm4", {AArch64::FeatureSM4}},
3720 {
"sha3", {AArch64::FeatureSHA3}},
3721 {
"sha2", {AArch64::FeatureSHA2}},
3722 {
"aes", {AArch64::FeatureAES}},
3723 {
"crypto", {AArch64::FeatureCrypto}},
3724 {
"fp", {AArch64::FeatureFPARMv8}},
3725 {
"simd", {AArch64::FeatureNEON}},
3726 {
"ras", {AArch64::FeatureRAS}},
3727 {
"rasv2", {AArch64::FeatureRASv2}},
3728 {
"lse", {AArch64::FeatureLSE}},
3729 {
"predres", {AArch64::FeaturePredRes}},
3730 {
"predres2", {AArch64::FeatureSPECRES2}},
3731 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3732 {
"mte", {AArch64::FeatureMTE}},
3733 {
"memtag", {AArch64::FeatureMTE}},
3734 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3735 {
"pan", {AArch64::FeaturePAN}},
3736 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3737 {
"ccpp", {AArch64::FeatureCCPP}},
3738 {
"rcpc", {AArch64::FeatureRCPC}},
3739 {
"rng", {AArch64::FeatureRandGen}},
3740 {
"sve", {AArch64::FeatureSVE}},
3741 {
"sve-b16b16", {AArch64::FeatureSVEB16B16}},
3742 {
"sve2", {AArch64::FeatureSVE2}},
3743 {
"sve-aes", {AArch64::FeatureSVEAES}},
3744 {
"sve2-aes", {AArch64::FeatureAliasSVE2AES, AArch64::FeatureSVEAES}},
3745 {
"sve-sm4", {AArch64::FeatureSVESM4}},
3746 {
"sve2-sm4", {AArch64::FeatureAliasSVE2SM4, AArch64::FeatureSVESM4}},
3747 {
"sve-sha3", {AArch64::FeatureSVESHA3}},
3748 {
"sve2-sha3", {AArch64::FeatureAliasSVE2SHA3, AArch64::FeatureSVESHA3}},
3749 {
"sve-bitperm", {AArch64::FeatureSVEBitPerm}},
3751 {AArch64::FeatureAliasSVE2BitPerm, AArch64::FeatureSVEBitPerm,
3752 AArch64::FeatureSVE2}},
3753 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3754 {
"ls64", {AArch64::FeatureLS64}},
3755 {
"xs", {AArch64::FeatureXS}},
3756 {
"pauth", {AArch64::FeaturePAuth}},
3757 {
"flagm", {AArch64::FeatureFlagM}},
3758 {
"rme", {AArch64::FeatureRME}},
3759 {
"sme", {AArch64::FeatureSME}},
3760 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3761 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3762 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3763 {
"sme2", {AArch64::FeatureSME2}},
3764 {
"sme2p1", {AArch64::FeatureSME2p1}},
3765 {
"sme-b16b16", {AArch64::FeatureSMEB16B16}},
3766 {
"hbc", {AArch64::FeatureHBC}},
3767 {
"mops", {AArch64::FeatureMOPS}},
3768 {
"mec", {AArch64::FeatureMEC}},
3769 {
"the", {AArch64::FeatureTHE}},
3770 {
"d128", {AArch64::FeatureD128}},
3771 {
"lse128", {AArch64::FeatureLSE128}},
3772 {
"ite", {AArch64::FeatureITE}},
3773 {
"cssc", {AArch64::FeatureCSSC}},
3774 {
"rcpc3", {AArch64::FeatureRCPC3}},
3775 {
"gcs", {AArch64::FeatureGCS}},
3776 {
"bf16", {AArch64::FeatureBF16}},
3777 {
"compnum", {AArch64::FeatureComplxNum}},
3778 {
"dotprod", {AArch64::FeatureDotProd}},
3779 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3780 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3781 {
"fp16", {AArch64::FeatureFullFP16}},
3782 {
"fp16fml", {AArch64::FeatureFP16FML}},
3783 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3784 {
"lor", {AArch64::FeatureLOR}},
3785 {
"profile", {AArch64::FeatureSPE}},
3789 {
"rdm", {AArch64::FeatureRDM}},
3790 {
"rdma", {AArch64::FeatureRDM}},
3791 {
"sb", {AArch64::FeatureSB}},
3792 {
"ssbs", {AArch64::FeatureSSBS}},
3793 {
"tme", {AArch64::FeatureTME}},
3794 {
"fp8", {AArch64::FeatureFP8}},
3795 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3796 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3797 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3798 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3799 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3800 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3801 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3802 {
"lut", {AArch64::FeatureLUT}},
3803 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3804 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3805 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3806 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3807 {
"cpa", {AArch64::FeatureCPA}},
3808 {
"tlbiw", {AArch64::FeatureTLBIW}},
3809 {
"pops", {AArch64::FeaturePoPS}},
3810 {
"cmpbr", {AArch64::FeatureCMPBR}},
3811 {
"f8f32mm", {AArch64::FeatureF8F32MM}},
3812 {
"f8f16mm", {AArch64::FeatureF8F16MM}},
3813 {
"fprcvt", {AArch64::FeatureFPRCVT}},
3814 {
"lsfe", {AArch64::FeatureLSFE}},
3815 {
"sme2p2", {AArch64::FeatureSME2p2}},
3816 {
"ssve-aes", {AArch64::FeatureSSVE_AES}},
3817 {
"sve2p2", {AArch64::FeatureSVE2p2}},
3818 {
"sve-aes2", {AArch64::FeatureSVEAES2}},
3819 {
"sve-bfscale", {AArch64::FeatureSVEBFSCALE}},
3820 {
"sve-f16f32mm", {AArch64::FeatureSVE_F16F32MM}},
3821 {
"lsui", {AArch64::FeatureLSUI}},
3822 {
"occmo", {AArch64::FeatureOCCMO}},
3823 {
"pcdphint", {AArch64::FeaturePCDPHINT}},
3824 {
"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
3825 {
"sme-mop4", {AArch64::FeatureSME_MOP4}},
3826 {
"sme-tmop", {AArch64::FeatureSME_TMOP}},
3830 if (FBS[AArch64::HasV8_0aOps])
3832 if (FBS[AArch64::HasV8_1aOps])
3834 else if (FBS[AArch64::HasV8_2aOps])
3836 else if (FBS[AArch64::HasV8_3aOps])
3838 else if (FBS[AArch64::HasV8_4aOps])
3840 else if (FBS[AArch64::HasV8_5aOps])
3842 else if (FBS[AArch64::HasV8_6aOps])
3844 else if (FBS[AArch64::HasV8_7aOps])
3846 else if (FBS[AArch64::HasV8_8aOps])
3848 else if (FBS[AArch64::HasV8_9aOps])
3850 else if (FBS[AArch64::HasV9_0aOps])
3852 else if (FBS[AArch64::HasV9_1aOps])
3854 else if (FBS[AArch64::HasV9_2aOps])
3856 else if (FBS[AArch64::HasV9_3aOps])
3858 else if (FBS[AArch64::HasV9_4aOps])
3860 else if (FBS[AArch64::HasV9_5aOps])
3862 else if (FBS[AArch64::HasV9_6aOps])
3864 else if (FBS[AArch64::HasV8_0rOps])
3873 Str += !ExtMatches.
empty() ?
llvm::join(ExtMatches,
", ") :
"(unknown)";
3879 const uint16_t Op2 = Encoding & 7;
3880 const uint16_t Cm = (Encoding & 0x78) >> 3;
3881 const uint16_t Cn = (Encoding & 0x780) >> 7;
3882 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3887 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3889 AArch64Operand::CreateSysCR(Cn, S, getLoc(),
getContext()));
3891 AArch64Operand::CreateSysCR(Cm, S, getLoc(),
getContext()));
3894 AArch64Operand::CreateImm(Expr, S, getLoc(),
getContext()));
3899bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
3901 if (
Name.contains(
'.'))
3902 return TokError(
"invalid operand");
3907 const AsmToken &Tok = getTok();
3910 bool ExpectRegister =
true;
3912 if (Mnemonic ==
"ic") {
3913 const AArch64IC::IC *IC = AArch64IC::lookupICByName(
Op);
3915 return TokError(
"invalid operand for IC instruction");
3916 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3917 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3919 return TokError(Str);
3923 }
else if (Mnemonic ==
"dc") {
3924 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(
Op);
3926 return TokError(
"invalid operand for DC instruction");
3927 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3928 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3930 return TokError(Str);
3933 }
else if (Mnemonic ==
"at") {
3934 const AArch64AT::AT *AT = AArch64AT::lookupATByName(
Op);
3936 return TokError(
"invalid operand for AT instruction");
3937 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3938 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3940 return TokError(Str);
3943 }
else if (Mnemonic ==
"tlbi") {
3944 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(
Op);
3946 return TokError(
"invalid operand for TLBI instruction");
3947 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3948 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3950 return TokError(Str);
3954 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3956 if (
Op.lower() !=
"rctx")
3957 return TokError(
"invalid operand for prediction restriction instruction");
3959 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3960 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3961 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3963 if (Mnemonic ==
"cosp" && !hasSpecres2)
3964 return TokError(
"COSP requires: predres2");
3966 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3968 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3969 : Mnemonic ==
"dvp" ? 0b101
3970 : Mnemonic ==
"cosp" ? 0b110
3971 : Mnemonic ==
"cpp" ? 0b111
3974 "Invalid mnemonic for prediction restriction instruction");
3975 const auto SYS_3_7_3 = 0b01101110011;
3976 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3978 createSysAlias(Encoding,
Operands, S);
3983 bool HasRegister =
false;
3988 return TokError(
"expected register operand");
3992 if (ExpectRegister && !HasRegister)
3993 return TokError(
"specified " + Mnemonic +
" op requires a register");
3994 else if (!ExpectRegister && HasRegister)
3995 return TokError(
"specified " + Mnemonic +
" op does not use a register");
4005bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
4007 if (
Name.contains(
'.'))
4008 return TokError(
"invalid operand");
4012 AArch64Operand::CreateToken(
"sysp", NameLoc,
getContext()));
4014 const AsmToken &Tok = getTok();
4018 if (Mnemonic ==
"tlbip") {
4019 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
4020 if (HasnXSQualifier) {
4021 Op =
Op.drop_back(3);
4023 const AArch64TLBI::TLBI *TLBIorig = AArch64TLBI::lookupTLBIByName(
Op);
4025 return TokError(
"invalid operand for TLBIP instruction");
4026 const AArch64TLBI::TLBI TLBI(
4027 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
4034 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
4035 std::string Str(
"TLBIP " + Name +
" requires: ");
4037 return TokError(Str);
4048 return TokError(
"expected register identifier");
4053 return TokError(
"specified " + Mnemonic +
4054 " op requires a pair of registers");
4063 MCAsmParser &Parser = getParser();
4064 const AsmToken &Tok = getTok();
4067 return TokError(
"'csync' operand expected");
4070 const MCExpr *ImmVal;
4071 SMLoc ExprLoc = getLoc();
4072 AsmToken IntTok = Tok;
4073 if (getParser().parseExpression(ImmVal))
4077 return Error(ExprLoc,
"immediate value expected for barrier operand");
4079 if (Mnemonic ==
"dsb" &&
Value > 15) {
4087 return Error(ExprLoc,
"barrier operand out of range");
4088 auto DB = AArch64DB::lookupDBByEncoding(
Value);
4089 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
4096 return TokError(
"invalid operand for instruction");
4099 auto TSB = AArch64TSB::lookupTSBByName(Operand);
4100 auto DB = AArch64DB::lookupDBByName(Operand);
4102 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
4103 return TokError(
"'sy' or #imm operand expected");
4105 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
4106 return TokError(
"'csync' operand expected");
4108 if (Mnemonic ==
"dsb") {
4113 return TokError(
"invalid barrier option name");
4116 Operands.push_back(AArch64Operand::CreateBarrier(
4117 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
4126 const AsmToken &Tok = getTok();
4128 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4129 if (Mnemonic !=
"dsb")
4134 const MCExpr *ImmVal;
4135 SMLoc ExprLoc = getLoc();
4136 if (getParser().parseExpression(ImmVal))
4140 return Error(ExprLoc,
"immediate value expected for barrier operand");
4145 return Error(ExprLoc,
"barrier operand out of range");
4146 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4147 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4154 return TokError(
"invalid operand for instruction");
4157 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4160 return TokError(
"invalid barrier option name");
4163 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4171 const AsmToken &Tok = getTok();
4176 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4180 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.
getString());
4181 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4182 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4183 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4187 unsigned PStateImm = -1;
4188 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4189 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4190 PStateImm = PState15->Encoding;
4192 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4193 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4194 PStateImm = PState1->Encoding;
4198 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4208 const AsmToken &Tok = getTok();
4210 return TokError(
"invalid operand for instruction");
4214 return TokError(
"invalid operand for instruction");
4216 Operands.push_back(AArch64Operand::CreatePHintInst(
4231 ParseStatus Res = tryParseVectorRegister(
Reg, Kind, RegKind::NeonVector);
4239 unsigned ElementWidth = KindRes->second;
4241 AArch64Operand::CreateVectorReg(
Reg, RegKind::NeonVector, ElementWidth,
4249 return tryParseVectorIndex(
Operands).isFailure();
4253 SMLoc SIdx = getLoc();
4255 const MCExpr *ImmVal;
4256 if (getParser().parseExpression(ImmVal))
4260 return TokError(
"immediate value expected for vector index");
4267 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4278ParseStatus AArch64AsmParser::tryParseVectorRegister(MCRegister &
Reg,
4280 RegKind MatchKind) {
4281 const AsmToken &Tok = getTok();
4290 StringRef Head =
Name.slice(Start,
Next);
4291 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4297 return TokError(
"invalid vector kind qualifier");
4308ParseStatus AArch64AsmParser::tryParseSVEPredicateOrPredicateAsCounterVector(
4310 ParseStatus Status =
4311 tryParseSVEPredicateVector<RegKind::SVEPredicateAsCounter>(
Operands);
4313 Status = tryParseSVEPredicateVector<RegKind::SVEPredicateVector>(
Operands);
4318template <RegKind RK>
4322 const SMLoc S = getLoc();
4325 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4333 unsigned ElementWidth = KindRes->second;
4334 Operands.push_back(AArch64Operand::CreateVectorReg(
4335 RegNum, RK, ElementWidth, S,
4339 if (RK == RegKind::SVEPredicateAsCounter) {
4340 ParseStatus ResIndex = tryParseVectorIndex(
Operands);
4346 if (parseOperand(
Operands,
false,
false))
4357 return Error(S,
"not expecting size suffix");
4365 auto Pred = getTok().getString().lower();
4366 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4367 return Error(getLoc(),
"expecting 'z' predication");
4369 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4370 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4373 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4383 if (!tryParseNeonVectorRegister(
Operands))
4386 if (tryParseZTOperand(
Operands).isSuccess())
4390 if (tryParseGPROperand<false>(
Operands).isSuccess())
4396bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4397 bool HasELFModifier =
false;
4399 SMLoc Loc = getLexer().getLoc();
4401 HasELFModifier =
true;
4404 return TokError(
"expect relocation specifier in operand after ':'");
4406 std::string LowerCase = getTok().getIdentifier().lower();
4407 RefKind = StringSwitch<AArch64::Specifier>(LowerCase)
4461 return TokError(
"expect relocation specifier in operand after ':'");
4465 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4469 if (getParser().parseExpression(ImmVal))
4476 if (
getContext().getAsmInfo()->hasSubsectionsViaSymbols()) {
4477 if (getParser().parseAtSpecifier(ImmVal, EndLoc))
4487 if (getParser().parsePrimaryExpr(Term, EndLoc))
4499 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4500 unsigned &ElementWidth) -> ParseStatus {
4501 StringRef
Name = getTok().getString();
4502 size_t DotPosition =
Name.find(
'.');
4510 StringRef
Tail =
Name.drop_front(DotPosition);
4511 const std::optional<std::pair<int, int>> &KindRes =
4515 "Expected the register to be followed by element width suffix");
4516 ElementWidth = KindRes->second;
4523 auto LCurly = getTok();
4528 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4534 if (getTok().getString().equals_insensitive(
"za")) {
4540 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4545 SMLoc TileLoc = getLoc();
4547 unsigned FirstReg, ElementWidth;
4548 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4549 if (!ParseRes.isSuccess()) {
4550 getLexer().UnLex(LCurly);
4554 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4556 unsigned PrevReg = FirstReg;
4558 SmallSet<unsigned, 8> DRegs;
4559 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4561 SmallSet<unsigned, 8> SeenRegs;
4562 SeenRegs.
insert(FirstReg);
4566 unsigned Reg, NextElementWidth;
4567 ParseRes = ParseMatrixTile(
Reg, NextElementWidth);
4568 if (!ParseRes.isSuccess())
4572 if (ElementWidth != NextElementWidth)
4573 return Error(TileLoc,
"mismatched register size suffix");
4576 Warning(TileLoc,
"tile list not in ascending order");
4579 Warning(TileLoc,
"duplicate tile in list");
4582 AArch64Operand::ComputeRegsForAlias(
Reg, DRegs, ElementWidth);
4591 unsigned RegMask = 0;
4592 for (
auto Reg : DRegs)
4596 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(),
getContext()));
4601template <RegKind VectorKind>
4604 MCAsmParser &Parser = getParser();
4609 auto ParseVector = [
this](MCRegister &
Reg, StringRef &
Kind, SMLoc Loc,
4610 bool NoMatchIsError) -> ParseStatus {
4611 auto RegTok = getTok();
4612 auto ParseRes = tryParseVectorRegister(
Reg, Kind, VectorKind);
4613 if (ParseRes.isSuccess()) {
4620 RegTok.getString().equals_insensitive(
"zt0"))
4624 (ParseRes.isNoMatch() && NoMatchIsError &&
4625 !RegTok.getString().starts_with_insensitive(
"za")))
4626 return Error(Loc,
"vector register expected");
4631 unsigned NumRegs = getNumRegsForRegKind(VectorKind);
4633 auto LCurly = getTok();
4637 MCRegister FirstReg;
4638 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4642 if (ParseRes.isNoMatch())
4645 if (!ParseRes.isSuccess())
4648 MCRegister PrevReg = FirstReg;
4651 unsigned Stride = 1;
4653 SMLoc Loc = getLoc();
4657 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4658 if (!ParseRes.isSuccess())
4662 if (Kind != NextKind)
4663 return Error(Loc,
"mismatched register size suffix");
4666 (PrevReg <
Reg) ? (
Reg - PrevReg) : (NumRegs - (PrevReg -
Reg));
4668 if (Space == 0 || Space > 3)
4669 return Error(Loc,
"invalid number of vectors");
4674 bool HasCalculatedStride =
false;
4676 SMLoc Loc = getLoc();
4679 ParseRes = ParseVector(
Reg, NextKind, getLoc(),
true);
4680 if (!ParseRes.isSuccess())
4684 if (Kind != NextKind)
4685 return Error(Loc,
"mismatched register size suffix");
4687 unsigned RegVal =
getContext().getRegisterInfo()->getEncodingValue(
Reg);
4688 unsigned PrevRegVal =
4689 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4690 if (!HasCalculatedStride) {
4691 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4692 : (NumRegs - (PrevRegVal - RegVal));
4693 HasCalculatedStride =
true;
4697 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4698 return Error(Loc,
"registers must have the same sequential stride");
4709 return Error(S,
"invalid number of vectors");
4711 unsigned NumElements = 0;
4712 unsigned ElementWidth = 0;
4713 if (!
Kind.empty()) {
4715 std::tie(NumElements, ElementWidth) = *VK;
4718 Operands.push_back(AArch64Operand::CreateVectorList(
4719 FirstReg,
Count, Stride, NumElements, ElementWidth, VectorKind, S,
4727 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4728 if (!ParseRes.isSuccess())
4731 return tryParseVectorIndex(
Operands).isFailure();
4735 SMLoc StartLoc = getLoc();
4738 ParseStatus Res = tryParseScalarRegister(RegNum);
4743 Operands.push_back(AArch64Operand::CreateReg(
4744 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4751 return Error(getLoc(),
"index must be absent or #0");
4753 const MCExpr *ImmVal;
4756 return Error(getLoc(),
"index must be absent or #0");
4758 Operands.push_back(AArch64Operand::CreateReg(
4759 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext()));
4764 SMLoc StartLoc = getLoc();
4765 const AsmToken &Tok = getTok();
4768 unsigned RegNum = matchRegisterNameAlias(Name, RegKind::LookupTable);
4773 Operands.push_back(AArch64Operand::CreateReg(
4774 RegNum, RegKind::LookupTable, StartLoc, getLoc(),
getContext()));
4780 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4781 const MCExpr *ImmVal;
4782 if (getParser().parseExpression(ImmVal))
4786 return TokError(
"immediate value expected for vector index");
4787 Operands.push_back(AArch64Operand::CreateImm(
4791 if (parseOptionalMulOperand(
Operands))
4796 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
4801template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4803 SMLoc StartLoc = getLoc();
4806 ParseStatus Res = tryParseScalarRegister(RegNum);
4812 Operands.push_back(AArch64Operand::CreateReg(
4813 RegNum, RegKind::Scalar, StartLoc, getLoc(),
getContext(), EqTy));
4822 Res = tryParseOptionalShiftExtend(ExtOpnd);
4826 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().
get());
4827 Operands.push_back(AArch64Operand::CreateReg(
4828 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(),
getContext(), EqTy,
4829 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4830 Ext->hasShiftExtendAmount()));
4836 MCAsmParser &Parser = getParser();
4844 if (!getTok().getString().equals_insensitive(
"mul") ||
4845 !(NextIsVL || NextIsHash))
4849 AArch64Operand::CreateToken(
"mul", getLoc(),
getContext()));
4854 AArch64Operand::CreateToken(
"vl", getLoc(),
getContext()));
4864 const MCExpr *ImmVal;
4867 Operands.push_back(AArch64Operand::CreateImm(
4874 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4878 StringRef &VecGroup) {
4879 MCAsmParser &Parser = getParser();
4880 auto Tok = Parser.
getTok();
4885 .Case(
"vgx2",
"vgx2")
4886 .Case(
"vgx4",
"vgx4")
4898 auto Tok = getTok();
4917 bool invertCondCode) {
4918 MCAsmParser &Parser = getParser();
4921 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4935 auto parseOptionalShiftExtend = [&](AsmToken SavedTok) {
4937 ParseStatus Res = tryParseOptionalShiftExtend(
Operands);
4940 getLexer().UnLex(SavedTok);
4944 switch (getLexer().getKind()) {
4948 if (parseSymbolicImmVal(Expr))
4949 return Error(S,
"invalid operand");
4953 return parseOptionalShiftExtend(getTok());
4957 AArch64Operand::CreateToken(
"[", getLoc(),
getContext()));
4962 return parseOperand(
Operands,
false,
false);
4965 if (!parseNeonVectorList(
Operands))
4969 AArch64Operand::CreateToken(
"{", getLoc(),
getContext()));
4974 return parseOperand(
Operands,
false,
false);
4979 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4981 AArch64Operand::CreateToken(VecGroup, getLoc(),
getContext()));
4986 return parseCondCode(
Operands, invertCondCode);
4991 AsmToken SavedTok = getTok();
4996 ParseStatus Res = MatchOperandParserImpl(
Operands, Mnemonic,
5000 Res = tryParseOptionalShiftExtend(
Operands);
5003 getLexer().UnLex(SavedTok);
5010 if (!parseOptionalMulOperand(
Operands))
5015 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
5017 return parseKeywordOperand(
Operands);
5021 const MCExpr *IdVal, *
Term;
5023 if (getParser().parseExpression(IdVal))
5025 if (getParser().parseAtSpecifier(IdVal,
E))
5027 std::optional<MCBinaryExpr::Opcode> Opcode;
5033 if (getParser().parsePrimaryExpr(Term,
E))
5040 return parseOptionalShiftExtend(getTok());
5051 bool isNegative =
false;
5063 const AsmToken &Tok = getTok();
5066 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5067 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
5068 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
5069 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
5070 return TokError(
"unexpected floating point literal");
5071 else if (IntVal != 0 || isNegative)
5072 return TokError(
"expected floating-point constant #0.0");
5080 const MCExpr *ImmVal;
5081 if (parseSymbolicImmVal(ImmVal))
5088 return parseOptionalShiftExtend(Tok);
5091 SMLoc Loc = getLoc();
5092 if (Mnemonic !=
"ldr")
5093 return TokError(
"unexpected token in operand");
5095 const MCExpr *SubExprVal;
5096 if (getParser().parseExpression(SubExprVal))
5100 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
5101 return Error(Loc,
"Only valid when first operand is register");
5104 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
5112 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
5117 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
5118 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
5119 Operands.push_back(AArch64Operand::CreateImm(
5123 ShiftAmt,
true, S,
E, Ctx));
5126 APInt Simm = APInt(64, Imm << ShiftAmt);
5129 return Error(Loc,
"Immediate too large for register");
5132 const MCExpr *CPLoc =
5133 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
5134 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
5140bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
5141 const MCExpr *Expr =
nullptr;
5143 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
5146 if (check(!
Value, L,
"expected constant expression"))
5148 Out =
Value->getValue();
5152bool AArch64AsmParser::parseComma() {
5160bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
5164 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register"))
5169 unsigned RangeEnd =
Last;
5170 if (
Base == AArch64::X0) {
5171 if (
Last == AArch64::FP) {
5172 RangeEnd = AArch64::X28;
5173 if (
Reg == AArch64::FP) {
5178 if (
Last == AArch64::LR) {
5179 RangeEnd = AArch64::X28;
5180 if (
Reg == AArch64::FP) {
5183 }
else if (
Reg == AArch64::LR) {
5191 Twine(
"expected register in range ") +
5199bool AArch64AsmParser::areEqualRegs(
const MCParsedAsmOperand &Op1,
5200 const MCParsedAsmOperand &Op2)
const {
5201 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5202 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5204 if (AOp1.isVectorList() && AOp2.isVectorList())
5205 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5206 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5207 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5209 if (!AOp1.isReg() || !AOp2.isReg())
5212 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5213 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5216 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5217 "Testing equality of non-scalar registers not supported");
5220 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5222 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5224 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5226 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5233bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &
Info,
5234 StringRef Name, SMLoc NameLoc,
5236 Name = StringSwitch<StringRef>(
Name.lower())
5237 .Case(
"beq",
"b.eq")
5238 .Case(
"bne",
"b.ne")
5239 .Case(
"bhs",
"b.hs")
5240 .Case(
"bcs",
"b.cs")
5241 .Case(
"blo",
"b.lo")
5242 .Case(
"bcc",
"b.cc")
5243 .Case(
"bmi",
"b.mi")
5244 .Case(
"bpl",
"b.pl")
5245 .Case(
"bvs",
"b.vs")
5246 .Case(
"bvc",
"b.vc")
5247 .Case(
"bhi",
"b.hi")
5248 .Case(
"bls",
"b.ls")
5249 .Case(
"bge",
"b.ge")
5250 .Case(
"blt",
"b.lt")
5251 .Case(
"bgt",
"b.gt")
5252 .Case(
"ble",
"b.le")
5253 .Case(
"bal",
"b.al")
5254 .Case(
"bnv",
"b.nv")
5259 getTok().getIdentifier().lower() ==
".req") {
5260 parseDirectiveReq(Name, NameLoc);
5268 StringRef Head =
Name.slice(Start,
Next);
5272 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5273 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5274 return parseSysAlias(Head, NameLoc,
Operands);
5277 if (Head ==
"tlbip")
5278 return parseSyspAlias(Head, NameLoc,
Operands);
5287 Head =
Name.slice(Start + 1,
Next);
5291 std::string Suggestion;
5294 std::string Msg =
"invalid condition code";
5295 if (!Suggestion.empty())
5296 Msg +=
", did you mean " + Suggestion +
"?";
5297 return Error(SuffixLoc, Msg);
5302 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc,
getContext()));
5312 Operands.push_back(AArch64Operand::CreateToken(
5318 bool condCodeFourthOperand =
5319 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5320 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5321 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5329 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5330 bool condCodeThirdOperand =
5331 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5339 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5340 (
N == 3 && condCodeThirdOperand) ||
5341 (
N == 2 && condCodeSecondOperand),
5342 condCodeSecondOperand || condCodeThirdOperand)) {
5362 AArch64Operand::CreateToken(
"]", getLoc(),
getContext()));
5365 AArch64Operand::CreateToken(
"!", getLoc(),
getContext()));
5368 AArch64Operand::CreateToken(
"}", getLoc(),
getContext()));
5381 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5382 return (ZReg == ((
Reg - AArch64::B0) + AArch64::Z0)) ||
5383 (ZReg == ((
Reg - AArch64::H0) + AArch64::Z0)) ||
5384 (ZReg == ((
Reg - AArch64::S0) + AArch64::Z0)) ||
5385 (ZReg == ((
Reg - AArch64::D0) + AArch64::Z0)) ||
5386 (ZReg == ((
Reg - AArch64::Q0) + AArch64::Z0)) ||
5387 (ZReg == ((
Reg - AArch64::Z0) + AArch64::Z0));
5393bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
5394 SmallVectorImpl<SMLoc> &Loc) {
5395 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
5396 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
5402 PrefixInfo
Prefix = NextPrefix;
5403 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5415 return Error(IDLoc,
"instruction is unpredictable when following a"
5416 " movprfx, suggest replacing movprfx with mov");
5420 return Error(Loc[0],
"instruction is unpredictable when following a"
5421 " movprfx writing to a different destination");
5428 return Error(Loc[0],
"instruction is unpredictable when following a"
5429 " movprfx and destination also used as non-destructive"
5433 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5434 if (
Prefix.isPredicated()) {
5448 return Error(IDLoc,
"instruction is unpredictable when following a"
5449 " predicated movprfx, suggest using unpredicated movprfx");
5453 return Error(IDLoc,
"instruction is unpredictable when following a"
5454 " predicated movprfx using a different general predicate");
5458 return Error(IDLoc,
"instruction is unpredictable when following a"
5459 " predicated movprfx with a different element size");
5465 if (IsWindowsArm64EC) {
5471 if ((
Reg == AArch64::W13 ||
Reg == AArch64::X13) ||
5472 (
Reg == AArch64::W14 ||
Reg == AArch64::X14) ||
5473 (
Reg == AArch64::W23 ||
Reg == AArch64::X23) ||
5474 (
Reg == AArch64::W24 ||
Reg == AArch64::X24) ||
5475 (
Reg == AArch64::W28 ||
Reg == AArch64::X28) ||
5476 (
Reg >= AArch64::Q16 &&
Reg <= AArch64::Q31) ||
5477 (
Reg >= AArch64::D16 &&
Reg <= AArch64::D31) ||
5478 (
Reg >= AArch64::S16 &&
Reg <= AArch64::S31) ||
5479 (
Reg >= AArch64::H16 &&
Reg <= AArch64::H31) ||
5480 (
Reg >= AArch64::B16 &&
Reg <= AArch64::B31)) {
5482 " is disallowed on ARM64EC.");
5492 case AArch64::LDPSWpre:
5493 case AArch64::LDPWpost:
5494 case AArch64::LDPWpre:
5495 case AArch64::LDPXpost:
5496 case AArch64::LDPXpre: {
5501 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5502 "is also a destination");
5504 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5505 "is also a destination");
5508 case AArch64::LDR_ZA:
5509 case AArch64::STR_ZA: {
5512 return Error(Loc[1],
5513 "unpredictable instruction, immediate and offset mismatch.");
5516 case AArch64::LDPDi:
5517 case AArch64::LDPQi:
5518 case AArch64::LDPSi:
5519 case AArch64::LDPSWi:
5520 case AArch64::LDPWi:
5521 case AArch64::LDPXi: {
5525 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5528 case AArch64::LDPDpost:
5529 case AArch64::LDPDpre:
5530 case AArch64::LDPQpost:
5531 case AArch64::LDPQpre:
5532 case AArch64::LDPSpost:
5533 case AArch64::LDPSpre:
5534 case AArch64::LDPSWpost: {
5538 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5541 case AArch64::STPDpost:
5542 case AArch64::STPDpre:
5543 case AArch64::STPQpost:
5544 case AArch64::STPQpre:
5545 case AArch64::STPSpost:
5546 case AArch64::STPSpre:
5547 case AArch64::STPWpost:
5548 case AArch64::STPWpre:
5549 case AArch64::STPXpost:
5550 case AArch64::STPXpre: {
5555 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5556 "is also a source");
5558 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5559 "is also a source");
5562 case AArch64::LDRBBpre:
5563 case AArch64::LDRBpre:
5564 case AArch64::LDRHHpre:
5565 case AArch64::LDRHpre:
5566 case AArch64::LDRSBWpre:
5567 case AArch64::LDRSBXpre:
5568 case AArch64::LDRSHWpre:
5569 case AArch64::LDRSHXpre:
5570 case AArch64::LDRSWpre:
5571 case AArch64::LDRWpre:
5572 case AArch64::LDRXpre:
5573 case AArch64::LDRBBpost:
5574 case AArch64::LDRBpost:
5575 case AArch64::LDRHHpost:
5576 case AArch64::LDRHpost:
5577 case AArch64::LDRSBWpost:
5578 case AArch64::LDRSBXpost:
5579 case AArch64::LDRSHWpost:
5580 case AArch64::LDRSHXpost:
5581 case AArch64::LDRSWpost:
5582 case AArch64::LDRWpost:
5583 case AArch64::LDRXpost: {
5587 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5588 "is also a source");
5591 case AArch64::STRBBpost:
5592 case AArch64::STRBpost:
5593 case AArch64::STRHHpost:
5594 case AArch64::STRHpost:
5595 case AArch64::STRWpost:
5596 case AArch64::STRXpost:
5597 case AArch64::STRBBpre:
5598 case AArch64::STRBpre:
5599 case AArch64::STRHHpre:
5600 case AArch64::STRHpre:
5601 case AArch64::STRWpre:
5602 case AArch64::STRXpre: {
5606 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5607 "is also a source");
5610 case AArch64::STXRB:
5611 case AArch64::STXRH:
5612 case AArch64::STXRW:
5613 case AArch64::STXRX:
5614 case AArch64::STLXRB:
5615 case AArch64::STLXRH:
5616 case AArch64::STLXRW:
5617 case AArch64::STLXRX: {
5623 return Error(Loc[0],
5624 "unpredictable STXR instruction, status is also a source");
5627 case AArch64::STXPW:
5628 case AArch64::STXPX:
5629 case AArch64::STLXPW:
5630 case AArch64::STLXPX: {
5637 return Error(Loc[0],
5638 "unpredictable STXP instruction, status is also a source");
5641 case AArch64::LDRABwriteback:
5642 case AArch64::LDRAAwriteback: {
5646 return Error(Loc[0],
5647 "unpredictable LDRA instruction, writeback base"
5648 " is also a destination");
5655 case AArch64::CPYFP:
5656 case AArch64::CPYFPWN:
5657 case AArch64::CPYFPRN:
5658 case AArch64::CPYFPN:
5659 case AArch64::CPYFPWT:
5660 case AArch64::CPYFPWTWN:
5661 case AArch64::CPYFPWTRN:
5662 case AArch64::CPYFPWTN:
5663 case AArch64::CPYFPRT:
5664 case AArch64::CPYFPRTWN:
5665 case AArch64::CPYFPRTRN:
5666 case AArch64::CPYFPRTN:
5667 case AArch64::CPYFPT:
5668 case AArch64::CPYFPTWN:
5669 case AArch64::CPYFPTRN:
5670 case AArch64::CPYFPTN:
5671 case AArch64::CPYFM:
5672 case AArch64::CPYFMWN:
5673 case AArch64::CPYFMRN:
5674 case AArch64::CPYFMN:
5675 case AArch64::CPYFMWT:
5676 case AArch64::CPYFMWTWN:
5677 case AArch64::CPYFMWTRN:
5678 case AArch64::CPYFMWTN:
5679 case AArch64::CPYFMRT:
5680 case AArch64::CPYFMRTWN:
5681 case AArch64::CPYFMRTRN:
5682 case AArch64::CPYFMRTN:
5683 case AArch64::CPYFMT:
5684 case AArch64::CPYFMTWN:
5685 case AArch64::CPYFMTRN:
5686 case AArch64::CPYFMTN:
5687 case AArch64::CPYFE:
5688 case AArch64::CPYFEWN:
5689 case AArch64::CPYFERN:
5690 case AArch64::CPYFEN:
5691 case AArch64::CPYFEWT:
5692 case AArch64::CPYFEWTWN:
5693 case AArch64::CPYFEWTRN:
5694 case AArch64::CPYFEWTN:
5695 case AArch64::CPYFERT:
5696 case AArch64::CPYFERTWN:
5697 case AArch64::CPYFERTRN:
5698 case AArch64::CPYFERTN:
5699 case AArch64::CPYFET:
5700 case AArch64::CPYFETWN:
5701 case AArch64::CPYFETRN:
5702 case AArch64::CPYFETN:
5704 case AArch64::CPYPWN:
5705 case AArch64::CPYPRN:
5706 case AArch64::CPYPN:
5707 case AArch64::CPYPWT:
5708 case AArch64::CPYPWTWN:
5709 case AArch64::CPYPWTRN:
5710 case AArch64::CPYPWTN:
5711 case AArch64::CPYPRT:
5712 case AArch64::CPYPRTWN:
5713 case AArch64::CPYPRTRN:
5714 case AArch64::CPYPRTN:
5715 case AArch64::CPYPT:
5716 case AArch64::CPYPTWN:
5717 case AArch64::CPYPTRN:
5718 case AArch64::CPYPTN:
5720 case AArch64::CPYMWN:
5721 case AArch64::CPYMRN:
5722 case AArch64::CPYMN:
5723 case AArch64::CPYMWT:
5724 case AArch64::CPYMWTWN:
5725 case AArch64::CPYMWTRN:
5726 case AArch64::CPYMWTN:
5727 case AArch64::CPYMRT:
5728 case AArch64::CPYMRTWN:
5729 case AArch64::CPYMRTRN:
5730 case AArch64::CPYMRTN:
5731 case AArch64::CPYMT:
5732 case AArch64::CPYMTWN:
5733 case AArch64::CPYMTRN:
5734 case AArch64::CPYMTN:
5736 case AArch64::CPYEWN:
5737 case AArch64::CPYERN:
5738 case AArch64::CPYEN:
5739 case AArch64::CPYEWT:
5740 case AArch64::CPYEWTWN:
5741 case AArch64::CPYEWTRN:
5742 case AArch64::CPYEWTN:
5743 case AArch64::CPYERT:
5744 case AArch64::CPYERTWN:
5745 case AArch64::CPYERTRN:
5746 case AArch64::CPYERTN:
5747 case AArch64::CPYET:
5748 case AArch64::CPYETWN:
5749 case AArch64::CPYETRN:
5750 case AArch64::CPYETN: {
5758 return Error(Loc[0],
5759 "invalid CPY instruction, Xd_wb and Xd do not match");
5761 return Error(Loc[0],
5762 "invalid CPY instruction, Xs_wb and Xs do not match");
5764 return Error(Loc[0],
5765 "invalid CPY instruction, Xn_wb and Xn do not match");
5767 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5768 " registers are the same");
5770 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5771 " registers are the same");
5773 return Error(Loc[0],
"invalid CPY instruction, source and size"
5774 " registers are the same");
5778 case AArch64::SETPT:
5779 case AArch64::SETPN:
5780 case AArch64::SETPTN:
5782 case AArch64::SETMT:
5783 case AArch64::SETMN:
5784 case AArch64::SETMTN:
5786 case AArch64::SETET:
5787 case AArch64::SETEN:
5788 case AArch64::SETETN:
5789 case AArch64::SETGP:
5790 case AArch64::SETGPT:
5791 case AArch64::SETGPN:
5792 case AArch64::SETGPTN:
5793 case AArch64::SETGM:
5794 case AArch64::SETGMT:
5795 case AArch64::SETGMN:
5796 case AArch64::SETGMTN:
5797 case AArch64::MOPSSETGE:
5798 case AArch64::MOPSSETGET:
5799 case AArch64::MOPSSETGEN:
5800 case AArch64::MOPSSETGETN: {
5807 return Error(Loc[0],
5808 "invalid SET instruction, Xd_wb and Xd do not match");
5810 return Error(Loc[0],
5811 "invalid SET instruction, Xn_wb and Xn do not match");
5813 return Error(Loc[0],
"invalid SET instruction, destination and size"
5814 " registers are the same");
5816 return Error(Loc[0],
"invalid SET instruction, destination and source"
5817 " registers are the same");
5819 return Error(Loc[0],
"invalid SET instruction, source and size"
5820 " registers are the same");
5829 case AArch64::ADDSWri:
5830 case AArch64::ADDSXri:
5831 case AArch64::ADDWri:
5832 case AArch64::ADDXri:
5833 case AArch64::SUBSWri:
5834 case AArch64::SUBSXri:
5835 case AArch64::SUBWri:
5836 case AArch64::SUBXri: {
5844 if (classifySymbolRef(Expr, ELFSpec, DarwinSpec, Addend)) {
5869 return Error(Loc.
back(),
"invalid immediate expression");
5882 unsigned VariantID = 0);
5884bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5888 case Match_InvalidTiedOperand: {
5890 if (
Op.isVectorList())
5891 return Error(
Loc,
"operand must match destination register list");
5893 assert(
Op.isReg() &&
"Unexpected operand type");
5894 switch (
Op.getRegEqualityTy()) {
5895 case RegConstraintEqualityTy::EqualsSubReg:
5896 return Error(
Loc,
"operand must be 64-bit form of destination register");
5897 case RegConstraintEqualityTy::EqualsSuperReg:
5898 return Error(
Loc,
"operand must be 32-bit form of destination register");
5899 case RegConstraintEqualityTy::EqualsReg:
5900 return Error(
Loc,
"operand must match destination register");
5904 case Match_MissingFeature:
5906 "instruction requires a CPU feature not currently enabled");
5907 case Match_InvalidOperand:
5908 return Error(Loc,
"invalid operand for instruction");
5909 case Match_InvalidSuffix:
5910 return Error(Loc,
"invalid type suffix for instruction");
5911 case Match_InvalidCondCode:
5912 return Error(Loc,
"expected AArch64 condition code");
5913 case Match_AddSubRegExtendSmall:
5915 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5916 case Match_AddSubRegExtendLarge:
5918 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5919 case Match_AddSubSecondSource:
5921 "expected compatible register, symbol or integer in range [0, 4095]");
5922 case Match_LogicalSecondSource:
5923 return Error(Loc,
"expected compatible register or logical immediate");
5924 case Match_InvalidMovImm32Shift:
5925 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5926 case Match_InvalidMovImm64Shift:
5927 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5928 case Match_AddSubRegShift32:
5930 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5931 case Match_AddSubRegShift64:
5933 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5934 case Match_InvalidFPImm:
5936 "expected compatible register or floating-point constant");
5937 case Match_InvalidMemoryIndexedSImm6:
5938 return Error(Loc,
"index must be an integer in range [-32, 31].");
5939 case Match_InvalidMemoryIndexedSImm5:
5940 return Error(Loc,
"index must be an integer in range [-16, 15].");
5941 case Match_InvalidMemoryIndexed1SImm4:
5942 return Error(Loc,
"index must be an integer in range [-8, 7].");
5943 case Match_InvalidMemoryIndexed2SImm4:
5944 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5945 case Match_InvalidMemoryIndexed3SImm4:
5946 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5947 case Match_InvalidMemoryIndexed4SImm4:
5948 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5949 case Match_InvalidMemoryIndexed16SImm4:
5950 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5951 case Match_InvalidMemoryIndexed32SImm4:
5952 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5953 case Match_InvalidMemoryIndexed1SImm6:
5954 return Error(Loc,
"index must be an integer in range [-32, 31].");
5955 case Match_InvalidMemoryIndexedSImm8:
5956 return Error(Loc,
"index must be an integer in range [-128, 127].");
5957 case Match_InvalidMemoryIndexedSImm9:
5958 return Error(Loc,
"index must be an integer in range [-256, 255].");
5959 case Match_InvalidMemoryIndexed16SImm9:
5960 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5961 case Match_InvalidMemoryIndexed8SImm10:
5962 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5963 case Match_InvalidMemoryIndexed4SImm7:
5964 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5965 case Match_InvalidMemoryIndexed8SImm7:
5966 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5967 case Match_InvalidMemoryIndexed16SImm7:
5968 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5969 case Match_InvalidMemoryIndexed8UImm5:
5970 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5971 case Match_InvalidMemoryIndexed8UImm3:
5972 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5973 case Match_InvalidMemoryIndexed4UImm5:
5974 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5975 case Match_InvalidMemoryIndexed2UImm5:
5976 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5977 case Match_InvalidMemoryIndexed8UImm6:
5978 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5979 case Match_InvalidMemoryIndexed16UImm6:
5980 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5981 case Match_InvalidMemoryIndexed4UImm6:
5982 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5983 case Match_InvalidMemoryIndexed2UImm6:
5984 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5985 case Match_InvalidMemoryIndexed1UImm6:
5986 return Error(Loc,
"index must be in range [0, 63].");
5987 case Match_InvalidMemoryWExtend8:
5989 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5990 case Match_InvalidMemoryWExtend16:
5992 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5993 case Match_InvalidMemoryWExtend32:
5995 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5996 case Match_InvalidMemoryWExtend64:
5998 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5999 case Match_InvalidMemoryWExtend128:
6001 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
6002 case Match_InvalidMemoryXExtend8:
6004 "expected 'lsl' or 'sxtx' with optional shift of #0");
6005 case Match_InvalidMemoryXExtend16:
6007 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
6008 case Match_InvalidMemoryXExtend32:
6010 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
6011 case Match_InvalidMemoryXExtend64:
6013 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
6014 case Match_InvalidMemoryXExtend128:
6016 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
6017 case Match_InvalidMemoryIndexed1:
6018 return Error(Loc,
"index must be an integer in range [0, 4095].");
6019 case Match_InvalidMemoryIndexed2:
6020 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
6021 case Match_InvalidMemoryIndexed4:
6022 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
6023 case Match_InvalidMemoryIndexed8:
6024 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
6025 case Match_InvalidMemoryIndexed16:
6026 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
6027 case Match_InvalidImm0_0:
6028 return Error(Loc,
"immediate must be 0.");
6029 case Match_InvalidImm0_1:
6030 return Error(Loc,
"immediate must be an integer in range [0, 1].");
6031 case Match_InvalidImm0_3:
6032 return Error(Loc,
"immediate must be an integer in range [0, 3].");
6033 case Match_InvalidImm0_7:
6034 return Error(Loc,
"immediate must be an integer in range [0, 7].");
6035 case Match_InvalidImm0_15:
6036 return Error(Loc,
"immediate must be an integer in range [0, 15].");
6037 case Match_InvalidImm0_31:
6038 return Error(Loc,
"immediate must be an integer in range [0, 31].");
6039 case Match_InvalidImm0_63:
6040 return Error(Loc,
"immediate must be an integer in range [0, 63].");
6041 case Match_InvalidImm0_127:
6042 return Error(Loc,
"immediate must be an integer in range [0, 127].");
6043 case Match_InvalidImm0_255:
6044 return Error(Loc,
"immediate must be an integer in range [0, 255].");
6045 case Match_InvalidImm0_65535:
6046 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
6047 case Match_InvalidImm1_8:
6048 return Error(Loc,
"immediate must be an integer in range [1, 8].");
6049 case Match_InvalidImm1_16:
6050 return Error(Loc,
"immediate must be an integer in range [1, 16].");
6051 case Match_InvalidImm1_32:
6052 return Error(Loc,
"immediate must be an integer in range [1, 32].");
6053 case Match_InvalidImm1_64:
6054 return Error(Loc,
"immediate must be an integer in range [1, 64].");
6055 case Match_InvalidImmM1_62:
6056 return Error(Loc,
"immediate must be an integer in range [-1, 62].");
6057 case Match_InvalidMemoryIndexedRange2UImm0:
6058 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
6059 case Match_InvalidMemoryIndexedRange2UImm1:
6060 return Error(Loc,
"vector select offset must be an immediate range of the "
6061 "form <immf>:<imml>, where the first "
6062 "immediate is a multiple of 2 in the range [0, 2], and "
6063 "the second immediate is immf + 1.");
6064 case Match_InvalidMemoryIndexedRange2UImm2:
6065 case Match_InvalidMemoryIndexedRange2UImm3:
6068 "vector select offset must be an immediate range of the form "
6070 "where the first immediate is a multiple of 2 in the range [0, 6] or "
6072 "depending on the instruction, and the second immediate is immf + 1.");
6073 case Match_InvalidMemoryIndexedRange4UImm0:
6074 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
6075 case Match_InvalidMemoryIndexedRange4UImm1:
6076 case Match_InvalidMemoryIndexedRange4UImm2:
6079 "vector select offset must be an immediate range of the form "
6081 "where the first immediate is a multiple of 4 in the range [0, 4] or "
6083 "depending on the instruction, and the second immediate is immf + 3.");
6084 case Match_InvalidSVEAddSubImm8:
6085 return Error(Loc,
"immediate must be an integer in range [0, 255]"
6086 " with a shift amount of 0");
6087 case Match_InvalidSVEAddSubImm16:
6088 case Match_InvalidSVEAddSubImm32:
6089 case Match_InvalidSVEAddSubImm64:
6090 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
6091 "multiple of 256 in range [256, 65280]");
6092 case Match_InvalidSVECpyImm8:
6093 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
6094 " with a shift amount of 0");
6095 case Match_InvalidSVECpyImm16:
6096 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6097 "multiple of 256 in range [-32768, 65280]");
6098 case Match_InvalidSVECpyImm32:
6099 case Match_InvalidSVECpyImm64:
6100 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
6101 "multiple of 256 in range [-32768, 32512]");
6102 case Match_InvalidIndexRange0_0:
6103 return Error(Loc,
"expected lane specifier '[0]'");
6104 case Match_InvalidIndexRange1_1:
6105 return Error(Loc,
"expected lane specifier '[1]'");
6106 case Match_InvalidIndexRange0_15:
6107 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6108 case Match_InvalidIndexRange0_7:
6109 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6110 case Match_InvalidIndexRange0_3:
6111 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6112 case Match_InvalidIndexRange0_1:
6113 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
6114 case Match_InvalidSVEIndexRange0_63:
6115 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
6116 case Match_InvalidSVEIndexRange0_31:
6117 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
6118 case Match_InvalidSVEIndexRange0_15:
6119 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
6120 case Match_InvalidSVEIndexRange0_7:
6121 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
6122 case Match_InvalidSVEIndexRange0_3:
6123 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
6124 case Match_InvalidLabel:
6125 return Error(Loc,
"expected label or encodable integer pc offset");
6127 return Error(Loc,
"expected readable system register");
6129 case Match_InvalidSVCR:
6130 return Error(Loc,
"expected writable system register or pstate");
6131 case Match_InvalidComplexRotationEven:
6132 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
6133 case Match_InvalidComplexRotationOdd:
6134 return Error(Loc,
"complex rotation must be 90 or 270.");
6135 case Match_MnemonicFail: {
6138 ComputeAvailableFeatures(STI->getFeatureBits()));
6139 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
6141 case Match_InvalidGPR64shifted8:
6142 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
6143 case Match_InvalidGPR64shifted16:
6144 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
6145 case Match_InvalidGPR64shifted32:
6146 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
6147 case Match_InvalidGPR64shifted64:
6148 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
6149 case Match_InvalidGPR64shifted128:
6151 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
6152 case Match_InvalidGPR64NoXZRshifted8:
6153 return Error(Loc,
"register must be x0..x30 without shift");
6154 case Match_InvalidGPR64NoXZRshifted16:
6155 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
6156 case Match_InvalidGPR64NoXZRshifted32:
6157 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
6158 case Match_InvalidGPR64NoXZRshifted64:
6159 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
6160 case Match_InvalidGPR64NoXZRshifted128:
6161 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
6162 case Match_InvalidZPR32UXTW8:
6163 case Match_InvalidZPR32SXTW8:
6164 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
6165 case Match_InvalidZPR32UXTW16:
6166 case Match_InvalidZPR32SXTW16:
6167 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
6168 case Match_InvalidZPR32UXTW32:
6169 case Match_InvalidZPR32SXTW32:
6170 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
6171 case Match_InvalidZPR32UXTW64:
6172 case Match_InvalidZPR32SXTW64:
6173 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
6174 case Match_InvalidZPR64UXTW8:
6175 case Match_InvalidZPR64SXTW8:
6176 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
6177 case Match_InvalidZPR64UXTW16:
6178 case Match_InvalidZPR64SXTW16:
6179 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
6180 case Match_InvalidZPR64UXTW32:
6181 case Match_InvalidZPR64SXTW32:
6182 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
6183 case Match_InvalidZPR64UXTW64:
6184 case Match_InvalidZPR64SXTW64:
6185 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
6186 case Match_InvalidZPR32LSL8:
6187 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
6188 case Match_InvalidZPR32LSL16:
6189 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
6190 case Match_InvalidZPR32LSL32:
6191 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
6192 case Match_InvalidZPR32LSL64:
6193 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
6194 case Match_InvalidZPR64LSL8:
6195 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
6196 case Match_InvalidZPR64LSL16:
6197 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
6198 case Match_InvalidZPR64LSL32:
6199 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
6200 case Match_InvalidZPR64LSL64:
6201 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
6202 case Match_InvalidZPR0:
6203 return Error(Loc,
"expected register without element width suffix");
6204 case Match_InvalidZPR8:
6205 case Match_InvalidZPR16:
6206 case Match_InvalidZPR32:
6207 case Match_InvalidZPR64:
6208 case Match_InvalidZPR128:
6209 return Error(Loc,
"invalid element width");
6210 case Match_InvalidZPR_3b8:
6211 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6212 case Match_InvalidZPR_3b16:
6213 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6214 case Match_InvalidZPR_3b32:
6215 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6216 case Match_InvalidZPR_4b8:
6218 "Invalid restricted vector register, expected z0.b..z15.b");
6219 case Match_InvalidZPR_4b16:
6220 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6221 case Match_InvalidZPR_4b32:
6222 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6223 case Match_InvalidZPR_4b64:
6224 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6225 case Match_InvalidZPRMul2_Lo8:
6226 return Error(Loc,
"Invalid restricted vector register, expected even "
6227 "register in z0.b..z14.b");
6228 case Match_InvalidZPRMul2_Hi8:
6229 return Error(Loc,
"Invalid restricted vector register, expected even "
6230 "register in z16.b..z30.b");
6231 case Match_InvalidZPRMul2_Lo16:
6232 return Error(Loc,
"Invalid restricted vector register, expected even "
6233 "register in z0.h..z14.h");
6234 case Match_InvalidZPRMul2_Hi16:
6235 return Error(Loc,
"Invalid restricted vector register, expected even "
6236 "register in z16.h..z30.h");
6237 case Match_InvalidZPRMul2_Lo32:
6238 return Error(Loc,
"Invalid restricted vector register, expected even "
6239 "register in z0.s..z14.s");
6240 case Match_InvalidZPRMul2_Hi32:
6241 return Error(Loc,
"Invalid restricted vector register, expected even "
6242 "register in z16.s..z30.s");
6243 case Match_InvalidZPRMul2_Lo64:
6244 return Error(Loc,
"Invalid restricted vector register, expected even "
6245 "register in z0.d..z14.d");
6246 case Match_InvalidZPRMul2_Hi64:
6247 return Error(Loc,
"Invalid restricted vector register, expected even "
6248 "register in z16.d..z30.d");
6249 case Match_InvalidZPR_K0:
6250 return Error(Loc,
"invalid restricted vector register, expected register "
6251 "in z20..z23 or z28..z31");
6252 case Match_InvalidSVEPattern:
6253 return Error(Loc,
"invalid predicate pattern");
6254 case Match_InvalidSVEPPRorPNRAnyReg:
6255 case Match_InvalidSVEPPRorPNRBReg:
6256 case Match_InvalidSVEPredicateAnyReg:
6257 case Match_InvalidSVEPredicateBReg:
6258 case Match_InvalidSVEPredicateHReg:
6259 case Match_InvalidSVEPredicateSReg:
6260 case Match_InvalidSVEPredicateDReg:
6261 return Error(Loc,
"invalid predicate register.");
6262 case Match_InvalidSVEPredicate3bAnyReg:
6263 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6264 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6265 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6266 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6267 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6268 return Error(Loc,
"Invalid predicate register, expected PN in range "
6269 "pn8..pn15 with element suffix.");
6270 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6271 return Error(Loc,
"invalid restricted predicate-as-counter register "
6272 "expected pn8..pn15");
6273 case Match_InvalidSVEPNPredicateBReg:
6274 case Match_InvalidSVEPNPredicateHReg:
6275 case Match_InvalidSVEPNPredicateSReg:
6276 case Match_InvalidSVEPNPredicateDReg:
6277 return Error(Loc,
"Invalid predicate register, expected PN in range "
6278 "pn0..pn15 with element suffix.");
6279 case Match_InvalidSVEVecLenSpecifier:
6280 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6281 case Match_InvalidSVEPredicateListMul2x8:
6282 case Match_InvalidSVEPredicateListMul2x16:
6283 case Match_InvalidSVEPredicateListMul2x32:
6284 case Match_InvalidSVEPredicateListMul2x64:
6285 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6286 "predicate registers, where the first vector is a multiple of 2 "
6287 "and with correct element type");
6288 case Match_InvalidSVEExactFPImmOperandHalfOne:
6289 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6290 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6291 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6292 case Match_InvalidSVEExactFPImmOperandZeroOne:
6293 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6294 case Match_InvalidMatrixTileVectorH8:
6295 case Match_InvalidMatrixTileVectorV8:
6296 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6297 case Match_InvalidMatrixTileVectorH16:
6298 case Match_InvalidMatrixTileVectorV16:
6300 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6301 case Match_InvalidMatrixTileVectorH32:
6302 case Match_InvalidMatrixTileVectorV32:
6304 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6305 case Match_InvalidMatrixTileVectorH64:
6306 case Match_InvalidMatrixTileVectorV64:
6308 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6309 case Match_InvalidMatrixTileVectorH128:
6310 case Match_InvalidMatrixTileVectorV128:
6312 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6313 case Match_InvalidMatrixTile16:
6314 return Error(Loc,
"invalid matrix operand, expected za[0-1].h");
6315 case Match_InvalidMatrixTile32:
6316 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6317 case Match_InvalidMatrixTile64:
6318 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6319 case Match_InvalidMatrix:
6320 return Error(Loc,
"invalid matrix operand, expected za");
6321 case Match_InvalidMatrix8:
6322 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6323 case Match_InvalidMatrix16:
6324 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6325 case Match_InvalidMatrix32:
6326 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6327 case Match_InvalidMatrix64:
6328 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6329 case Match_InvalidMatrixIndexGPR32_12_15:
6330 return Error(Loc,
"operand must be a register in range [w12, w15]");
6331 case Match_InvalidMatrixIndexGPR32_8_11:
6332 return Error(Loc,
"operand must be a register in range [w8, w11]");
6333 case Match_InvalidSVEVectorList2x8Mul2:
6334 case Match_InvalidSVEVectorList2x16Mul2:
6335 case Match_InvalidSVEVectorList2x32Mul2:
6336 case Match_InvalidSVEVectorList2x64Mul2:
6337 case Match_InvalidSVEVectorList2x128Mul2:
6338 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6339 "SVE vectors, where the first vector is a multiple of 2 "
6340 "and with matching element types");
6341 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6342 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6343 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6344 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6345 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6346 "SVE vectors in the range z0-z14, where the first vector "
6347 "is a multiple of 2 "
6348 "and with matching element types");
6349 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6350 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6351 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6352 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6354 "Invalid vector list, expected list with 2 consecutive "
6355 "SVE vectors in the range z16-z30, where the first vector "
6356 "is a multiple of 2 "
6357 "and with matching element types");
6358 case Match_InvalidSVEVectorList4x8Mul4:
6359 case Match_InvalidSVEVectorList4x16Mul4:
6360 case Match_InvalidSVEVectorList4x32Mul4:
6361 case Match_InvalidSVEVectorList4x64Mul4:
6362 case Match_InvalidSVEVectorList4x128Mul4:
6363 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6364 "SVE vectors, where the first vector is a multiple of 4 "
6365 "and with matching element types");
6366 case Match_InvalidLookupTable:
6367 return Error(Loc,
"Invalid lookup table, expected zt0");
6368 case Match_InvalidSVEVectorListStrided2x8:
6369 case Match_InvalidSVEVectorListStrided2x16:
6370 case Match_InvalidSVEVectorListStrided2x32:
6371 case Match_InvalidSVEVectorListStrided2x64:
6374 "Invalid vector list, expected list with each SVE vector in the list "
6375 "8 registers apart, and the first register in the range [z0, z7] or "
6376 "[z16, z23] and with correct element type");
6377 case Match_InvalidSVEVectorListStrided4x8:
6378 case Match_InvalidSVEVectorListStrided4x16:
6379 case Match_InvalidSVEVectorListStrided4x32:
6380 case Match_InvalidSVEVectorListStrided4x64:
6383 "Invalid vector list, expected list with each SVE vector in the list "
6384 "4 registers apart, and the first register in the range [z0, z3] or "
6385 "[z16, z19] and with correct element type");
6386 case Match_AddSubLSLImm3ShiftLarge:
6388 "expected 'lsl' with optional integer in range [0, 7]");
6396bool AArch64AsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6400 bool MatchingInlineAsm) {
6402 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6403 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6406 unsigned NumOperands =
Operands.size();
6408 if (NumOperands == 4 && Tok ==
"lsl") {
6409 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6410 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6411 if (Op2.isScalarReg() && Op3.isImm()) {
6417 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6419 NewOp3Val = (32 - Op3Val) & 0x1f;
6420 NewOp4Val = 31 - Op3Val;
6422 NewOp3Val = (64 - Op3Val) & 0x3f;
6423 NewOp4Val = 63 - Op3Val;
6430 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
getContext());
6431 Operands.push_back(AArch64Operand::CreateImm(
6432 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(),
getContext()));
6433 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6437 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6439 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6440 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6441 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6443 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6447 if (LSBCE && WidthCE) {
6449 uint64_t Width = WidthCE->
getValue();
6451 uint64_t RegWidth = 0;
6452 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6458 if (LSB >= RegWidth)
6459 return Error(LSBOp.getStartLoc(),
6460 "expected integer in range [0, 31]");
6461 if (Width < 1 || Width > RegWidth)
6462 return Error(WidthOp.getStartLoc(),
6463 "expected integer in range [1, 32]");
6467 ImmR = (32 - LSB) & 0x1f;
6469 ImmR = (64 - LSB) & 0x3f;
6471 uint64_t ImmS = Width - 1;
6473 if (ImmR != 0 && ImmS >= ImmR)
6474 return Error(WidthOp.getStartLoc(),
6475 "requested insert overflows register");
6480 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
getContext());
6481 Operands[2] = AArch64Operand::CreateReg(
6482 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6484 Operands[3] = AArch64Operand::CreateImm(
6485 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(),
getContext());
6487 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6491 }
else if (NumOperands == 5) {
6494 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6495 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6496 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6497 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6499 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6503 if (Op3CE && Op4CE) {
6504 uint64_t Op3Val = Op3CE->
getValue();
6505 uint64_t Op4Val = Op4CE->
getValue();
6507 uint64_t RegWidth = 0;
6508 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6514 if (Op3Val >= RegWidth)
6515 return Error(Op3.getStartLoc(),
6516 "expected integer in range [0, 31]");
6517 if (Op4Val < 1 || Op4Val > RegWidth)
6518 return Error(Op4.getStartLoc(),
6519 "expected integer in range [1, 32]");
6521 uint64_t NewOp3Val = 0;
6523 NewOp3Val = (32 - Op3Val) & 0x1f;
6525 NewOp3Val = (64 - Op3Val) & 0x3f;
6527 uint64_t NewOp4Val = Op4Val - 1;
6529 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6530 return Error(Op4.getStartLoc(),
6531 "requested insert overflows register");
6533 const MCExpr *NewOp3 =
6535 const MCExpr *NewOp4 =
6537 Operands[3] = AArch64Operand::CreateImm(
6538 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(),
getContext());
6539 Operands[4] = AArch64Operand::CreateImm(
6540 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6542 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6544 else if (Tok ==
"sbfiz")
6545 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6547 else if (Tok ==
"ubfiz")
6548 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6557 }
else if (NumOperands == 5 &&
6558 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6559 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6560 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6561 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6563 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6567 if (Op3CE && Op4CE) {
6568 uint64_t Op3Val = Op3CE->
getValue();
6569 uint64_t Op4Val = Op4CE->
getValue();
6571 uint64_t RegWidth = 0;
6572 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6578 if (Op3Val >= RegWidth)
6579 return Error(Op3.getStartLoc(),
6580 "expected integer in range [0, 31]");
6581 if (Op4Val < 1 || Op4Val > RegWidth)
6582 return Error(Op4.getStartLoc(),
6583 "expected integer in range [1, 32]");
6585 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6587 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6588 return Error(Op4.getStartLoc(),
6589 "requested extract overflows register");
6591 const MCExpr *NewOp4 =
6593 Operands[4] = AArch64Operand::CreateImm(
6594 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(),
getContext());
6596 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6598 else if (Tok ==
"sbfx")
6599 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6601 else if (Tok ==
"ubfx")
6602 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6615 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6616 NumOperands == 4 && Tok ==
"movi") {
6617 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6618 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6619 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6620 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6621 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6622 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6623 if (Suffix.
lower() ==
".2d" &&
6625 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6626 " correctly on this CPU, converting to equivalent movi.16b");
6628 unsigned Idx = Op1.isToken() ? 1 : 2;
6630 AArch64Operand::CreateToken(
".16b", IDLoc,
getContext());
6638 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6641 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6642 if (
Op.isScalarReg()) {
6644 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6645 Op.getStartLoc(),
Op.getEndLoc(),
6650 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6651 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6652 if (
Op.isScalarReg() &&
6653 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6657 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6658 if (
Op.isScalarReg()) {
6660 Operands[2] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6667 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6668 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6669 if (
Op.isScalarReg() &&
6670 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6674 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6675 if (
Op.isScalarReg()) {
6677 Operands[1] = AArch64Operand::CreateReg(
Reg, RegKind::Scalar,
6685 FeatureBitset MissingFeatures;
6688 unsigned MatchResult =
6689 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6690 MatchingInlineAsm, 1);
6694 if (MatchResult != Match_Success) {
6697 auto ShortFormNEONErrorInfo = ErrorInfo;
6698 auto ShortFormNEONMatchResult = MatchResult;
6699 auto ShortFormNEONMissingFeatures = MissingFeatures;
6702 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
6703 MatchingInlineAsm, 0);
6708 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
6710 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6711 MatchResult = ShortFormNEONMatchResult;
6712 ErrorInfo = ShortFormNEONErrorInfo;
6713 MissingFeatures = ShortFormNEONMissingFeatures;
6717 switch (MatchResult) {
6718 case Match_Success: {
6722 for (
unsigned i = 1; i < NumOperands; ++i)
6724 if (validateInstruction(Inst, IDLoc, OperandLocs))
6731 case Match_MissingFeature: {
6732 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6735 std::string Msg =
"instruction requires:";
6736 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6737 if (MissingFeatures[i]) {
6742 return Error(IDLoc, Msg);
6744 case Match_MnemonicFail:
6745 return showMatchError(IDLoc, MatchResult, ErrorInfo,
Operands);
6746 case Match_InvalidOperand: {
6747 SMLoc ErrorLoc = IDLoc;
6749 if (ErrorInfo != ~0ULL) {
6751 return Error(IDLoc,
"too few operands for instruction",
6752 SMRange(IDLoc, getTok().getLoc()));
6754 ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6755 if (ErrorLoc == SMLoc())
6760 if (((AArch64Operand &)*
Operands[ErrorInfo]).isToken() &&
6761 ((AArch64Operand &)*
Operands[ErrorInfo]).isTokenSuffix())
6762 MatchResult = Match_InvalidSuffix;
6764 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
6766 case Match_InvalidTiedOperand:
6767 case Match_InvalidMemoryIndexed1:
6768 case Match_InvalidMemoryIndexed2:
6769 case Match_InvalidMemoryIndexed4:
6770 case Match_InvalidMemoryIndexed8:
6771 case Match_InvalidMemoryIndexed16:
6772 case Match_InvalidCondCode:
6773 case Match_AddSubLSLImm3ShiftLarge:
6774 case Match_AddSubRegExtendSmall:
6775 case Match_AddSubRegExtendLarge:
6776 case Match_AddSubSecondSource:
6777 case Match_LogicalSecondSource:
6778 case Match_AddSubRegShift32:
6779 case Match_AddSubRegShift64:
6780 case Match_InvalidMovImm32Shift:
6781 case Match_InvalidMovImm64Shift:
6782 case Match_InvalidFPImm:
6783 case Match_InvalidMemoryWExtend8:
6784 case Match_InvalidMemoryWExtend16:
6785 case Match_InvalidMemoryWExtend32:
6786 case Match_InvalidMemoryWExtend64:
6787 case Match_InvalidMemoryWExtend128:
6788 case Match_InvalidMemoryXExtend8:
6789 case Match_InvalidMemoryXExtend16:
6790 case Match_InvalidMemoryXExtend32:
6791 case Match_InvalidMemoryXExtend64:
6792 case Match_InvalidMemoryXExtend128:
6793 case Match_InvalidMemoryIndexed1SImm4:
6794 case Match_InvalidMemoryIndexed2SImm4:
6795 case Match_InvalidMemoryIndexed3SImm4:
6796 case Match_InvalidMemoryIndexed4SImm4:
6797 case Match_InvalidMemoryIndexed1SImm6:
6798 case Match_InvalidMemoryIndexed16SImm4:
6799 case Match_InvalidMemoryIndexed32SImm4:
6800 case Match_InvalidMemoryIndexed4SImm7:
6801 case Match_InvalidMemoryIndexed8SImm7:
6802 case Match_InvalidMemoryIndexed16SImm7:
6803 case Match_InvalidMemoryIndexed8UImm5:
6804 case Match_InvalidMemoryIndexed8UImm3:
6805 case Match_InvalidMemoryIndexed4UImm5:
6806 case Match_InvalidMemoryIndexed2UImm5:
6807 case Match_InvalidMemoryIndexed1UImm6:
6808 case Match_InvalidMemoryIndexed2UImm6:
6809 case Match_InvalidMemoryIndexed4UImm6:
6810 case Match_InvalidMemoryIndexed8UImm6:
6811 case Match_InvalidMemoryIndexed16UImm6:
6812 case Match_InvalidMemoryIndexedSImm6:
6813 case Match_InvalidMemoryIndexedSImm5:
6814 case Match_InvalidMemoryIndexedSImm8:
6815 case Match_InvalidMemoryIndexedSImm9:
6816 case Match_InvalidMemoryIndexed16SImm9:
6817 case Match_InvalidMemoryIndexed8SImm10:
6818 case Match_InvalidImm0_0:
6819 case Match_InvalidImm0_1:
6820 case Match_InvalidImm0_3:
6821 case Match_InvalidImm0_7:
6822 case Match_InvalidImm0_15:
6823 case Match_InvalidImm0_31:
6824 case Match_InvalidImm0_63:
6825 case Match_InvalidImm0_127:
6826 case Match_InvalidImm0_255:
6827 case Match_InvalidImm0_65535:
6828 case Match_InvalidImm1_8:
6829 case Match_InvalidImm1_16:
6830 case Match_InvalidImm1_32:
6831 case Match_InvalidImm1_64:
6832 case Match_InvalidImmM1_62:
6833 case Match_InvalidMemoryIndexedRange2UImm0:
6834 case Match_InvalidMemoryIndexedRange2UImm1:
6835 case Match_InvalidMemoryIndexedRange2UImm2:
6836 case Match_InvalidMemoryIndexedRange2UImm3:
6837 case Match_InvalidMemoryIndexedRange4UImm0:
6838 case Match_InvalidMemoryIndexedRange4UImm1:
6839 case Match_InvalidMemoryIndexedRange4UImm2:
6840 case Match_InvalidSVEAddSubImm8:
6841 case Match_InvalidSVEAddSubImm16:
6842 case Match_InvalidSVEAddSubImm32:
6843 case Match_InvalidSVEAddSubImm64:
6844 case Match_InvalidSVECpyImm8:
6845 case Match_InvalidSVECpyImm16:
6846 case Match_InvalidSVECpyImm32:
6847 case Match_InvalidSVECpyImm64:
6848 case Match_InvalidIndexRange0_0:
6849 case Match_InvalidIndexRange1_1:
6850 case Match_InvalidIndexRange0_15:
6851 case Match_InvalidIndexRange0_7:
6852 case Match_InvalidIndexRange0_3:
6853 case Match_InvalidIndexRange0_1:
6854 case Match_InvalidSVEIndexRange0_63:
6855 case Match_InvalidSVEIndexRange0_31:
6856 case Match_InvalidSVEIndexRange0_15:
6857 case Match_InvalidSVEIndexRange0_7:
6858 case Match_InvalidSVEIndexRange0_3:
6859 case Match_InvalidLabel:
6860 case Match_InvalidComplexRotationEven:
6861 case Match_InvalidComplexRotationOdd:
6862 case Match_InvalidGPR64shifted8:
6863 case Match_InvalidGPR64shifted16:
6864 case Match_InvalidGPR64shifted32:
6865 case Match_InvalidGPR64shifted64:
6866 case Match_InvalidGPR64shifted128:
6867 case Match_InvalidGPR64NoXZRshifted8:
6868 case Match_InvalidGPR64NoXZRshifted16:
6869 case Match_InvalidGPR64NoXZRshifted32:
6870 case Match_InvalidGPR64NoXZRshifted64:
6871 case Match_InvalidGPR64NoXZRshifted128:
6872 case Match_InvalidZPR32UXTW8:
6873 case Match_InvalidZPR32UXTW16:
6874 case Match_InvalidZPR32UXTW32:
6875 case Match_InvalidZPR32UXTW64:
6876 case Match_InvalidZPR32SXTW8:
6877 case Match_InvalidZPR32SXTW16:
6878 case Match_InvalidZPR32SXTW32:
6879 case Match_InvalidZPR32SXTW64:
6880 case Match_InvalidZPR64UXTW8:
6881 case Match_InvalidZPR64SXTW8:
6882 case Match_InvalidZPR64UXTW16:
6883 case Match_InvalidZPR64SXTW16:
6884 case Match_InvalidZPR64UXTW32:
6885 case Match_InvalidZPR64SXTW32:
6886 case Match_InvalidZPR64UXTW64:
6887 case Match_InvalidZPR64SXTW64:
6888 case Match_InvalidZPR32LSL8:
6889 case Match_InvalidZPR32LSL16:
6890 case Match_InvalidZPR32LSL32:
6891 case Match_InvalidZPR32LSL64:
6892 case Match_InvalidZPR64LSL8:
6893 case Match_InvalidZPR64LSL16:
6894 case Match_InvalidZPR64LSL32:
6895 case Match_InvalidZPR64LSL64:
6896 case Match_InvalidZPR0:
6897 case Match_InvalidZPR8:
6898 case Match_InvalidZPR16:
6899 case Match_InvalidZPR32:
6900 case Match_InvalidZPR64:
6901 case Match_InvalidZPR128:
6902 case Match_InvalidZPR_3b8:
6903 case Match_InvalidZPR_3b16:
6904 case Match_InvalidZPR_3b32:
6905 case Match_InvalidZPR_4b8:
6906 case Match_InvalidZPR_4b16:
6907 case Match_InvalidZPR_4b32:
6908 case Match_InvalidZPR_4b64:
6909 case Match_InvalidSVEPPRorPNRAnyReg:
6910 case Match_InvalidSVEPPRorPNRBReg:
6911 case Match_InvalidSVEPredicateAnyReg:
6912 case Match_InvalidSVEPattern:
6913 case Match_InvalidSVEVecLenSpecifier:
6914 case Match_InvalidSVEPredicateBReg:
6915 case Match_InvalidSVEPredicateHReg:
6916 case Match_InvalidSVEPredicateSReg:
6917 case Match_InvalidSVEPredicateDReg:
6918 case Match_InvalidSVEPredicate3bAnyReg:
6919 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6920 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6921 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6922 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6923 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6924 case Match_InvalidSVEPNPredicateBReg:
6925 case Match_InvalidSVEPNPredicateHReg:
6926 case Match_InvalidSVEPNPredicateSReg:
6927 case Match_InvalidSVEPNPredicateDReg:
6928 case Match_InvalidSVEPredicateListMul2x8:
6929 case Match_InvalidSVEPredicateListMul2x16:
6930 case Match_InvalidSVEPredicateListMul2x32:
6931 case Match_InvalidSVEPredicateListMul2x64:
6932 case Match_InvalidSVEExactFPImmOperandHalfOne:
6933 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6934 case Match_InvalidSVEExactFPImmOperandZeroOne:
6935 case Match_InvalidMatrixTile16:
6936 case Match_InvalidMatrixTile32:
6937 case Match_InvalidMatrixTile64:
6938 case Match_InvalidMatrix:
6939 case Match_InvalidMatrix8:
6940 case Match_InvalidMatrix16:
6941 case Match_InvalidMatrix32:
6942 case Match_InvalidMatrix64:
6943 case Match_InvalidMatrixTileVectorH8:
6944 case Match_InvalidMatrixTileVectorH16:
6945 case Match_InvalidMatrixTileVectorH32:
6946 case Match_InvalidMatrixTileVectorH64:
6947 case Match_InvalidMatrixTileVectorH128:
6948 case Match_InvalidMatrixTileVectorV8:
6949 case Match_InvalidMatrixTileVectorV16:
6950 case Match_InvalidMatrixTileVectorV32:
6951 case Match_InvalidMatrixTileVectorV64:
6952 case Match_InvalidMatrixTileVectorV128:
6953 case Match_InvalidSVCR:
6954 case Match_InvalidMatrixIndexGPR32_12_15:
6955 case Match_InvalidMatrixIndexGPR32_8_11:
6956 case Match_InvalidLookupTable:
6957 case Match_InvalidZPRMul2_Lo8:
6958 case Match_InvalidZPRMul2_Hi8:
6959 case Match_InvalidZPRMul2_Lo16:
6960 case Match_InvalidZPRMul2_Hi16:
6961 case Match_InvalidZPRMul2_Lo32:
6962 case Match_InvalidZPRMul2_Hi32:
6963 case Match_InvalidZPRMul2_Lo64:
6964 case Match_InvalidZPRMul2_Hi64:
6965 case Match_InvalidZPR_K0:
6966 case Match_InvalidSVEVectorList2x8Mul2:
6967 case Match_InvalidSVEVectorList2x16Mul2:
6968 case Match_InvalidSVEVectorList2x32Mul2:
6969 case Match_InvalidSVEVectorList2x64Mul2:
6970 case Match_InvalidSVEVectorList2x128Mul2:
6971 case Match_InvalidSVEVectorList4x8Mul4:
6972 case Match_InvalidSVEVectorList4x16Mul4:
6973 case Match_InvalidSVEVectorList4x32Mul4:
6974 case Match_InvalidSVEVectorList4x64Mul4:
6975 case Match_InvalidSVEVectorList4x128Mul4:
6976 case Match_InvalidSVEVectorList2x8Mul2_Lo:
6977 case Match_InvalidSVEVectorList2x16Mul2_Lo:
6978 case Match_InvalidSVEVectorList2x32Mul2_Lo:
6979 case Match_InvalidSVEVectorList2x64Mul2_Lo:
6980 case Match_InvalidSVEVectorList2x8Mul2_Hi:
6981 case Match_InvalidSVEVectorList2x16Mul2_Hi:
6982 case Match_InvalidSVEVectorList2x32Mul2_Hi:
6983 case Match_InvalidSVEVectorList2x64Mul2_Hi:
6984 case Match_InvalidSVEVectorListStrided2x8:
6985 case Match_InvalidSVEVectorListStrided2x16:
6986 case Match_InvalidSVEVectorListStrided2x32:
6987 case Match_InvalidSVEVectorListStrided2x64:
6988 case Match_InvalidSVEVectorListStrided4x8:
6989 case Match_InvalidSVEVectorListStrided4x16:
6990 case Match_InvalidSVEVectorListStrided4x32:
6991 case Match_InvalidSVEVectorListStrided4x64:
6995 return Error(IDLoc,
"too few operands for instruction", SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6998 SMLoc ErrorLoc = ((AArch64Operand &)*
Operands[ErrorInfo]).getStartLoc();
6999 if (ErrorLoc == SMLoc())
7001 return showMatchError(ErrorLoc, MatchResult, ErrorInfo,
Operands);
7009bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
7016 SMLoc Loc = DirectiveID.
getLoc();
7017 if (IDVal ==
".arch")
7018 parseDirectiveArch(Loc);
7019 else if (IDVal ==
".cpu")
7020 parseDirectiveCPU(Loc);
7021 else if (IDVal ==
".tlsdesccall")
7022 parseDirectiveTLSDescCall(Loc);
7023 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
7024 parseDirectiveLtorg(Loc);
7025 else if (IDVal ==
".unreq")
7026 parseDirectiveUnreq(Loc);
7027 else if (IDVal ==
".inst")
7028 parseDirectiveInst(Loc);
7029 else if (IDVal ==
".cfi_negate_ra_state")
7030 parseDirectiveCFINegateRAState();
7031 else if (IDVal ==
".cfi_negate_ra_state_with_pc")
7032 parseDirectiveCFINegateRAStateWithPC();
7033 else if (IDVal ==
".cfi_b_key_frame")
7034 parseDirectiveCFIBKeyFrame();
7035 else if (IDVal ==
".cfi_mte_tagged_frame")
7036 parseDirectiveCFIMTETaggedFrame();
7037 else if (IDVal ==
".arch_extension")
7038 parseDirectiveArchExtension(Loc);
7039 else if (IDVal ==
".variant_pcs")
7040 parseDirectiveVariantPCS(Loc);
7043 parseDirectiveLOH(IDVal, Loc);
7046 }
else if (IsCOFF) {
7047 if (IDVal ==
".seh_stackalloc")
7048 parseDirectiveSEHAllocStack(Loc);
7049 else if (IDVal ==
".seh_endprologue")
7050 parseDirectiveSEHPrologEnd(Loc);
7051 else if (IDVal ==
".seh_save_r19r20_x")
7052 parseDirectiveSEHSaveR19R20X(Loc);
7053 else if (IDVal ==
".seh_save_fplr")
7054 parseDirectiveSEHSaveFPLR(Loc);
7055 else if (IDVal ==
".seh_save_fplr_x")
7056 parseDirectiveSEHSaveFPLRX(Loc);
7057 else if (IDVal ==
".seh_save_reg")
7058 parseDirectiveSEHSaveReg(Loc);
7059 else if (IDVal ==
".seh_save_reg_x")
7060 parseDirectiveSEHSaveRegX(Loc);
7061 else if (IDVal ==
".seh_save_regp")
7062 parseDirectiveSEHSaveRegP(Loc);
7063 else if (IDVal ==
".seh_save_regp_x")
7064 parseDirectiveSEHSaveRegPX(Loc);
7065 else if (IDVal ==
".seh_save_lrpair")
7066 parseDirectiveSEHSaveLRPair(Loc);
7067 else if (IDVal ==
".seh_save_freg")
7068 parseDirectiveSEHSaveFReg(Loc);
7069 else if (IDVal ==
".seh_save_freg_x")
7070 parseDirectiveSEHSaveFRegX(Loc);
7071 else if (IDVal ==
".seh_save_fregp")
7072 parseDirectiveSEHSaveFRegP(Loc);
7073 else if (IDVal ==
".seh_save_fregp_x")
7074 parseDirectiveSEHSaveFRegPX(Loc);
7075 else if (IDVal ==
".seh_set_fp")
7076 parseDirectiveSEHSetFP(Loc);
7077 else if (IDVal ==
".seh_add_fp")
7078 parseDirectiveSEHAddFP(Loc);
7079 else if (IDVal ==
".seh_nop")
7080 parseDirectiveSEHNop(Loc);
7081 else if (IDVal ==
".seh_save_next")
7082 parseDirectiveSEHSaveNext(Loc);
7083 else if (IDVal ==
".seh_startepilogue")
7084 parseDirectiveSEHEpilogStart(Loc);
7085 else if (IDVal ==
".seh_endepilogue")
7086 parseDirectiveSEHEpilogEnd(Loc);
7087 else if (IDVal ==
".seh_trap_frame")
7088 parseDirectiveSEHTrapFrame(Loc);
7089 else if (IDVal ==
".seh_pushframe")
7090 parseDirectiveSEHMachineFrame(Loc);
7091 else if (IDVal ==
".seh_context")
7092 parseDirectiveSEHContext(Loc);
7093 else if (IDVal ==
".seh_ec_context")
7094 parseDirectiveSEHECContext(Loc);
7095 else if (IDVal ==
".seh_clear_unwound_to_call")
7096 parseDirectiveSEHClearUnwoundToCall(Loc);
7097 else if (IDVal ==
".seh_pac_sign_lr")
7098 parseDirectiveSEHPACSignLR(Loc);
7099 else if (IDVal ==
".seh_save_any_reg")
7100 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
7101 else if (IDVal ==
".seh_save_any_reg_p")
7102 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
7103 else if (IDVal ==
".seh_save_any_reg_x")
7104 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
7105 else if (IDVal ==
".seh_save_any_reg_px")
7106 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
7107 else if (IDVal ==
".seh_allocz")
7108 parseDirectiveSEHAllocZ(Loc);
7109 else if (IDVal ==
".seh_save_zreg")
7110 parseDirectiveSEHSaveZReg(Loc);
7111 else if (IDVal ==
".seh_save_preg")
7112 parseDirectiveSEHSavePReg(Loc);
7116 if (IDVal ==
".aeabi_subsection")
7117 parseDirectiveAeabiSubSectionHeader(Loc);
7118 else if (IDVal ==
".aeabi_attribute")
7119 parseDirectiveAeabiAArch64Attr(Loc);
7132 if (!NoCrypto && Crypto) {
7135 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7136 ArchInfo == AArch64::ARMV8_3A) {
7140 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7141 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7142 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7143 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7144 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7145 ArchInfo == AArch64::ARMV9_4A || ArchInfo == AArch64::ARMV8R) {
7151 }
else if (NoCrypto) {
7154 if (ArchInfo == AArch64::ARMV8_1A || ArchInfo == AArch64::ARMV8_2A ||
7155 ArchInfo == AArch64::ARMV8_3A) {
7156 RequestedExtensions.
push_back(
"nosha2");
7159 if (ArchInfo == AArch64::ARMV8_4A || ArchInfo == AArch64::ARMV8_5A ||
7160 ArchInfo == AArch64::ARMV8_6A || ArchInfo == AArch64::ARMV8_7A ||
7161 ArchInfo == AArch64::ARMV8_8A || ArchInfo == AArch64::ARMV8_9A ||
7162 ArchInfo == AArch64::ARMV9A || ArchInfo == AArch64::ARMV9_1A ||
7163 ArchInfo == AArch64::ARMV9_2A || ArchInfo == AArch64::ARMV9_3A ||
7164 ArchInfo == AArch64::ARMV9_4A) {
7166 RequestedExtensions.
push_back(
"nosha3");
7167 RequestedExtensions.
push_back(
"nosha2");
7179bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
7180 SMLoc CurLoc = getLoc();
7182 StringRef
Name = getParser().parseStringToEndOfStatement().trim();
7183 StringRef Arch, ExtensionString;
7184 std::tie(Arch, ExtensionString) =
Name.split(
'+');
7188 return Error(CurLoc,
"unknown arch name");
7194 std::vector<StringRef> AArch64Features;
7198 MCSubtargetInfo &STI = copySTI();
7199 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
7201 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
7204 if (!ExtensionString.
empty())
7205 ExtensionString.
split(RequestedExtensions,
'+');
7210 for (
auto Name : RequestedExtensions) {
7214 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7221 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7229 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7230 setAvailableFeatures(Features);
7232 getTargetStreamer().emitDirectiveArch(Name);
7238bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
7239 SMLoc ExtLoc = getLoc();
7241 StringRef FullName = getParser().parseStringToEndOfStatement().trim();
7246 bool EnableFeature =
true;
7247 StringRef
Name = FullName;
7248 if (
Name.starts_with_insensitive(
"no")) {
7249 EnableFeature =
false;
7258 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
7260 MCSubtargetInfo &STI = copySTI();
7265 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7266 setAvailableFeatures(Features);
7268 getTargetStreamer().emitDirectiveArchExtension(FullName);
7274bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
7275 SMLoc CurLoc = getLoc();
7277 StringRef CPU, ExtensionString;
7278 std::tie(CPU, ExtensionString) =
7279 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
7285 if (!ExtensionString.
empty())
7286 ExtensionString.
split(RequestedExtensions,
'+');
7290 Error(CurLoc,
"unknown CPU name");
7295 MCSubtargetInfo &STI = copySTI();
7299 for (
auto Name : RequestedExtensions) {
7303 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7310 return Error(CurLoc,
"unsupported architectural extension: " + Name);
7318 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
7319 setAvailableFeatures(Features);
7325bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
7327 return Error(Loc,
"expected expression following '.inst' directive");
7329 auto parseOp = [&]() ->
bool {
7331 const MCExpr *Expr =
nullptr;
7332 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
7335 if (check(!
Value, L,
"expected constant expression"))
7337 getTargetStreamer().emitInst(
Value->getValue());
7341 return parseMany(parseOp);
7346bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
7348 if (check(getParser().parseIdentifier(Name), L,
"expected symbol") ||
7360 getParser().getStreamer().emitInstruction(Inst, getSTI());
7366bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
7370 return TokError(
"expected an identifier or a number in directive");
7373 int64_t
Id = getTok().getIntVal();
7375 return TokError(
"invalid numeric identifier in directive");
7378 StringRef
Name = getTok().getIdentifier();
7384 return TokError(
"invalid identifier in directive");
7392 assert(NbArgs != -1 &&
"Invalid number of arguments");
7395 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
7397 if (getParser().parseIdentifier(Name))
7398 return TokError(
"expected identifier in directive");
7401 if (Idx + 1 == NbArgs)
7409 getStreamer().emitLOHDirective(Kind, Args);
7415bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
7418 getTargetStreamer().emitCurrentConstantPool();
7424bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7426 SMLoc SRegLoc = getLoc();
7427 RegKind RegisterKind = RegKind::Scalar;
7429 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7433 RegisterKind = RegKind::NeonVector;
7434 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7440 return Error(SRegLoc,
"vector register without type specifier expected");
7445 RegisterKind = RegKind::SVEDataVector;
7447 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7453 return Error(SRegLoc,
7454 "sve vector register without type specifier expected");
7459 RegisterKind = RegKind::SVEPredicateVector;
7460 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7466 return Error(SRegLoc,
7467 "sve predicate register without type specifier expected");
7471 return Error(SRegLoc,
"register name or alias expected");
7477 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7478 if (RegisterReqs.
insert(std::make_pair(Name, pair)).first->second != pair)
7479 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
7486bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
7488 return TokError(
"unexpected input in .unreq directive.");
7489 RegisterReqs.
erase(getTok().getIdentifier().lower());
7494bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7497 getStreamer().emitCFINegateRAState();
7501bool AArch64AsmParser::parseDirectiveCFINegateRAStateWithPC() {
7504 getStreamer().emitCFINegateRAStateWithPC();
7510bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7513 getStreamer().emitCFIBKeyFrame();
7519bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7522 getStreamer().emitCFIMTETaggedFrame();
7528bool AArch64AsmParser::parseDirectiveVariantPCS(SMLoc L) {
7530 if (getParser().parseIdentifier(Name))
7531 return TokError(
"expected symbol name");
7534 getTargetStreamer().emitDirectiveVariantPCS(
7541bool AArch64AsmParser::parseDirectiveSEHAllocStack(SMLoc L) {
7543 if (parseImmExpr(
Size))
7545 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7551bool AArch64AsmParser::parseDirectiveSEHPrologEnd(SMLoc L) {
7552 getTargetStreamer().emitARM64WinCFIPrologEnd();
7558bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(SMLoc L) {
7560 if (parseImmExpr(
Offset))
7562 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7568bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(SMLoc L) {
7570 if (parseImmExpr(
Offset))
7572 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7578bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(SMLoc L) {
7580 if (parseImmExpr(
Offset))
7582 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7588bool AArch64AsmParser::parseDirectiveSEHSaveReg(SMLoc L) {
7591 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7592 parseComma() || parseImmExpr(
Offset))
7594 getTargetStreamer().emitARM64WinCFISaveReg(
Reg,
Offset);
7600bool AArch64AsmParser::parseDirectiveSEHSaveRegX(SMLoc L) {
7603 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7604 parseComma() || parseImmExpr(
Offset))
7606 getTargetStreamer().emitARM64WinCFISaveRegX(
Reg,
Offset);
7612bool AArch64AsmParser::parseDirectiveSEHSaveRegP(SMLoc L) {
7615 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7616 parseComma() || parseImmExpr(
Offset))
7618 getTargetStreamer().emitARM64WinCFISaveRegP(
Reg,
Offset);
7624bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(SMLoc L) {
7627 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7628 parseComma() || parseImmExpr(
Offset))
7630 getTargetStreamer().emitARM64WinCFISaveRegPX(
Reg,
Offset);
7636bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(SMLoc L) {
7640 if (parseRegisterInRange(
Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7641 parseComma() || parseImmExpr(
Offset))
7643 if (check(((
Reg - 19) % 2 != 0), L,
7644 "expected register with even offset from x19"))
7646 getTargetStreamer().emitARM64WinCFISaveLRPair(
Reg,
Offset);
7652bool AArch64AsmParser::parseDirectiveSEHSaveFReg(SMLoc L) {
7655 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7656 parseComma() || parseImmExpr(
Offset))
7658 getTargetStreamer().emitARM64WinCFISaveFReg(
Reg,
Offset);
7664bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(SMLoc L) {
7667 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7668 parseComma() || parseImmExpr(
Offset))
7670 getTargetStreamer().emitARM64WinCFISaveFRegX(
Reg,
Offset);
7676bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(SMLoc L) {
7679 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7680 parseComma() || parseImmExpr(
Offset))
7682 getTargetStreamer().emitARM64WinCFISaveFRegP(
Reg,
Offset);
7688bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(SMLoc L) {
7691 if (parseRegisterInRange(
Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7692 parseComma() || parseImmExpr(
Offset))
7694 getTargetStreamer().emitARM64WinCFISaveFRegPX(
Reg,
Offset);
7700bool AArch64AsmParser::parseDirectiveSEHSetFP(SMLoc L) {
7701 getTargetStreamer().emitARM64WinCFISetFP();
7707bool AArch64AsmParser::parseDirectiveSEHAddFP(SMLoc L) {
7709 if (parseImmExpr(
Size))
7711 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7717bool AArch64AsmParser::parseDirectiveSEHNop(SMLoc L) {
7718 getTargetStreamer().emitARM64WinCFINop();
7724bool AArch64AsmParser::parseDirectiveSEHSaveNext(SMLoc L) {
7725 getTargetStreamer().emitARM64WinCFISaveNext();
7731bool AArch64AsmParser::parseDirectiveSEHEpilogStart(SMLoc L) {
7732 getTargetStreamer().emitARM64WinCFIEpilogStart();
7738bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
7739 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7745bool AArch64AsmParser::parseDirectiveSEHTrapFrame(SMLoc L) {
7746 getTargetStreamer().emitARM64WinCFITrapFrame();
7752bool AArch64AsmParser::parseDirectiveSEHMachineFrame(SMLoc L) {
7753 getTargetStreamer().emitARM64WinCFIMachineFrame();
7759bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
7760 getTargetStreamer().emitARM64WinCFIContext();
7766bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7767 getTargetStreamer().emitARM64WinCFIECContext();
7773bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
7774 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7780bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
7781 getTargetStreamer().emitARM64WinCFIPACSignLR();
7790bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L,
bool Paired,
7795 if (check(parseRegister(
Reg, Start, End), getLoc(),
"expected register") ||
7796 parseComma() || parseImmExpr(
Offset))
7799 if (
Reg == AArch64::FP ||
Reg == AArch64::LR ||
7800 (
Reg >= AArch64::X0 &&
Reg <= AArch64::X28)) {
7801 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7802 return Error(L,
"invalid save_any_reg offset");
7803 unsigned EncodedReg;
7804 if (
Reg == AArch64::FP)
7806 else if (
Reg == AArch64::LR)
7809 EncodedReg =
Reg - AArch64::X0;
7811 if (
Reg == AArch64::LR)
7812 return Error(Start,
"lr cannot be paired with another register");
7814 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7816 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7819 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7821 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7823 }
else if (
Reg >= AArch64::D0 &&
Reg <= AArch64::D31) {
7824 unsigned EncodedReg =
Reg - AArch64::D0;
7825 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7826 return Error(L,
"invalid save_any_reg offset");
7828 if (
Reg == AArch64::D31)
7829 return Error(Start,
"d31 cannot be paired with another register");
7831 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7833 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7836 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7838 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7840 }
else if (
Reg >= AArch64::Q0 &&
Reg <= AArch64::Q31) {
7841 unsigned EncodedReg =
Reg - AArch64::Q0;
7843 return Error(L,
"invalid save_any_reg offset");
7845 if (
Reg == AArch64::Q31)
7846 return Error(Start,
"q31 cannot be paired with another register");
7848 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7850 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7853 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7855 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7858 return Error(Start,
"save_any_reg register must be x, q or d register");
7865bool AArch64AsmParser::parseDirectiveSEHAllocZ(SMLoc L) {
7867 if (parseImmExpr(
Offset))
7869 getTargetStreamer().emitARM64WinCFIAllocZ(
Offset);
7875bool AArch64AsmParser::parseDirectiveSEHSaveZReg(SMLoc L) {
7880 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7883 if (check(RegNum < AArch64::Z8 || RegNum > AArch64::Z23, L,
7884 "expected register in range z8 to z23"))
7886 if (parseComma() || parseImmExpr(
Offset))
7888 getTargetStreamer().emitARM64WinCFISaveZReg(RegNum - AArch64::Z0,
Offset);
7894bool AArch64AsmParser::parseDirectiveSEHSavePReg(SMLoc L) {
7899 tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7902 if (check(RegNum < AArch64::P4 || RegNum > AArch64::P15, L,
7903 "expected register in range p4 to p15"))
7905 if (parseComma() || parseImmExpr(
Offset))
7907 getTargetStreamer().emitARM64WinCFISavePReg(RegNum - AArch64::P0,
Offset);
7911bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) {
7917 MCAsmParser &Parser = getParser();
7920 StringRef SubsectionName;
7931 std::unique_ptr<MCELFStreamer::AttributeSubSection> SubsectionExists =
7932 getTargetStreamer().getAttributesSubsectionByName(SubsectionName);
7937 if (SubsectionExists) {
7938 getTargetStreamer().emitAttributesSubsection(
7941 SubsectionExists->IsOptional),
7943 SubsectionExists->ParameterType));
7949 "Could not switch to subsection '" + SubsectionName +
7950 "' using subsection name, subsection has not been defined");
7973 if (SubsectionExists) {
7974 if (IsOptional != SubsectionExists->IsOptional) {
7976 "optionality mismatch! subsection '" + SubsectionName +
7977 "' already exists with optionality defined as '" +
7979 SubsectionExists->IsOptional) +
7987 "optionality parameter not found, expected required|optional");
7994 "aeabi_feature_and_bits must be marked as optional");
8001 "aeabi_pauthabi must be marked as required");
8021 if (SubsectionExists) {
8022 if (
Type != SubsectionExists->ParameterType) {
8024 "type mismatch! subsection '" + SubsectionName +
8025 "' already exists with type defined as '" +
8027 SubsectionExists->ParameterType) +
8035 "type parameter not found, expected uleb128|ntbs");
8043 SubsectionName +
" must be marked as ULEB128");
8052 "attributes subsection header directive");
8056 getTargetStreamer().emitAttributesSubsection(SubsectionName, IsOptional,
Type);
8061bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) {
8065 MCAsmParser &Parser = getParser();
8067 std::unique_ptr<MCELFStreamer::AttributeSubSection> ActiveSubsection =
8068 getTargetStreamer().getActiveAttributesSubsection();
8069 if (
nullptr == ActiveSubsection) {
8071 "no active subsection, build attribute can not be added");
8074 StringRef ActiveSubsectionName = ActiveSubsection->VendorName;
8075 unsigned ActiveSubsectionType = ActiveSubsection->ParameterType;
8083 ActiveSubsectionName)
8086 StringRef TagStr =
"";
8089 Tag = getTok().getIntVal();
8092 switch (ActiveSubsectionID) {
8097 "' \nExcept for public subsections, "
8098 "tags have to be an unsigned int.");
8105 TagStr +
"' for subsection '" +
8106 ActiveSubsectionName +
"'");
8114 TagStr +
"' for subsection '" +
8115 ActiveSubsectionName +
"'");
8133 unsigned ValueInt = unsigned(-1);
8134 std::string ValueStr =
"";
8139 "active subsection type is NTBS (string), found ULEB128 (unsigned)");
8142 ValueInt = getTok().getIntVal();
8147 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8155 "active subsection type is ULEB128 (unsigned), found NTBS (string)");
8166 if (0 != ValueInt && 1 != ValueInt) {
8168 "unknown AArch64 build attributes Value for Tag '" + TagStr +
8169 "' options are 0|1");
8178 "unexpected token for AArch64 build attributes tag and value "
8179 "attribute directive");
8183 if (
unsigned(-1) != ValueInt) {
8184 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag, ValueInt,
"");
8186 if (
"" != ValueStr) {
8187 getTargetStreamer().emitAttribute(ActiveSubsectionName,
Tag,
unsigned(-1),
8193bool AArch64AsmParser::parseDataExpr(
const MCExpr *&Res) {
8196 if (getParser().parseExpression(Res))
8198 MCAsmParser &Parser = getParser();
8202 return Error(getLoc(),
"expected relocation specifier");
8205 SMLoc Loc = getLoc();
8207 if (Identifier ==
"auth")
8208 return parseAuthExpr(Res, EndLoc);
8212 if (Identifier ==
"got")
8216 if (Identifier ==
"gotpcrel")
8218 else if (Identifier ==
"plt")
8222 return Error(Loc,
"invalid relocation specifier");
8227 return Error(Loc,
"@ specifier only allowed after a symbol");
8230 std::optional<MCBinaryExpr::Opcode> Opcode;
8238 if (getParser().parsePrimaryExpr(Term, EndLoc,
nullptr))
8249bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
8250 MCAsmParser &Parser = getParser();
8252 AsmToken Tok = Parser.
getTok();
8259 return TokError(
"expected key name");
8264 return TokError(
"invalid key '" + KeyStr +
"'");
8271 return TokError(
"expected integer discriminator");
8275 return TokError(
"integer discriminator " + Twine(Discriminator) +
8276 " out of range [0, 0xFFFF]");
8279 bool UseAddressDiversity =
false;
8284 return TokError(
"expected 'addr'");
8285 UseAddressDiversity =
true;
8294 UseAddressDiversity, Ctx, Res->
getLoc());
8298bool AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
8307 ELFSpec = AE->getSpecifier();
8308 Expr = AE->getSubExpr();
8348#define GET_REGISTER_MATCHER
8349#define GET_SUBTARGET_FEATURE_NAME
8350#define GET_MATCHER_IMPLEMENTATION
8351#define GET_MNEMONIC_SPELL_CHECKER
8352#include "AArch64GenAsmMatcher.inc"
8358 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
8360 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
8362 return Match_InvalidOperand;
8365 return Match_InvalidOperand;
8366 if (CE->getValue() == ExpectedVal)
8367 return Match_Success;
8368 return Match_InvalidOperand;
8373 return Match_InvalidOperand;
8379 if (
Op.isTokenEqual(
"za"))
8380 return Match_Success;
8381 return Match_InvalidOperand;
8387#define MATCH_HASH(N) \
8388 case MCK__HASH_##N: \
8389 return MatchesOpImmediate(N);
8415#define MATCH_HASH_MINUS(N) \
8416 case MCK__HASH__MINUS_##N: \
8417 return MatchesOpImmediate(-N);
8421#undef MATCH_HASH_MINUS
8430 return Error(S,
"expected register");
8432 MCRegister FirstReg;
8433 ParseStatus Res = tryParseScalarRegister(FirstReg);
8435 return Error(S,
"expected first even register of a consecutive same-size "
8436 "even/odd register pair");
8438 const MCRegisterClass &WRegClass =
8439 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
8440 const MCRegisterClass &XRegClass =
8441 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
8443 bool isXReg = XRegClass.
contains(FirstReg),
8444 isWReg = WRegClass.
contains(FirstReg);
8445 if (!isXReg && !isWReg)
8446 return Error(S,
"expected first even register of a consecutive same-size "
8447 "even/odd register pair");
8449 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
8452 if (FirstEncoding & 0x1)
8453 return Error(S,
"expected first even register of a consecutive same-size "
8454 "even/odd register pair");
8457 return Error(getLoc(),
"expected comma");
8462 MCRegister SecondReg;
8463 Res = tryParseScalarRegister(SecondReg);
8465 return Error(
E,
"expected second odd register of a consecutive same-size "
8466 "even/odd register pair");
8469 (isXReg && !XRegClass.
contains(SecondReg)) ||
8470 (isWReg && !WRegClass.
contains(SecondReg)))
8471 return Error(
E,
"expected second odd register of a consecutive same-size "
8472 "even/odd register pair");
8477 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
8480 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
8483 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
8489template <
bool ParseShiftExtend,
bool ParseSuffix>
8491 const SMLoc S = getLoc();
8497 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
8502 if (ParseSuffix &&
Kind.empty())
8509 unsigned ElementWidth = KindRes->second;
8513 Operands.push_back(AArch64Operand::CreateVectorReg(
8514 RegNum, RegKind::SVEDataVector, ElementWidth, S, S,
getContext()));
8516 ParseStatus Res = tryParseVectorIndex(
Operands);
8527 Res = tryParseOptionalShiftExtend(ExtOpnd);
8531 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().
get());
8532 Operands.push_back(AArch64Operand::CreateVectorReg(
8533 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
8535 Ext->hasShiftExtendAmount()));
8541 MCAsmParser &Parser = getParser();
8543 SMLoc
SS = getLoc();
8544 const AsmToken &TokE = getTok();
8555 const MCExpr *ImmVal;
8562 return TokError(
"invalid operand for instruction");
8567 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
8572 Pattern = Pat->Encoding;
8573 assert(Pattern >= 0 && Pattern < 32);
8586 SMLoc
SS = getLoc();
8587 const AsmToken &TokE = getTok();
8589 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
8595 Pattern = Pat->Encoding;
8596 assert(Pattern >= 0 && Pattern <= 1 &&
"Pattern does not exist");
8606 SMLoc
SS = getLoc();
8609 if (!tryParseScalarRegister(XReg).isSuccess())
8615 XReg, AArch64::x8sub_0,
8616 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
8619 "expected an even-numbered x-register in the range [x0,x22]");
8622 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8636 if (getParser().parseExpression(ImmF))
8646 SMLoc
E = getTok().getLoc();
8648 if (getParser().parseExpression(ImmL))
8655 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E,
getContext()));
8670 if (getParser().parseExpression(Ex))
8680 static_assert(Adj == 1 || Adj == -1,
"Unsafe immediate adjustment");
8687 Operands.push_back(AArch64Operand::CreateImm(
#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.
static unsigned matchMatrixRegName(StringRef Name)
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 const struct Extension ExtensionMap[]
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
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")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
loop data Loop Data Prefetch
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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.
constexpr size_t size() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual MCRegister getReg() const =0
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
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
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
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.
FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB)
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
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - 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.
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
empty - 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
size - Get the string size.
constexpr const char * data() const
data - 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
static constexpr size_t npos
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.
SubsectionType getTypeID(StringRef Type)
StringRef getVendorName(unsigned const Vendor)
StringRef getOptionalStr(unsigned Optional)
@ FEATURE_AND_BITS_TAG_NOT_FOUND
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
StringRef getSubsectionTypeUnknownError()
SubsectionOptional getOptionalID(StringRef Optional)
StringRef getSubsectionOptionalUnknownError()
FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag)
VendorID getVendorID(StringRef const Vendor)
PauthABITags getPauthABITagsID(StringRef PauthABITag)
StringRef getTypeStr(unsigned Type)
static CondCode getInvertedCondCode(CondCode Code)
const PHint * lookupPHintByName(StringRef)
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 ==...
LLVM_ABI const ArchInfo * parseArch(StringRef Arch)
LLVM_ABI const ArchInfo * getArchForCpu(StringRef CPU)
@ DestructiveInstTypeMask
LLVM_ABI bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
NodeAddr< CodeNode * > Code
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
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)
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)
FunctionAddr VTableAddr Count
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.
FunctionAddr VTableAddr Next
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.
const FeatureBitset Features
AArch64::ExtensionBitset DefaultExts
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
FeatureBitset FeaturesRequired