71#define DEBUG_TYPE "asm-parser"
78enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
81 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
82 cl::desc(
"Allow conditional instructions outside of an IT block"),
84 "Accept in both ISAs, emit implicit ITs in Thumb"),
86 "Warn in ARM, reject in Thumb"),
88 "Accept in ARM, reject in Thumb"),
89 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
90 "Warn in ARM, emit implicit ITs in Thumb")));
95enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
97static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
104 return (Mask >> (5 - Position) & 1);
113 Locs PersonalityLocs;
114 Locs PersonalityIndexLocs;
115 Locs HandlerDataLocs;
121 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
122 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
123 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
125 bool hasPersonality()
const {
126 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
129 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
130 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
131 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
132 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
133 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
135 void saveFPReg(
MCRegister Reg) { FPReg = Reg; }
138 void emitFnStartLocNotes()
const {
139 for (
const SMLoc &Loc : FnStartLocs)
140 Parser.
Note(Loc,
".fnstart was specified here");
143 void emitCantUnwindLocNotes()
const {
144 for (
const SMLoc &Loc : CantUnwindLocs)
145 Parser.
Note(Loc,
".cantunwind was specified here");
148 void emitHandlerDataLocNotes()
const {
149 for (
const SMLoc &Loc : HandlerDataLocs)
150 Parser.
Note(Loc,
".handlerdata was specified here");
153 void emitPersonalityLocNotes()
const {
155 PE = PersonalityLocs.end(),
156 PII = PersonalityIndexLocs.begin(),
157 PIE = PersonalityIndexLocs.end();
158 PI != PE || PII != PIE;) {
159 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
160 Parser.
Note(*PI++,
".personality was specified here");
161 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
162 Parser.
Note(*PII++,
".personalityindex was specified here");
165 "at the same location");
170 FnStartLocs = Locs();
171 CantUnwindLocs = Locs();
172 PersonalityLocs = Locs();
173 HandlerDataLocs = Locs();
174 PersonalityIndexLocs = Locs();
180class ARMMnemonicSets {
191 return CDE.
count(Mnemonic);
196 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
199 return CDEWithVPTSuffix.
count(Mnemonic);
204 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
214 bool isCDEDualRegInstr(
StringRef Mnemonic) {
217 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
218 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
219 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
224 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
225 "cx2",
"cx2a",
"cx2d",
"cx2da",
226 "cx3",
"cx3a",
"cx3d",
"cx3da", })
227 CDE.insert(Mnemonic);
229 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
230 CDE.insert(Mnemonic);
231 CDEWithVPTSuffix.insert(Mnemonic);
232 CDEWithVPTSuffix.insert(std::string(Mnemonic) +
"t");
233 CDEWithVPTSuffix.insert(std::string(Mnemonic) +
"e");
244 "do not have a target streamer");
252 bool NextSymbolIsThumb;
254 bool useImplicitITThumb()
const {
255 return ImplicitItMode == ImplicitItModeTy::Always ||
256 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
259 bool useImplicitITARM()
const {
260 return ImplicitItMode == ImplicitItModeTy::Always ||
261 ImplicitItMode == ImplicitItModeTy::ARMOnly;
276 unsigned CurPosition;
292 if (!inImplicitITBlock()) {
306 for (
const MCInst &Inst : PendingConditionalInsts) {
309 PendingConditionalInsts.clear();
313 ITState.CurPosition = ~0U;
316 bool inITBlock() {
return ITState.CurPosition != ~0U; }
317 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
318 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
320 bool lastInITBlock() {
324 void forwardITPosition() {
325 if (!inITBlock())
return;
330 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
331 ITState.CurPosition = ~0U;
335 void rewindImplicitITPosition() {
336 assert(inImplicitITBlock());
337 assert(ITState.CurPosition > 1);
338 ITState.CurPosition--;
340 unsigned NewMask = 0;
341 NewMask |= ITState.Mask & (0xC << TZ);
342 NewMask |= 0x2 << TZ;
343 ITState.Mask = NewMask;
348 void discardImplicitITBlock() {
349 assert(inImplicitITBlock());
350 assert(ITState.CurPosition == 1);
351 ITState.CurPosition = ~0U;
356 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
362 void invertCurrentITCondition() {
363 if (ITState.CurPosition == 1) {
366 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
371 bool isITBlockFull() {
372 return inITBlock() && (ITState.Mask & 1);
378 assert(inImplicitITBlock());
383 unsigned NewMask = 0;
385 NewMask |= ITState.Mask & (0xE << TZ);
387 NewMask |= (
Cond != ITState.Cond) << TZ;
389 NewMask |= 1 << (TZ - 1);
390 ITState.Mask = NewMask;
394 void startImplicitITBlock() {
398 ITState.CurPosition = 1;
399 ITState.IsExplicit =
false;
410 ITState.CurPosition = 0;
411 ITState.IsExplicit =
true;
416 unsigned CurPosition;
418 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
419 void forwardVPTPosition() {
420 if (!inVPTBlock())
return;
422 if (++VPTState.CurPosition == 5 - TZ)
423 VPTState.CurPosition = ~0U;
439 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
440 bool IsARPop =
false);
442 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
447 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
448 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
449 bool AllowRAAC =
false,
bool IsLazyLoadStore =
false,
450 bool IsVSCCLRM =
false);
453 bool parseImmExpr(int64_t &Out);
456 unsigned &ShiftAmount);
457 bool parseLiteralValues(
unsigned Size,
SMLoc L);
458 bool parseDirectiveThumb(
SMLoc L);
459 bool parseDirectiveARM(
SMLoc L);
460 bool parseDirectiveThumbFunc(
SMLoc L);
461 bool parseDirectiveCode(
SMLoc L);
462 bool parseDirectiveSyntax(
SMLoc L);
464 bool parseDirectiveUnreq(
SMLoc L);
465 bool parseDirectiveArch(
SMLoc L);
466 bool parseDirectiveEabiAttr(
SMLoc L);
467 bool parseDirectiveCPU(
SMLoc L);
468 bool parseDirectiveFPU(
SMLoc L);
469 bool parseDirectiveFnStart(
SMLoc L);
470 bool parseDirectiveFnEnd(
SMLoc L);
471 bool parseDirectiveCantUnwind(
SMLoc L);
472 bool parseDirectivePersonality(
SMLoc L);
473 bool parseDirectiveHandlerData(
SMLoc L);
474 bool parseDirectiveSetFP(
SMLoc L);
475 bool parseDirectivePad(
SMLoc L);
476 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
477 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
478 bool parseDirectiveLtorg(
SMLoc L);
479 bool parseDirectiveEven(
SMLoc L);
480 bool parseDirectivePersonalityIndex(
SMLoc L);
481 bool parseDirectiveUnwindRaw(
SMLoc L);
482 bool parseDirectiveTLSDescSeq(
SMLoc L);
483 bool parseDirectiveMovSP(
SMLoc L);
484 bool parseDirectiveObjectArch(
SMLoc L);
485 bool parseDirectiveArchExtension(
SMLoc L);
486 bool parseDirectiveAlign(
SMLoc L);
487 bool parseDirectiveThumbSet(
SMLoc L);
489 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
490 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
491 bool parseDirectiveSEHSaveSP(
SMLoc L);
492 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
493 bool parseDirectiveSEHSaveLR(
SMLoc L);
494 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
495 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
496 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
497 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
498 bool parseDirectiveSEHCustom(
SMLoc L);
500 std::unique_ptr<ARMOperand> defaultCondCodeOp();
501 std::unique_ptr<ARMOperand> defaultCCOutOp();
502 std::unique_ptr<ARMOperand> defaultVPTPredOp();
508 bool &CarrySetting,
unsigned &ProcessorIMod,
511 StringRef FullInst,
bool &CanAcceptCarrySet,
512 bool &CanAcceptPredicationCode,
513 bool &CanAcceptVPTPredicationCode);
516 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
519 unsigned MnemonicOpsEndInd);
522 unsigned MnemonicOpsEndInd);
529 bool isThumbOne()
const {
533 bool isThumbTwo()
const {
537 bool hasThumb()
const {
541 bool hasThumb2()
const {
545 bool hasV6Ops()
const {
549 bool hasV6T2Ops()
const {
553 bool hasV6MOps()
const {
557 bool hasV7Ops()
const {
561 bool hasV8Ops()
const {
565 bool hasV8MBaseline()
const {
569 bool hasV8MMainline()
const {
572 bool hasV8_1MMainline()
const {
575 bool hasMVEFloat()
const {
578 bool hasCDE()
const {
581 bool has8MSecExt()
const {
585 bool hasARM()
const {
589 bool hasDSP()
const {
593 bool hasD32()
const {
597 bool hasV8_1aOps()
const {
601 bool hasRAS()
const {
607 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
611 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
613 bool isMClass()
const {
620#define GET_ASSEMBLER_HEADER
621#include "ARMGenAsmMatcher.inc"
652 ParseStatus parseVectorLane(VectorLaneTy &LaneKind,
unsigned &Index,
661 unsigned MnemonicOpsEndInd);
664 bool shouldOmitVectorPredicateOperand(
StringRef Mnemonic,
666 unsigned MnemonicOpsEndInd);
667 bool isITBlockTerminator(
MCInst &Inst)
const;
670 unsigned MnemonicOpsEndInd);
672 bool ARMMode,
bool Writeback,
673 unsigned MnemonicOpsEndInd);
676 enum ARMMatchResultTy {
678 Match_RequiresNotITBlock,
680 Match_RequiresThumb2,
682 Match_RequiresFlagSetting,
683#define GET_OPERAND_DIAGNOSTIC_TYPES
684#include "ARMGenAsmMatcher.inc"
701 getTargetStreamer().emitTargetAttributes(STI);
704 ITState.CurPosition = ~0
U;
706 VPTState.CurPosition = ~0
U;
708 NextSymbolIsThumb =
false;
714 SMLoc &EndLoc)
override;
720 unsigned Kind)
override;
729 bool MatchingInlineAsm)
override;
732 bool MatchingInlineAsm,
bool &EmitInITBlock,
735 struct NearMissMessage {
740 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
755 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
756 return MII.get(Opcode);
763 return MRI->getSubReg(QReg, ARM::dsub_0);
782 k_InstSyncBarrierOpt,
783 k_TraceSyncBarrierOpt,
792 k_RegisterListWithAPSR,
795 k_FPSRegisterListWithVPR,
796 k_FPDRegisterListWithVPR,
798 k_VectorListAllLanes,
805 k_ConstantPoolImmediate,
806 k_BitfieldDescriptor,
810 SMLoc StartLoc, EndLoc, AlignmentLoc;
813 ARMAsmParser *Parser;
827 struct CoprocOptionOp {
869 struct VectorListOp {
876 struct VectorIndexOp {
895 unsigned isNegative : 1;
898 struct PostIdxRegOp {
905 struct ShifterImmOp {
910 struct RegShiftedRegOp {
917 struct RegShiftedImmOp {
941 struct CoprocOptionOp CoprocOption;
942 struct MBOptOp MBOpt;
943 struct ISBOptOp ISBOpt;
944 struct TSBOptOp TSBOpt;
945 struct ITMaskOp ITMask;
947 struct MMaskOp MMask;
948 struct BankedRegOp BankedReg;
951 struct VectorListOp VectorList;
952 struct VectorIndexOp VectorIndex;
955 struct PostIdxRegOp PostIdxReg;
956 struct ShifterImmOp ShifterImm;
957 struct RegShiftedRegOp RegShiftedReg;
958 struct RegShiftedImmOp RegShiftedImm;
959 struct RotImmOp RotImm;
960 struct ModImmOp ModImm;
965 ARMOperand(KindTy K, ARMAsmParser &Parser) :
Kind(
K), Parser(&Parser) {}
978 SMLoc getAlignmentLoc()
const {
979 assert(Kind == k_Memory &&
"Invalid access!");
984 assert(Kind == k_CondCode &&
"Invalid access!");
989 assert(isVPTPred() &&
"Invalid access!");
993 unsigned getCoproc()
const {
994 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
999 assert(Kind == k_Token &&
"Invalid access!");
1004 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1009 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1010 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1011 Kind == k_FPSRegisterListWithVPR ||
1012 Kind == k_FPDRegisterListWithVPR) &&
1017 const MCExpr *getImm()
const {
1022 const MCExpr *getConstantPoolImm()
const {
1023 assert(isConstantPoolImm() &&
"Invalid access!");
1027 unsigned getVectorIndex()
const {
1028 assert(Kind == k_VectorIndex &&
"Invalid access!");
1029 return VectorIndex.Val;
1033 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1038 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1043 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1048 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1052 unsigned getMSRMask()
const {
1053 assert(Kind == k_MSRMask &&
"Invalid access!");
1057 unsigned getBankedReg()
const {
1058 assert(Kind == k_BankedReg &&
"Invalid access!");
1059 return BankedReg.Val;
1062 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1063 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1064 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1066 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1067 bool isCCOut()
const {
return Kind == k_CCOut; }
1068 bool isITMask()
const {
return Kind == k_ITCondMask; }
1069 bool isITCondCode()
const {
return Kind == k_CondCode; }
1070 bool isImm()
const override {
1071 return Kind == k_Immediate;
1074 bool isARMBranchTarget()
const {
1075 if (!
isImm())
return false;
1077 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1078 return CE->getValue() % 4 == 0;
1083 bool isThumbBranchTarget()
const {
1084 if (!
isImm())
return false;
1086 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1087 return CE->getValue() % 2 == 0;
1093 template<
unsigned w
idth,
unsigned scale>
1094 bool isUnsignedOffset()
const {
1095 if (!
isImm())
return false;
1096 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1098 int64_t Val =
CE->getValue();
1100 int64_t
Max =
Align * ((1LL << width) - 1);
1101 return ((Val %
Align) == 0) && (Val >= 0) && (Val <= Max);
1108 template<
unsigned w
idth,
unsigned scale>
1109 bool isSignedOffset()
const {
1110 if (!
isImm())
return false;
1111 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1113 int64_t Val =
CE->getValue();
1115 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1116 int64_t Min = -
Align * (1LL << (width-1));
1117 return ((Val %
Align) == 0) && (Val >= Min) && (Val <= Max);
1124 bool isLEOffset()
const {
1125 if (!
isImm())
return false;
1126 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1128 int64_t Val =
CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1138 bool isThumbMemPC()
const {
1141 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1143 if (!CE)
return false;
1144 Val =
CE->getValue();
1146 else if (isGPRMem()) {
1147 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
1148 if(
Memory.BaseRegNum != ARM::PC)
return false;
1149 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
1150 Val =
CE->getValue();
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1158 bool isFPImm()
const {
1159 if (!
isImm())
return false;
1161 if (!CE || !isUInt<32>(
CE->getValue()))
1167 template<
int64_t N,
int64_t M>
1168 bool isImmediate()
const {
1169 if (!
isImm())
return false;
1171 if (!CE)
return false;
1172 int64_t
Value =
CE->getValue();
1176 template<
int64_t N,
int64_t M>
1177 bool isImmediateS4()
const {
1178 if (!
isImm())
return false;
1180 if (!CE)
return false;
1181 int64_t
Value =
CE->getValue();
1184 template<
int64_t N,
int64_t M>
1185 bool isImmediateS2()
const {
1186 if (!
isImm())
return false;
1188 if (!CE)
return false;
1189 int64_t
Value =
CE->getValue();
1192 bool isFBits16()
const {
1193 return isImmediate<0, 17>();
1195 bool isFBits32()
const {
1196 return isImmediate<1, 33>();
1198 bool isImm8s4()
const {
1199 return isImmediateS4<-1020, 1020>();
1201 bool isImm7s4()
const {
1202 return isImmediateS4<-508, 508>();
1204 bool isImm7Shift0()
const {
1205 return isImmediate<-127, 127>();
1207 bool isImm7Shift1()
const {
1208 return isImmediateS2<-255, 255>();
1210 bool isImm7Shift2()
const {
1211 return isImmediateS4<-511, 511>();
1213 bool isImm7()
const {
1214 return isImmediate<-127, 127>();
1216 bool isImm0_1020s4()
const {
1217 return isImmediateS4<0, 1020>();
1219 bool isImm0_508s4()
const {
1220 return isImmediateS4<0, 508>();
1222 bool isImm0_508s4Neg()
const {
1223 if (!
isImm())
return false;
1225 if (!CE)
return false;
1226 int64_t
Value = -
CE->getValue();
1231 bool isImm0_4095Neg()
const {
1232 if (!
isImm())
return false;
1234 if (!CE)
return false;
1239 if ((
CE->getValue() >> 32) > 0)
return false;
1244 bool isImm0_7()
const {
1245 return isImmediate<0, 7>();
1248 bool isImm1_16()
const {
1249 return isImmediate<1, 16>();
1252 bool isImm1_32()
const {
1253 return isImmediate<1, 32>();
1256 bool isImm8_255()
const {
1257 return isImmediate<8, 255>();
1260 bool isImm0_255Expr()
const {
1268 int64_t
Value =
CE->getValue();
1269 return isUInt<8>(
Value);
1272 bool isImm256_65535Expr()
const {
1273 if (!
isImm())
return false;
1277 if (!CE)
return true;
1278 int64_t
Value =
CE->getValue();
1282 bool isImm0_65535Expr()
const {
1283 if (!
isImm())
return false;
1287 if (!CE)
return true;
1288 int64_t
Value =
CE->getValue();
1292 bool isImm24bit()
const {
1293 return isImmediate<0, 0xffffff + 1>();
1296 bool isImmThumbSR()
const {
1297 return isImmediate<1, 33>();
1300 bool isPKHLSLImm()
const {
1301 return isImmediate<0, 32>();
1304 bool isPKHASRImm()
const {
1305 return isImmediate<0, 33>();
1308 bool isAdrLabel()
const {
1311 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1315 if (!
isImm())
return false;
1317 if (!CE)
return false;
1318 int64_t
Value =
CE->getValue();
1323 bool isT2SOImm()
const {
1326 if (
isImm() && !isa<MCConstantExpr>(getImm())) {
1329 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1333 if (!
isImm())
return false;
1335 if (!CE)
return false;
1336 int64_t
Value =
CE->getValue();
1340 bool isT2SOImmNot()
const {
1341 if (!
isImm())
return false;
1343 if (!CE)
return false;
1344 int64_t
Value =
CE->getValue();
1349 bool isT2SOImmNeg()
const {
1350 if (!
isImm())
return false;
1352 if (!CE)
return false;
1353 int64_t
Value =
CE->getValue();
1359 bool isSetEndImm()
const {
1360 if (!
isImm())
return false;
1362 if (!CE)
return false;
1363 int64_t
Value =
CE->getValue();
1367 bool isReg()
const override {
return Kind == k_Register; }
1368 bool isRegList()
const {
return Kind == k_RegisterList; }
1369 bool isRegListWithAPSR()
const {
1370 return Kind == k_RegisterListWithAPSR ||
Kind == k_RegisterList;
1372 bool isDReg()
const {
1374 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
Reg.RegNum);
1376 bool isQReg()
const {
1378 ARMMCRegisterClasses[ARM::QPRRegClassID].contains(
Reg.RegNum);
1380 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1381 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1382 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1383 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1384 bool isToken()
const override {
return Kind == k_Token; }
1385 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1386 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1387 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1388 bool isMem()
const override {
1389 return isGPRMem() || isMVEMem();
1391 bool isMVEMem()
const {
1392 if (Kind != k_Memory)
1395 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum) &&
1396 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
Memory.BaseRegNum))
1398 if (
Memory.OffsetRegNum &&
1399 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1404 bool isGPRMem()
const {
1405 if (Kind != k_Memory)
1408 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum))
1410 if (
Memory.OffsetRegNum &&
1411 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.OffsetRegNum))
1415 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1416 bool isRegShiftedReg()
const {
1417 return Kind == k_ShiftedRegister &&
1418 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1419 RegShiftedReg.SrcReg) &&
1420 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1421 RegShiftedReg.ShiftReg);
1423 bool isRegShiftedImm()
const {
1424 return Kind == k_ShiftedImmediate &&
1425 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1426 RegShiftedImm.SrcReg);
1428 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1430 template<
unsigned Min,
unsigned Max>
1431 bool isPowerTwoInRange()
const {
1432 if (!
isImm())
return false;
1434 if (!CE)
return false;
1435 int64_t
Value =
CE->getValue();
1439 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1441 bool isModImmNot()
const {
1442 if (!
isImm())
return false;
1444 if (!CE)
return false;
1445 int64_t
Value =
CE->getValue();
1449 bool isModImmNeg()
const {
1450 if (!
isImm())
return false;
1452 if (!CE)
return false;
1453 int64_t
Value =
CE->getValue();
1458 bool isThumbModImmNeg1_7()
const {
1459 if (!
isImm())
return false;
1461 if (!CE)
return false;
1462 int32_t
Value = -(int32_t)
CE->getValue();
1466 bool isThumbModImmNeg8_255()
const {
1467 if (!
isImm())
return false;
1469 if (!CE)
return false;
1470 int32_t
Value = -(int32_t)
CE->getValue();
1474 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1475 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1476 bool isPostIdxRegShifted()
const {
1477 return Kind == k_PostIndexRegister &&
1478 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1480 bool isPostIdxReg()
const {
1483 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1487 return !
Memory.OffsetRegNum &&
Memory.OffsetImm ==
nullptr &&
1488 (alignOK ||
Memory.Alignment == Alignment);
1490 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1494 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1499 return !
Memory.OffsetRegNum &&
Memory.OffsetImm ==
nullptr &&
1500 (alignOK ||
Memory.Alignment == Alignment);
1502 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1506 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].
contains(
1511 return !
Memory.OffsetRegNum &&
Memory.OffsetImm ==
nullptr &&
1512 (alignOK ||
Memory.Alignment == Alignment);
1514 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1518 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].
contains(
1523 return !
Memory.OffsetRegNum &&
Memory.OffsetImm ==
nullptr &&
1524 (alignOK ||
Memory.Alignment == Alignment);
1526 bool isMemPCRelImm12()
const {
1527 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1530 if (
Memory.BaseRegNum != ARM::PC)
1533 if (!
Memory.OffsetImm)
return true;
1534 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1535 int64_t Val =
CE->getValue();
1536 return (Val > -4096 && Val < 4096) ||
1537 (Val == std::numeric_limits<int32_t>::min());
1542 bool isAlignedMemory()
const {
1543 return isMemNoOffset(
true);
1546 bool isAlignedMemoryNone()
const {
1547 return isMemNoOffset(
false, 0);
1550 bool isDupAlignedMemoryNone()
const {
1551 return isMemNoOffset(
false, 0);
1554 bool isAlignedMemory16()
const {
1555 if (isMemNoOffset(
false, 2))
1557 return isMemNoOffset(
false, 0);
1560 bool isDupAlignedMemory16()
const {
1561 if (isMemNoOffset(
false, 2))
1563 return isMemNoOffset(
false, 0);
1566 bool isAlignedMemory32()
const {
1567 if (isMemNoOffset(
false, 4))
1569 return isMemNoOffset(
false, 0);
1572 bool isDupAlignedMemory32()
const {
1573 if (isMemNoOffset(
false, 4))
1575 return isMemNoOffset(
false, 0);
1578 bool isAlignedMemory64()
const {
1579 if (isMemNoOffset(
false, 8))
1581 return isMemNoOffset(
false, 0);
1584 bool isDupAlignedMemory64()
const {
1585 if (isMemNoOffset(
false, 8))
1587 return isMemNoOffset(
false, 0);
1590 bool isAlignedMemory64or128()
const {
1591 if (isMemNoOffset(
false, 8))
1593 if (isMemNoOffset(
false, 16))
1595 return isMemNoOffset(
false, 0);
1598 bool isDupAlignedMemory64or128()
const {
1599 if (isMemNoOffset(
false, 8))
1601 if (isMemNoOffset(
false, 16))
1603 return isMemNoOffset(
false, 0);
1606 bool isAlignedMemory64or128or256()
const {
1607 if (isMemNoOffset(
false, 8))
1609 if (isMemNoOffset(
false, 16))
1611 if (isMemNoOffset(
false, 32))
1613 return isMemNoOffset(
false, 0);
1616 bool isAddrMode2()
const {
1617 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1619 if (
Memory.OffsetRegNum)
return true;
1621 if (!
Memory.OffsetImm)
return true;
1622 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1623 int64_t Val =
CE->getValue();
1624 return Val > -4096 && Val < 4096;
1629 bool isAM2OffsetImm()
const {
1630 if (!
isImm())
return false;
1633 if (!CE)
return false;
1634 int64_t Val =
CE->getValue();
1635 return (Val == std::numeric_limits<int32_t>::min()) ||
1636 (Val > -4096 && Val < 4096);
1639 bool isAddrMode3()
const {
1643 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1645 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1649 if (
Memory.OffsetRegNum)
return true;
1651 if (!
Memory.OffsetImm)
return true;
1652 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1653 int64_t Val =
CE->getValue();
1656 return (Val > -256 && Val < 256) ||
1657 Val == std::numeric_limits<int32_t>::min();
1662 bool isAM3Offset()
const {
1669 if (!CE)
return false;
1670 int64_t Val =
CE->getValue();
1672 return (Val > -256 && Val < 256) ||
1673 Val == std::numeric_limits<int32_t>::min();
1676 bool isAddrMode5()
const {
1680 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1682 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1684 if (
Memory.OffsetRegNum)
return false;
1686 if (!
Memory.OffsetImm)
return true;
1687 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1688 int64_t Val =
CE->getValue();
1689 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1690 Val == std::numeric_limits<int32_t>::min();
1695 bool isAddrMode5FP16()
const {
1699 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1701 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1703 if (
Memory.OffsetRegNum)
return false;
1705 if (!
Memory.OffsetImm)
return true;
1706 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1707 int64_t Val =
CE->getValue();
1708 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1709 Val == std::numeric_limits<int32_t>::min();
1714 bool isMemTBB()
const {
1715 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1721 bool isMemTBH()
const {
1722 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1729 bool isMemRegOffset()
const {
1730 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1735 bool isT2MemRegOffset()
const {
1736 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1747 bool isMemThumbRR()
const {
1750 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1757 bool isMemThumbRIs4()
const {
1758 if (!isGPRMem() ||
Memory.OffsetRegNum ||
1762 if (!
Memory.OffsetImm)
return true;
1763 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1764 int64_t Val =
CE->getValue();
1765 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1770 bool isMemThumbRIs2()
const {
1771 if (!isGPRMem() ||
Memory.OffsetRegNum ||
1775 if (!
Memory.OffsetImm)
return true;
1776 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1777 int64_t Val =
CE->getValue();
1778 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1783 bool isMemThumbRIs1()
const {
1784 if (!isGPRMem() ||
Memory.OffsetRegNum ||
1788 if (!
Memory.OffsetImm)
return true;
1789 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1790 int64_t Val =
CE->getValue();
1791 return Val >= 0 && Val <= 31;
1796 bool isMemThumbSPI()
const {
1797 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.BaseRegNum != ARM::SP ||
1801 if (!
Memory.OffsetImm)
return true;
1802 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1803 int64_t Val =
CE->getValue();
1804 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1809 bool isMemImm8s4Offset()
const {
1813 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1815 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1818 if (!
Memory.OffsetImm)
return true;
1819 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1820 int64_t Val =
CE->getValue();
1822 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1823 Val == std::numeric_limits<int32_t>::min();
1828 bool isMemImm7s4Offset()
const {
1832 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1834 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0 ||
1835 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1839 if (!
Memory.OffsetImm)
return true;
1840 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1841 int64_t Val =
CE->getValue();
1843 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1848 bool isMemImm0_1020s4Offset()
const {
1849 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1852 if (!
Memory.OffsetImm)
return true;
1853 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1854 int64_t Val =
CE->getValue();
1855 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1860 bool isMemImm8Offset()
const {
1861 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1864 if (
Memory.BaseRegNum == ARM::PC)
return false;
1866 if (!
Memory.OffsetImm)
return true;
1867 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1868 int64_t Val =
CE->getValue();
1869 return (Val == std::numeric_limits<int32_t>::min()) ||
1870 (Val > -256 && Val < 256);
1875 template<
unsigned Bits,
unsigned RegClassID>
1876 bool isMemImm7ShiftedOffset()
const {
1877 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0 ||
1878 !ARMMCRegisterClasses[RegClassID].contains(
Memory.BaseRegNum))
1884 if (!
Memory.OffsetImm)
return true;
1885 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1886 int64_t Val =
CE->getValue();
1890 if (Val == INT32_MIN)
1893 unsigned Divisor = 1U <<
Bits;
1896 if (Val % Divisor != 0)
1901 return (Val >= -127 && Val <= 127);
1906 template <
int shift>
bool isMemRegRQOffset()
const {
1907 if (!isMVEMem() ||
Memory.OffsetImm !=
nullptr ||
Memory.Alignment != 0)
1910 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1913 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1927 template <
int shift>
bool isMemRegQOffset()
const {
1928 if (!isMVEMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1931 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1937 static_assert(shift < 56,
1938 "Such that we dont shift by a value higher than 62");
1939 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1940 int64_t Val =
CE->getValue();
1943 if ((Val & ((1U << shift) - 1)) != 0)
1949 int64_t
Range = (1U << (7 + shift)) - 1;
1950 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1955 bool isMemPosImm8Offset()
const {
1956 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1959 if (!
Memory.OffsetImm)
return true;
1960 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1961 int64_t Val =
CE->getValue();
1962 return Val >= 0 && Val < 256;
1967 bool isMemNegImm8Offset()
const {
1968 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1971 if (
Memory.BaseRegNum == ARM::PC)
return false;
1973 if (!
Memory.OffsetImm)
return false;
1974 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1975 int64_t Val =
CE->getValue();
1976 return (Val == std::numeric_limits<int32_t>::min()) ||
1977 (Val > -256 && Val < 0);
1982 bool isMemUImm12Offset()
const {
1983 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1986 if (!
Memory.OffsetImm)
return true;
1987 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1988 int64_t Val =
CE->getValue();
1989 return (Val >= 0 && Val < 4096);
1994 bool isMemImm12Offset()
const {
1999 if (
isImm() && !isa<MCConstantExpr>(getImm()))
2002 if (!isGPRMem() ||
Memory.OffsetRegNum ||
Memory.Alignment != 0)
2005 if (!
Memory.OffsetImm)
return true;
2006 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
2007 int64_t Val =
CE->getValue();
2008 return (Val > -4096 && Val < 4096) ||
2009 (Val == std::numeric_limits<int32_t>::min());
2016 bool isConstPoolAsmImm()
const {
2019 return (isConstantPoolImm());
2022 bool isPostIdxImm8()
const {
2023 if (!
isImm())
return false;
2025 if (!CE)
return false;
2026 int64_t Val =
CE->getValue();
2027 return (Val > -256 && Val < 256) ||
2028 (Val == std::numeric_limits<int32_t>::min());
2031 bool isPostIdxImm8s4()
const {
2032 if (!
isImm())
return false;
2034 if (!CE)
return false;
2035 int64_t Val =
CE->getValue();
2036 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2037 (Val == std::numeric_limits<int32_t>::min());
2040 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2041 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2042 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2045 bool isAnyVectorList()
const {
2046 return Kind == k_VectorList ||
Kind == k_VectorListAllLanes ||
2047 Kind == k_VectorListIndexed;
2050 bool isVectorList()
const {
return Kind == k_VectorList; }
2052 bool isSingleSpacedVectorList()
const {
2053 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2056 bool isDoubleSpacedVectorList()
const {
2057 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2060 bool isVecListOneD()
const {
2062 if (isDReg() && !Parser->hasMVE())
2064 if (!isSingleSpacedVectorList())
return false;
2065 return VectorList.Count == 1;
2068 bool isVecListTwoMQ()
const {
2069 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2070 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2074 bool isVecListDPair()
const {
2077 if (isQReg() && !Parser->hasMVE())
2079 if (!isSingleSpacedVectorList())
return false;
2080 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2084 bool isVecListThreeD()
const {
2085 if (!isSingleSpacedVectorList())
return false;
2086 return VectorList.Count == 3;
2089 bool isVecListFourD()
const {
2090 if (!isSingleSpacedVectorList())
return false;
2091 return VectorList.Count == 4;
2094 bool isVecListDPairSpaced()
const {
2095 if (Kind != k_VectorList)
return false;
2096 if (isSingleSpacedVectorList())
return false;
2097 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2101 bool isVecListThreeQ()
const {
2102 if (!isDoubleSpacedVectorList())
return false;
2103 return VectorList.Count == 3;
2106 bool isVecListFourQ()
const {
2107 if (!isDoubleSpacedVectorList())
return false;
2108 return VectorList.Count == 4;
2111 bool isVecListFourMQ()
const {
2112 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2113 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2117 bool isSingleSpacedVectorAllLanes()
const {
2118 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2121 bool isDoubleSpacedVectorAllLanes()
const {
2122 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2125 bool isVecListOneDAllLanes()
const {
2126 if (!isSingleSpacedVectorAllLanes())
return false;
2127 return VectorList.Count == 1;
2130 bool isVecListDPairAllLanes()
const {
2131 if (!isSingleSpacedVectorAllLanes())
return false;
2132 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2136 bool isVecListDPairSpacedAllLanes()
const {
2137 if (!isDoubleSpacedVectorAllLanes())
return false;
2138 return VectorList.Count == 2;
2141 bool isVecListThreeDAllLanes()
const {
2142 if (!isSingleSpacedVectorAllLanes())
return false;
2143 return VectorList.Count == 3;
2146 bool isVecListThreeQAllLanes()
const {
2147 if (!isDoubleSpacedVectorAllLanes())
return false;
2148 return VectorList.Count == 3;
2151 bool isVecListFourDAllLanes()
const {
2152 if (!isSingleSpacedVectorAllLanes())
return false;
2153 return VectorList.Count == 4;
2156 bool isVecListFourQAllLanes()
const {
2157 if (!isDoubleSpacedVectorAllLanes())
return false;
2158 return VectorList.Count == 4;
2161 bool isSingleSpacedVectorIndexed()
const {
2162 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2165 bool isDoubleSpacedVectorIndexed()
const {
2166 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2169 bool isVecListOneDByteIndexed()
const {
2170 if (!isSingleSpacedVectorIndexed())
return false;
2171 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2174 bool isVecListOneDHWordIndexed()
const {
2175 if (!isSingleSpacedVectorIndexed())
return false;
2176 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2179 bool isVecListOneDWordIndexed()
const {
2180 if (!isSingleSpacedVectorIndexed())
return false;
2181 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2184 bool isVecListTwoDByteIndexed()
const {
2185 if (!isSingleSpacedVectorIndexed())
return false;
2186 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2189 bool isVecListTwoDHWordIndexed()
const {
2190 if (!isSingleSpacedVectorIndexed())
return false;
2191 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2194 bool isVecListTwoQWordIndexed()
const {
2195 if (!isDoubleSpacedVectorIndexed())
return false;
2196 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2199 bool isVecListTwoQHWordIndexed()
const {
2200 if (!isDoubleSpacedVectorIndexed())
return false;
2201 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2204 bool isVecListTwoDWordIndexed()
const {
2205 if (!isSingleSpacedVectorIndexed())
return false;
2206 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2209 bool isVecListThreeDByteIndexed()
const {
2210 if (!isSingleSpacedVectorIndexed())
return false;
2211 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2214 bool isVecListThreeDHWordIndexed()
const {
2215 if (!isSingleSpacedVectorIndexed())
return false;
2216 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2219 bool isVecListThreeQWordIndexed()
const {
2220 if (!isDoubleSpacedVectorIndexed())
return false;
2221 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2224 bool isVecListThreeQHWordIndexed()
const {
2225 if (!isDoubleSpacedVectorIndexed())
return false;
2226 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2229 bool isVecListThreeDWordIndexed()
const {
2230 if (!isSingleSpacedVectorIndexed())
return false;
2231 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2234 bool isVecListFourDByteIndexed()
const {
2235 if (!isSingleSpacedVectorIndexed())
return false;
2236 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2239 bool isVecListFourDHWordIndexed()
const {
2240 if (!isSingleSpacedVectorIndexed())
return false;
2241 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2244 bool isVecListFourQWordIndexed()
const {
2245 if (!isDoubleSpacedVectorIndexed())
return false;
2246 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2249 bool isVecListFourQHWordIndexed()
const {
2250 if (!isDoubleSpacedVectorIndexed())
return false;
2251 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2254 bool isVecListFourDWordIndexed()
const {
2255 if (!isSingleSpacedVectorIndexed())
return false;
2256 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2259 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2261 template <
unsigned NumLanes>
2262 bool isVectorIndexInRange()
const {
2263 if (Kind != k_VectorIndex)
return false;
2264 return VectorIndex.Val < NumLanes;
2267 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2268 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2269 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2270 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2272 template<
int PermittedValue,
int OtherPermittedValue>
2273 bool isMVEPairVectorIndex()
const {
2274 if (Kind != k_VectorIndex)
return false;
2275 return VectorIndex.Val == PermittedValue ||
2276 VectorIndex.Val == OtherPermittedValue;
2279 bool isNEONi8splat()
const {
2280 if (!
isImm())
return false;
2283 if (!CE)
return false;
2284 int64_t
Value =
CE->getValue();
2291 if (isNEONByteReplicate(2))
2297 if (!CE)
return false;
2298 unsigned Value =
CE->getValue();
2302 bool isNEONi16splatNot()
const {
2307 if (!CE)
return false;
2308 unsigned Value =
CE->getValue();
2313 if (isNEONByteReplicate(4))
2319 if (!CE)
return false;
2320 unsigned Value =
CE->getValue();
2324 bool isNEONi32splatNot()
const {
2329 if (!CE)
return false;
2330 unsigned Value =
CE->getValue();
2334 static bool isValidNEONi32vmovImm(int64_t
Value) {
2337 return ((
Value & 0xffffffffffffff00) == 0) ||
2338 ((
Value & 0xffffffffffff00ff) == 0) ||
2339 ((
Value & 0xffffffffff00ffff) == 0) ||
2340 ((
Value & 0xffffffff00ffffff) == 0) ||
2341 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2342 ((
Value & 0xffffffffff00ffff) == 0xffff);
2345 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2346 assert((Width == 8 || Width == 16 || Width == 32) &&
2347 "Invalid element width");
2348 assert(NumElems * Width <= 64 &&
"Invalid result width");
2356 int64_t
Value =
CE->getValue();
2364 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2366 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2369 for (
unsigned i = 1; i < NumElems; ++i) {
2371 if ((
Value & Mask) != Elem)
2377 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2378 return isNEONReplicate(8, NumBytes,
false);
2381 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2382 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2383 "Invalid source width");
2384 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2385 "Invalid destination width");
2386 assert(FromW < ToW &&
"ToW is not less than FromW");
2389 template<
unsigned FromW,
unsigned ToW>
2390 bool isNEONmovReplicate()
const {
2391 checkNeonReplicateArgs(FromW, ToW);
2392 if (ToW == 64 && isNEONi64splat())
2394 return isNEONReplicate(FromW, ToW / FromW,
false);
2397 template<
unsigned FromW,
unsigned ToW>
2398 bool isNEONinvReplicate()
const {
2399 checkNeonReplicateArgs(FromW, ToW);
2400 return isNEONReplicate(FromW, ToW / FromW,
true);
2403 bool isNEONi32vmov()
const {
2404 if (isNEONByteReplicate(4))
2412 return isValidNEONi32vmovImm(
CE->getValue());
2415 bool isNEONi32vmovNeg()
const {
2416 if (!
isImm())
return false;
2419 if (!CE)
return false;
2420 return isValidNEONi32vmovImm(~
CE->getValue());
2423 bool isNEONi64splat()
const {
2424 if (!
isImm())
return false;
2427 if (!CE)
return false;
2430 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2431 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2435 template<
int64_t Angle,
int64_t Remainder>
2436 bool isComplexRotation()
const {
2437 if (!
isImm())
return false;
2440 if (!CE)
return false;
2443 return (
Value % Angle == Remainder &&
Value <= 270);
2446 bool isMVELongShift()
const {
2447 if (!
isImm())
return false;
2450 if (!CE)
return false;
2455 bool isMveSaturateOp()
const {
2456 if (!
isImm())
return false;
2458 if (!CE)
return false;
2463 bool isITCondCodeNoAL()
const {
2464 if (!isITCondCode())
return false;
2469 bool isITCondCodeRestrictedI()
const {
2470 if (!isITCondCode())
2476 bool isITCondCodeRestrictedS()
const {
2477 if (!isITCondCode())
2484 bool isITCondCodeRestrictedU()
const {
2485 if (!isITCondCode())
2491 bool isITCondCodeRestrictedFP()
const {
2492 if (!isITCondCode())
2499 void setVecListDPair(
unsigned int DPair) {
2500 Kind = k_VectorList;
2501 VectorList.RegNum = DPair;
2502 VectorList.Count = 2;
2503 VectorList.isDoubleSpaced =
false;
2506 void setVecListOneD(
unsigned int DReg) {
2507 Kind = k_VectorList;
2508 VectorList.RegNum =
DReg;
2509 VectorList.Count = 1;
2510 VectorList.isDoubleSpaced =
false;
2517 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2523 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2524 assert(
N == 1 &&
"Invalid number of operands!");
2525 addExpr(Inst, getImm());
2528 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2529 assert(
N == 1 &&
"Invalid number of operands!");
2530 addExpr(Inst, getImm());
2533 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2534 assert(
N == 2 &&
"Invalid number of operands!");
2540 void addVPTPredNOperands(
MCInst &Inst,
unsigned N)
const {
2541 assert(
N == 3 &&
"Invalid number of operands!");
2543 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2548 void addVPTPredROperands(
MCInst &Inst,
unsigned N)
const {
2549 assert(
N == 4 &&
"Invalid number of operands!");
2550 addVPTPredNOperands(Inst,
N-1);
2553 RegNum = ARM::NoRegister;
2556 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2557 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2559 "Inactive register in vpred_r is not tied to an output!");
2565 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
2566 assert(
N == 1 &&
"Invalid number of operands!");
2570 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
2571 assert(
N == 1 &&
"Invalid number of operands!");
2575 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
2576 assert(
N == 1 &&
"Invalid number of operands!");
2580 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
2581 assert(
N == 1 &&
"Invalid number of operands!");
2585 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2586 assert(
N == 1 &&
"Invalid number of operands!");
2590 void addITCondCodeInvOperands(
MCInst &Inst,
unsigned N)
const {
2591 assert(
N == 1 &&
"Invalid number of operands!");
2595 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
2596 assert(
N == 1 &&
"Invalid number of operands!");
2600 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
2601 assert(
N == 1 &&
"Invalid number of operands!");
2605 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
2606 assert(
N == 3 &&
"Invalid number of operands!");
2607 assert(isRegShiftedReg() &&
2608 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2615 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
2616 assert(
N == 2 &&
"Invalid number of operands!");
2617 assert(isRegShiftedImm() &&
2618 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2621 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2626 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
2627 assert(
N == 1 &&
"Invalid number of operands!");
2632 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
2633 assert(
N == 1 &&
"Invalid number of operands!");
2639 void addRegListWithAPSROperands(
MCInst &Inst,
unsigned N)
const {
2640 assert(
N == 1 &&
"Invalid number of operands!");
2646 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2647 addRegListOperands(Inst,
N);
2650 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2651 addRegListOperands(Inst,
N);
2654 void addFPSRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2655 addRegListOperands(Inst,
N);
2658 void addFPDRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2659 addRegListOperands(Inst,
N);
2662 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2663 assert(
N == 1 &&
"Invalid number of operands!");
2668 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2669 assert(
N == 1 &&
"Invalid number of operands!");
2673 return addImmOperands(Inst,
N);
2678 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2679 assert(
N == 1 &&
"Invalid number of operands!");
2685 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2686 assert(
N == 1 &&
"Invalid number of operands!");
2692 void addThumbModImmNeg8_255Operands(
MCInst &Inst,
unsigned N)
const {
2693 assert(
N == 1 &&
"Invalid number of operands!");
2699 void addThumbModImmNeg1_7Operands(
MCInst &Inst,
unsigned N)
const {
2700 assert(
N == 1 &&
"Invalid number of operands!");
2706 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2707 assert(
N == 1 &&
"Invalid number of operands!");
2713 (32 - (lsb + width)));
2717 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2718 assert(
N == 1 &&
"Invalid number of operands!");
2719 addExpr(Inst, getImm());
2722 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2723 assert(
N == 1 &&
"Invalid number of operands!");
2728 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2729 assert(
N == 1 &&
"Invalid number of operands!");
2734 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2735 assert(
N == 1 &&
"Invalid number of operands!");
2741 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2742 assert(
N == 1 &&
"Invalid number of operands!");
2749 void addImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
2750 assert(
N == 1 &&
"Invalid number of operands!");
2757 void addImm7Shift0Operands(
MCInst &Inst,
unsigned N)
const {
2758 assert(
N == 1 &&
"Invalid number of operands!");
2763 void addImm7Shift1Operands(
MCInst &Inst,
unsigned N)
const {
2764 assert(
N == 1 &&
"Invalid number of operands!");
2769 void addImm7Shift2Operands(
MCInst &Inst,
unsigned N)
const {
2770 assert(
N == 1 &&
"Invalid number of operands!");
2775 void addImm7Operands(
MCInst &Inst,
unsigned N)
const {
2776 assert(
N == 1 &&
"Invalid number of operands!");
2781 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2782 assert(
N == 1 &&
"Invalid number of operands!");
2789 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2790 assert(
N == 1 &&
"Invalid number of operands!");
2797 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2798 assert(
N == 1 &&
"Invalid number of operands!");
2805 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2806 assert(
N == 1 &&
"Invalid number of operands!");
2813 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2814 assert(
N == 1 &&
"Invalid number of operands!");
2821 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2822 assert(
N == 1 &&
"Invalid number of operands!");
2826 unsigned Imm =
CE->getValue();
2830 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2831 assert(
N == 1 &&
"Invalid number of operands!");
2835 int Val =
CE->getValue();
2839 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2840 assert(
N == 1 &&
"Invalid number of operands!");
2847 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2848 assert(
N == 1 &&
"Invalid number of operands!");
2855 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2856 assert(
N == 1 &&
"Invalid number of operands!");
2863 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2864 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2872 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2873 assert(
N == 1 &&
"Invalid number of operands!");
2885 assert(isGPRMem() &&
"Unknown value type!");
2886 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2887 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2893 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2894 assert(
N == 1 &&
"Invalid number of operands!");
2898 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2899 assert(
N == 1 &&
"Invalid number of operands!");
2903 void addTraceSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2904 assert(
N == 1 &&
"Invalid number of operands!");
2908 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2909 assert(
N == 1 &&
"Invalid number of operands!");
2913 void addMemNoOffsetT2Operands(
MCInst &Inst,
unsigned N)
const {
2914 assert(
N == 1 &&
"Invalid number of operands!");
2918 void addMemNoOffsetT2NoSpOperands(
MCInst &Inst,
unsigned N)
const {
2919 assert(
N == 1 &&
"Invalid number of operands!");
2923 void addMemNoOffsetTOperands(
MCInst &Inst,
unsigned N)
const {
2924 assert(
N == 1 &&
"Invalid number of operands!");
2928 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2929 assert(
N == 1 &&
"Invalid number of operands!");
2930 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2936 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2937 assert(
N == 1 &&
"Invalid number of operands!");
2942 if (!isa<MCConstantExpr>(getImm())) {
2948 int Val =
CE->getValue();
2952 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2953 assert(
N == 2 &&
"Invalid number of operands!");
2958 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2959 addAlignedMemoryOperands(Inst,
N);
2962 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2963 addAlignedMemoryOperands(Inst,
N);
2966 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2967 addAlignedMemoryOperands(Inst,
N);
2970 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2971 addAlignedMemoryOperands(Inst,
N);
2974 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2975 addAlignedMemoryOperands(Inst,
N);
2978 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2979 addAlignedMemoryOperands(Inst,
N);
2982 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2983 addAlignedMemoryOperands(Inst,
N);
2986 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2987 addAlignedMemoryOperands(Inst,
N);
2990 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2991 addAlignedMemoryOperands(Inst,
N);
2994 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2995 addAlignedMemoryOperands(Inst,
N);
2998 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2999 addAlignedMemoryOperands(Inst,
N);
3002 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
3003 assert(
N == 3 &&
"Invalid number of operands!");
3006 if (!
Memory.OffsetRegNum) {
3009 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3010 int32_t Val =
CE->getValue();
3013 if (Val == std::numeric_limits<int32_t>::min())
3031 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
3032 assert(
N == 2 &&
"Invalid number of operands!");
3034 assert(CE &&
"non-constant AM2OffsetImm operand!");
3035 int32_t Val =
CE->getValue();
3038 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3039 if (Val < 0) Val = -Val;
3045 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
3046 assert(
N == 3 &&
"Invalid number of operands!");
3059 if (!
Memory.OffsetRegNum) {
3062 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3063 int32_t Val =
CE->getValue();
3066 if (Val == std::numeric_limits<int32_t>::min())
3083 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3084 assert(
N == 2 &&
"Invalid number of operands!");
3085 if (Kind == k_PostIndexRegister) {
3095 int32_t Val =
CE->getValue();
3098 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3099 if (Val < 0) Val = -Val;
3105 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
3106 assert(
N == 2 &&
"Invalid number of operands!");
3119 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3121 int32_t Val =
CE->getValue() / 4;
3124 if (Val == std::numeric_limits<int32_t>::min())
3134 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
3135 assert(
N == 2 &&
"Invalid number of operands!");
3149 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3150 int32_t Val =
CE->getValue() / 2;
3153 if (Val == std::numeric_limits<int32_t>::min())
3163 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3164 assert(
N == 2 &&
"Invalid number of operands!");
3175 addExpr(Inst,
Memory.OffsetImm);
3178 void addMemImm7s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3179 assert(
N == 2 &&
"Invalid number of operands!");
3190 addExpr(Inst,
Memory.OffsetImm);
3193 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3194 assert(
N == 2 &&
"Invalid number of operands!");
3198 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3205 void addMemImmOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3206 assert(
N == 2 &&
"Invalid number of operands!");
3208 addExpr(Inst,
Memory.OffsetImm);
3211 void addMemRegRQOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3212 assert(
N == 2 &&
"Invalid number of operands!");
3217 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3218 assert(
N == 2 &&
"Invalid number of operands!");
3221 addExpr(Inst, getImm());
3228 addExpr(Inst,
Memory.OffsetImm);
3231 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3232 assert(
N == 2 &&
"Invalid number of operands!");
3235 addExpr(Inst, getImm());
3242 addExpr(Inst,
Memory.OffsetImm);
3245 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
3246 assert(
N == 1 &&
"Invalid number of operands!");
3249 addExpr(Inst, getConstantPoolImm());
3252 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
3253 assert(
N == 2 &&
"Invalid number of operands!");
3258 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
3259 assert(
N == 2 &&
"Invalid number of operands!");
3264 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3265 assert(
N == 3 &&
"Invalid number of operands!");
3274 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3275 assert(
N == 3 &&
"Invalid number of operands!");
3281 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
3282 assert(
N == 2 &&
"Invalid number of operands!");
3287 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
3288 assert(
N == 2 &&
"Invalid number of operands!");
3292 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3299 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
3300 assert(
N == 2 &&
"Invalid number of operands!");
3304 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3310 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
3311 assert(
N == 2 &&
"Invalid number of operands!");
3313 addExpr(Inst,
Memory.OffsetImm);
3316 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
3317 assert(
N == 2 &&
"Invalid number of operands!");
3321 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3328 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
3329 assert(
N == 1 &&
"Invalid number of operands!");
3331 assert(CE &&
"non-constant post-idx-imm8 operand!");
3332 int Imm =
CE->getValue();
3333 bool isAdd =
Imm >= 0;
3334 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3339 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
3340 assert(
N == 1 &&
"Invalid number of operands!");
3342 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3343 int Imm =
CE->getValue();
3344 bool isAdd =
Imm >= 0;
3345 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3351 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
3352 assert(
N == 2 &&
"Invalid number of operands!");
3357 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
3358 assert(
N == 2 &&
"Invalid number of operands!");
3364 PostIdxReg.ShiftTy);
3368 void addPowerTwoOperands(
MCInst &Inst,
unsigned N)
const {
3369 assert(
N == 1 &&
"Invalid number of operands!");
3374 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
3375 assert(
N == 1 &&
"Invalid number of operands!");
3379 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
3380 assert(
N == 1 &&
"Invalid number of operands!");
3384 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
3385 assert(
N == 1 &&
"Invalid number of operands!");
3389 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
3390 assert(
N == 1 &&
"Invalid number of operands!");
3392 if (isAnyVectorList())
3394 else if (isDReg() && !Parser->hasMVE()) {
3396 }
else if (isQReg() && !Parser->hasMVE()) {
3398 DPair = Parser->getMRI()->getMatchingSuperReg(
3399 DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3404 "attempted to add a vector list register with wrong type!");
3408 void addMVEVecListOperands(
MCInst &Inst,
unsigned N)
const {
3409 assert(
N == 1 &&
"Invalid number of operands!");
3425 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3427 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3428 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID];
3431 for (
I = 0;
I <
E;
I++)
3434 assert(
I <
E &&
"Invalid vector list start register!");
3439 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
3440 assert(
N == 2 &&
"Invalid number of operands!");
3445 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
3446 assert(
N == 1 &&
"Invalid number of operands!");
3450 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
3451 assert(
N == 1 &&
"Invalid number of operands!");
3455 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
3456 assert(
N == 1 &&
"Invalid number of operands!");
3460 void addVectorIndex64Operands(
MCInst &Inst,
unsigned N)
const {
3461 assert(
N == 1 &&
"Invalid number of operands!");
3465 void addMVEVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3466 assert(
N == 1 &&
"Invalid number of operands!");
3470 void addMVEPairVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3471 assert(
N == 1 &&
"Invalid number of operands!");
3475 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
3476 assert(
N == 1 &&
"Invalid number of operands!");
3483 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
3484 assert(
N == 1 &&
"Invalid number of operands!");
3487 unsigned Value =
CE->getValue();
3492 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3493 assert(
N == 1 &&
"Invalid number of operands!");
3496 unsigned Value =
CE->getValue();
3501 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
3502 assert(
N == 1 &&
"Invalid number of operands!");
3505 unsigned Value =
CE->getValue();
3510 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3511 assert(
N == 1 &&
"Invalid number of operands!");
3514 unsigned Value =
CE->getValue();
3519 void addNEONi8ReplicateOperands(
MCInst &Inst,
bool Inv)
const {
3524 "All instructions that wants to replicate non-zero byte "
3525 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3526 unsigned Value =
CE->getValue();
3529 unsigned B =
Value & 0xff;
3534 void addNEONinvi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3535 assert(
N == 1 &&
"Invalid number of operands!");
3536 addNEONi8ReplicateOperands(Inst,
true);
3539 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3542 else if (
Value > 0xffff &&
Value <= 0xffffff)
3544 else if (
Value > 0xffffff)
3549 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
3550 assert(
N == 1 &&
"Invalid number of operands!");
3553 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3557 void addNEONvmovi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3558 assert(
N == 1 &&
"Invalid number of operands!");
3559 addNEONi8ReplicateOperands(Inst,
false);
3562 void addNEONvmovi16ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3563 assert(
N == 1 &&
"Invalid number of operands!");
3569 "All instructions that want to replicate non-zero half-word "
3570 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3572 unsigned Elem =
Value & 0xffff;
3574 Elem = (Elem >> 8) | 0x200;
3578 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
3579 assert(
N == 1 &&
"Invalid number of operands!");
3582 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3586 void addNEONvmovi32ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3587 assert(
N == 1 &&
"Invalid number of operands!");
3593 "All instructions that want to replicate non-zero word "
3594 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3596 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3600 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
3601 assert(
N == 1 &&
"Invalid number of operands!");
3606 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3612 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
3613 assert(
N == 1 &&
"Invalid number of operands!");
3618 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
3619 assert(
N == 1 &&
"Invalid number of operands!");
3624 void addMveSaturateOperands(
MCInst &Inst,
unsigned N)
const {
3625 assert(
N == 1 &&
"Invalid number of operands!");
3627 unsigned Imm =
CE->getValue();
3628 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3634 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S,
3635 ARMAsmParser &Parser) {
3636 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3643 static std::unique_ptr<ARMOperand>
3645 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3653 ARMAsmParser &Parser) {
3654 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3661 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S,
3662 ARMAsmParser &Parser) {
3663 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3664 Op->Cop.Val = CopVal;
3670 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S,
3671 ARMAsmParser &Parser) {
3672 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3673 Op->Cop.Val = CopVal;
3679 static std::unique_ptr<ARMOperand>
3680 CreateCoprocOption(
unsigned Val,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3681 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3689 ARMAsmParser &Parser) {
3690 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3691 Op->Reg.RegNum =
Reg;
3697 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S,
3698 ARMAsmParser &Parser) {
3699 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3700 Op->Tok.Data = Str.data();
3701 Op->Tok.Length = Str.size();
3708 ARMAsmParser &Parser) {
3709 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3710 Op->Reg.RegNum =
Reg;
3716 static std::unique_ptr<ARMOperand>
3719 SMLoc E, ARMAsmParser &Parser) {
3720 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3721 Op->RegShiftedReg.ShiftTy = ShTy;
3722 Op->RegShiftedReg.SrcReg = SrcReg;
3723 Op->RegShiftedReg.ShiftReg = ShiftReg;
3724 Op->RegShiftedReg.ShiftImm = ShiftImm;
3730 static std::unique_ptr<ARMOperand>
3733 ARMAsmParser &Parser) {
3734 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3735 Op->RegShiftedImm.ShiftTy = ShTy;
3736 Op->RegShiftedImm.SrcReg = SrcReg;
3737 Op->RegShiftedImm.ShiftImm = ShiftImm;
3743 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3745 ARMAsmParser &Parser) {
3746 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3747 Op->ShifterImm.isASR = isASR;
3748 Op->ShifterImm.Imm =
Imm;
3754 static std::unique_ptr<ARMOperand>
3755 CreateRotImm(
unsigned Imm,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3756 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3757 Op->RotImm.Imm =
Imm;
3763 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3765 ARMAsmParser &Parser) {
3766 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3768 Op->ModImm.Rot = Rot;
3774 static std::unique_ptr<ARMOperand>
3776 ARMAsmParser &Parser) {
3777 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3784 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3785 unsigned Width,
SMLoc S,
3787 ARMAsmParser &Parser) {
3788 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3789 Op->Bitfield.LSB = LSB;
3790 Op->Bitfield.Width = Width;
3796 static std::unique_ptr<ARMOperand>
3798 SMLoc StartLoc,
SMLoc EndLoc, ARMAsmParser &Parser) {
3799 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3800 KindTy
Kind = k_RegisterList;
3802 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
3803 Regs.front().second)) {
3804 if (Regs.back().second == ARM::VPR)
3805 Kind = k_FPDRegisterListWithVPR;
3807 Kind = k_DPRRegisterList;
3808 }
else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
3809 Regs.front().second)) {
3810 if (Regs.back().second == ARM::VPR)
3811 Kind = k_FPSRegisterListWithVPR;
3813 Kind = k_SPRRegisterList;
3814 }
else if (Regs.front().second == ARM::VPR) {
3815 assert(Regs.size() == 1 &&
3816 "Register list starting with VPR expected to only contain VPR");
3817 Kind = k_FPSRegisterListWithVPR;
3820 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3821 Kind = k_RegisterListWithAPSR;
3825 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3826 for (
const auto &
P : Regs)
3827 Op->Registers.push_back(
P.second);
3829 Op->StartLoc = StartLoc;
3830 Op->EndLoc = EndLoc;
3834 static std::unique_ptr<ARMOperand>
3836 SMLoc E, ARMAsmParser &Parser) {
3837 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3838 Op->VectorList.RegNum =
Reg;
3839 Op->VectorList.Count = Count;
3840 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3846 static std::unique_ptr<ARMOperand>
3847 CreateVectorListAllLanes(
MCRegister Reg,
unsigned Count,
bool isDoubleSpaced,
3849 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3850 Op->VectorList.RegNum =
Reg;
3851 Op->VectorList.Count = Count;
3852 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3858 static std::unique_ptr<ARMOperand>
3861 ARMAsmParser &Parser) {
3862 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3863 Op->VectorList.RegNum =
Reg;
3864 Op->VectorList.Count = Count;
3865 Op->VectorList.LaneIndex =
Index;
3866 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3872 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx,
SMLoc S,
3874 ARMAsmParser &Parser) {
3875 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3876 Op->VectorIndex.Val =
Idx;
3882 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
3883 SMLoc E, ARMAsmParser &Parser) {
3884 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3891 static std::unique_ptr<ARMOperand>
3894 bool isNegative,
SMLoc S,
SMLoc E, ARMAsmParser &Parser,
3896 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3897 Op->Memory.BaseRegNum = BaseReg;
3898 Op->Memory.OffsetImm = OffsetImm;
3899 Op->Memory.OffsetRegNum = OffsetReg;
3900 Op->Memory.ShiftType = ShiftType;
3901 Op->Memory.ShiftImm = ShiftImm;
3902 Op->Memory.Alignment = Alignment;
3903 Op->Memory.isNegative = isNegative;
3906 Op->AlignmentLoc = AlignmentLoc;
3910 static std::unique_ptr<ARMOperand>
3912 unsigned ShiftImm,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3913 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3914 Op->PostIdxReg.RegNum =
Reg;
3915 Op->PostIdxReg.isAdd = isAdd;
3916 Op->PostIdxReg.ShiftTy = ShiftTy;
3917 Op->PostIdxReg.ShiftImm = ShiftImm;
3923 static std::unique_ptr<ARMOperand>
3925 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3926 Op->MBOpt.Val = Opt;
3932 static std::unique_ptr<ARMOperand>
3934 ARMAsmParser &Parser) {
3935 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3936 Op->ISBOpt.Val = Opt;
3942 static std::unique_ptr<ARMOperand>
3944 ARMAsmParser &Parser) {
3945 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3946 Op->TSBOpt.Val = Opt;
3952 static std::unique_ptr<ARMOperand>
3954 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3961 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S,
3962 ARMAsmParser &Parser) {
3963 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3964 Op->MMask.Val = MMask;
3970 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S,
3971 ARMAsmParser &Parser) {
3972 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3973 Op->BankedReg.Val =
Reg;
4000 case k_ITCondMask: {
4001 static const char *
const MaskStr[] = {
4002 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4003 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4004 "(t)",
"(tett)",
"(tet)",
"(tete)",
4005 "(te)",
"(teet)",
"(tee)",
"(teee)",
4007 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4008 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4012 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4015 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4017 case k_CoprocOption:
4018 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4021 OS <<
"<mask: " << getMSRMask() <<
">";
4024 OS <<
"<banked reg: " << getBankedReg() <<
">";
4029 case k_MemBarrierOpt:
4030 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4032 case k_InstSyncBarrierOpt:
4033 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4035 case k_TraceSyncBarrierOpt:
4036 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4043 OS <<
" offset-imm:" << *
Memory.OffsetImm;
4045 OS <<
" offset-reg:" << (
Memory.isNegative ?
"-" :
"")
4049 OS <<
" shift-imm:" <<
Memory.ShiftImm;
4052 OS <<
" alignment:" <<
Memory.Alignment;
4055 case k_PostIndexRegister:
4056 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4057 <<
RegName(PostIdxReg.RegNum);
4060 << PostIdxReg.ShiftImm;
4063 case k_ProcIFlags: {
4064 OS <<
"<ARM_PROC::";
4065 unsigned IFlags = getProcIFlags();
4066 for (
int i=2; i >= 0; --i)
4067 if (IFlags & (1 << i))
4075 case k_ShifterImmediate:
4076 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4077 <<
" #" << ShifterImm.Imm <<
">";
4079 case k_ShiftedRegister:
4080 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4082 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4084 case k_ShiftedImmediate:
4085 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4087 << RegShiftedImm.ShiftImm <<
">";
4089 case k_RotateImmediate:
4090 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4092 case k_ModifiedImmediate:
4093 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4094 << ModImm.Rot <<
")>";
4096 case k_ConstantPoolImmediate:
4097 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
4099 case k_BitfieldDescriptor:
4100 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4101 <<
", width: " <<
Bitfield.Width <<
">";
4103 case k_RegisterList:
4104 case k_RegisterListWithAPSR:
4105 case k_DPRRegisterList:
4106 case k_SPRRegisterList:
4107 case k_FPSRegisterListWithVPR:
4108 case k_FPDRegisterListWithVPR: {
4109 OS <<
"<register_list ";
4112 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4114 if (++
I <
E)
OS <<
", ";
4121 OS <<
"<vector_list " << VectorList.Count <<
" * "
4122 <<
RegName(VectorList.RegNum) <<
">";
4124 case k_VectorListAllLanes:
4125 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4126 <<
RegName(VectorList.RegNum) <<
">";
4128 case k_VectorListIndexed:
4129 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4130 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4133 OS <<
"'" << getToken() <<
"'";
4136 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4150 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4151 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4152 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4157 unsigned MnemonicOpsEndInd = 1;
4161 static_cast<ARMOperand &
>(*
Operands[0]).getToken() ==
"cps") {
4163 static_cast<ARMOperand &
>(*
Operands[1]).getImm()->getKind() ==
4165 (dyn_cast<MCConstantExpr>(
4166 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4168 dyn_cast<MCConstantExpr>(
4169 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4171 ++MnemonicOpsEndInd;
4175 bool RHSCondCode =
false;
4176 while (MnemonicOpsEndInd <
Operands.size()) {
4177 auto Op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
4179 if (
Op.isITMask()) {
4181 MnemonicOpsEndInd++;
4182 }
else if (
Op.isToken() &&
4186 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4187 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4193 MnemonicOpsEndInd++;
4196 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4197 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4198 MnemonicOpsEndInd++;
4202 return MnemonicOpsEndInd;
4207 const AsmToken &Tok = getParser().getTok();
4210 Reg = tryParseRegister();
4217 if (parseRegister(
Reg, StartLoc, EndLoc))
4225MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4235 .
Case(
"r13", ARM::SP)
4236 .
Case(
"r14", ARM::LR)
4237 .
Case(
"r15", ARM::PC)
4238 .
Case(
"ip", ARM::R12)
4240 .
Case(
"a1", ARM::R0)
4241 .
Case(
"a2", ARM::R1)
4242 .
Case(
"a3", ARM::R2)
4243 .
Case(
"a4", ARM::R3)
4244 .
Case(
"v1", ARM::R4)
4245 .
Case(
"v2", ARM::R5)
4246 .
Case(
"v3", ARM::R6)
4247 .
Case(
"v4", ARM::R7)
4248 .
Case(
"v5", ARM::R8)
4249 .
Case(
"v6", ARM::R9)
4250 .
Case(
"v7", ARM::R10)
4251 .
Case(
"v8", ARM::R11)
4252 .
Case(
"sb", ARM::R9)
4253 .
Case(
"sl", ARM::R10)
4254 .
Case(
"fp", ARM::R11)
4261 auto Entry = RegisterReqs.
find(lowerCase);
4263 if (Entry == RegisterReqs.
end())
4266 return Entry->getValue();
4270 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4278std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4282 return std::nullopt;
4304 auto ShiftTyOpt = tryParseShiftToken();
4305 if (ShiftTyOpt == std::nullopt)
4307 auto ShiftTy = ShiftTyOpt.value();
4314 std::unique_ptr<ARMOperand> PrevOp(
4315 (ARMOperand *)
Operands.pop_back_val().release());
4316 if (!PrevOp->isReg())
4317 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4334 const MCExpr *ShiftExpr =
nullptr;
4335 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4336 Error(ImmLoc,
"invalid immediate shift value");
4342 Error(ImmLoc,
"invalid immediate shift value");
4348 Imm =
CE->getValue();
4352 Error(ImmLoc,
"immediate shift value out of range");
4362 ShiftReg = tryParseRegister();
4364 Error(L,
"expected immediate or register in shift operand");
4369 "expected immediate or register in shift operand");
4375 Operands.push_back(ARMOperand::CreateShiftedRegister(
4376 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *
this));
4378 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4398 Operands.push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4403 ExclaimTok.
getLoc(), *
this));
4416 if (getParser().parseExpression(ImmVal))
4420 return TokError(
"immediate value expected for vector index");
4429 getContext(), *
this));
4447 if (
Name.size() < 2 ||
Name[0] != CoprocOp)
4451 switch (
Name.size()) {
4474 case '0':
return 10;
4475 case '1':
return 11;
4476 case '2':
return 12;
4477 case '3':
return 13;
4478 case '4':
return 14;
4479 case '5':
return 15;
4519 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4538 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4555 if (getParser().parseExpression(Expr))
4556 return Error(Loc,
"illegal expression");
4558 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4560 "coprocessor option must be an immediate in range [0, 255]");
4561 int Val =
CE->getValue();
4569 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4580 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4584 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4585 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4586 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4587 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4588 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4589 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4590 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4591 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4600 Regs.emplace_back(Enc,
Reg);
4601 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4602 if (J->first == Enc) {
4603 Regs.erase(J.base());
4615 bool AllowRAAC,
bool IsLazyLoadStore,
4619 return TokError(
"Token is not a Left Curly Brace");
4626 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4629 return Error(RegLoc,
"register expected");
4630 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4631 return Error(RegLoc,
"pseudo-register not allowed");
4642 bool VSCCLRMAdjustEncoding =
false;
4645 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4646 Reg = getDRegFromQReg(
Reg);
4647 EReg =
MRI->getEncodingValue(
Reg);
4652 if (
Reg == ARM::RA_AUTH_CODE ||
4653 ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4654 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4655 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg))
4656 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4657 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
Reg))
4658 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4659 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4660 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4661 else if (
Reg == ARM::VPR)
4662 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4664 return Error(RegLoc,
"invalid register in register list");
4667 EReg =
MRI->getEncodingValue(
Reg);
4676 if (
Reg == ARM::RA_AUTH_CODE)
4677 return Error(RegLoc,
"pseudo-register not allowed");
4680 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4682 return Error(AfterMinusLoc,
"register expected");
4683 if (EndReg == ARM::RA_AUTH_CODE)
4684 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4686 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4687 EndReg = getDRegFromQReg(EndReg) + 1;
4694 return Error(AfterMinusLoc,
"invalid register in register list");
4696 if (
MRI->getEncodingValue(
Reg) >
MRI->getEncodingValue(EndReg))
4697 return Error(AfterMinusLoc,
"bad range in register list");
4700 while (
Reg != EndReg) {
4702 EReg =
MRI->getEncodingValue(
Reg);
4703 if (VSCCLRMAdjustEncoding)
4708 ") in register list");
4718 Reg = tryParseRegister(AllowOutOfBoundReg);
4720 return Error(RegLoc,
"register expected");
4721 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4722 return Error(RegLoc,
"pseudo-register not allowed");
4724 bool isQReg =
false;
4725 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(