68#define DEBUG_TYPE "asm-parser"
83enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
86 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
87 cl::desc(
"Allow conditional instructions outdside of an IT block"),
89 "Accept in both ISAs, emit implicit ITs in Thumb"),
91 "Warn in ARM, reject in Thumb"),
93 "Accept in ARM, reject in Thumb"),
94 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
95 "Warn in ARM, emit implicit ITs in Thumb")));
100enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
102static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
109 return (Mask >> (5 - Position) & 1);
118 Locs PersonalityLocs;
119 Locs PersonalityIndexLocs;
120 Locs HandlerDataLocs;
126 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
127 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
128 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
130 bool hasPersonality()
const {
131 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
134 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
135 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
136 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
137 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
138 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
140 void saveFPReg(
int Reg) { FPReg =
Reg; }
141 int getFPReg()
const {
return FPReg; }
143 void emitFnStartLocNotes()
const {
144 for (
const SMLoc &Loc : FnStartLocs)
145 Parser.
Note(Loc,
".fnstart was specified here");
148 void emitCantUnwindLocNotes()
const {
149 for (
const SMLoc &Loc : CantUnwindLocs)
150 Parser.
Note(Loc,
".cantunwind was specified here");
153 void emitHandlerDataLocNotes()
const {
154 for (
const SMLoc &Loc : HandlerDataLocs)
155 Parser.
Note(Loc,
".handlerdata was specified here");
158 void emitPersonalityLocNotes()
const {
160 PE = PersonalityLocs.end(),
161 PII = PersonalityIndexLocs.begin(),
162 PIE = PersonalityIndexLocs.end();
163 PI != PE || PII != PIE;) {
164 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
165 Parser.
Note(*PI++,
".personality was specified here");
166 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
167 Parser.
Note(*PII++,
".personalityindex was specified here");
170 "at the same location");
175 FnStartLocs = Locs();
176 CantUnwindLocs = Locs();
177 PersonalityLocs = Locs();
178 HandlerDataLocs = Locs();
179 PersonalityIndexLocs = Locs();
185class ARMMnemonicSets {
196 return CDE.
count(Mnemonic);
201 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
204 return CDEWithVPTSuffix.
count(Mnemonic);
209 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
219 bool isCDEDualRegInstr(
StringRef Mnemonic) {
222 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
223 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
224 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
229 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
230 "cx2",
"cx2a",
"cx2d",
"cx2da",
231 "cx3",
"cx3a",
"cx3d",
"cx3da", })
234 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
236 CDEWithVPTSuffix.
insert(Mnemonic);
237 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"t");
238 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"e");
249 "do not have a target streamer");
257 bool NextSymbolIsThumb;
259 bool useImplicitITThumb()
const {
260 return ImplicitItMode == ImplicitItModeTy::Always ||
261 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
264 bool useImplicitITARM()
const {
265 return ImplicitItMode == ImplicitItModeTy::Always ||
266 ImplicitItMode == ImplicitItModeTy::ARMOnly;
281 unsigned CurPosition;
297 if (!inImplicitITBlock()) {
311 for (
const MCInst &Inst : PendingConditionalInsts) {
314 PendingConditionalInsts.clear();
318 ITState.CurPosition = ~0
U;
321 bool inITBlock() {
return ITState.CurPosition != ~0
U; }
322 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
323 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
325 bool lastInITBlock() {
329 void forwardITPosition() {
330 if (!inITBlock())
return;
335 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
336 ITState.CurPosition = ~0
U;
340 void rewindImplicitITPosition() {
341 assert(inImplicitITBlock());
342 assert(ITState.CurPosition > 1);
343 ITState.CurPosition--;
345 unsigned NewMask = 0;
346 NewMask |= ITState.Mask & (0xC << TZ);
347 NewMask |= 0x2 << TZ;
348 ITState.Mask = NewMask;
353 void discardImplicitITBlock() {
354 assert(inImplicitITBlock());
355 assert(ITState.CurPosition == 1);
356 ITState.CurPosition = ~0
U;
360 unsigned getDRegFromQReg(
unsigned QReg)
const {
361 return MRI->getSubReg(QReg, ARM::dsub_0);
366 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
372 void invertCurrentITCondition() {
373 if (ITState.CurPosition == 1) {
376 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
381 bool isITBlockFull() {
382 return inITBlock() && (ITState.Mask & 1);
388 assert(inImplicitITBlock());
393 unsigned NewMask = 0;
395 NewMask |= ITState.Mask & (0xE << TZ);
397 NewMask |= (
Cond != ITState.Cond) << TZ;
399 NewMask |= 1 << (TZ - 1);
400 ITState.Mask = NewMask;
404 void startImplicitITBlock() {
408 ITState.CurPosition = 1;
409 ITState.IsExplicit =
false;
420 ITState.CurPosition = 0;
421 ITState.IsExplicit =
true;
426 unsigned CurPosition;
428 bool inVPTBlock() {
return VPTState.CurPosition != ~0
U; }
429 void forwardVPTPosition() {
430 if (!inVPTBlock())
return;
432 if (++VPTState.CurPosition == 5 - TZ)
433 VPTState.CurPosition = ~0
U;
449 unsigned ListNo,
bool IsARPop =
false);
456 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
457 bool AllowRAAC =
false);
460 bool parseImmExpr(int64_t &Out);
463 unsigned &ShiftAmount);
464 bool parseLiteralValues(
unsigned Size,
SMLoc L);
465 bool parseDirectiveThumb(
SMLoc L);
466 bool parseDirectiveARM(
SMLoc L);
467 bool parseDirectiveThumbFunc(
SMLoc L);
468 bool parseDirectiveCode(
SMLoc L);
469 bool parseDirectiveSyntax(
SMLoc L);
471 bool parseDirectiveUnreq(
SMLoc L);
472 bool parseDirectiveArch(
SMLoc L);
473 bool parseDirectiveEabiAttr(
SMLoc L);
474 bool parseDirectiveCPU(
SMLoc L);
475 bool parseDirectiveFPU(
SMLoc L);
476 bool parseDirectiveFnStart(
SMLoc L);
477 bool parseDirectiveFnEnd(
SMLoc L);
478 bool parseDirectiveCantUnwind(
SMLoc L);
479 bool parseDirectivePersonality(
SMLoc L);
480 bool parseDirectiveHandlerData(
SMLoc L);
481 bool parseDirectiveSetFP(
SMLoc L);
482 bool parseDirectivePad(
SMLoc L);
483 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
484 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
485 bool parseDirectiveLtorg(
SMLoc L);
486 bool parseDirectiveEven(
SMLoc L);
487 bool parseDirectivePersonalityIndex(
SMLoc L);
488 bool parseDirectiveUnwindRaw(
SMLoc L);
489 bool parseDirectiveTLSDescSeq(
SMLoc L);
490 bool parseDirectiveMovSP(
SMLoc L);
491 bool parseDirectiveObjectArch(
SMLoc L);
492 bool parseDirectiveArchExtension(
SMLoc L);
493 bool parseDirectiveAlign(
SMLoc L);
494 bool parseDirectiveThumbSet(
SMLoc L);
496 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
497 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
498 bool parseDirectiveSEHSaveSP(
SMLoc L);
499 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
500 bool parseDirectiveSEHSaveLR(
SMLoc L);
501 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
502 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
503 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
504 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
505 bool parseDirectiveSEHCustom(
SMLoc L);
509 unsigned &PredicationCode,
510 unsigned &VPTPredicationCode,
bool &CarrySetting,
511 unsigned &ProcessorIMod,
StringRef &ITMask);
513 StringRef FullInst,
bool &CanAcceptCarrySet,
514 bool &CanAcceptPredicationCode,
515 bool &CanAcceptVPTPredicationCode);
518 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
bool CarrySetting,
527 bool isThumbOne()
const {
531 bool isThumbTwo()
const {
535 bool hasThumb()
const {
539 bool hasThumb2()
const {
543 bool hasV6Ops()
const {
547 bool hasV6T2Ops()
const {
551 bool hasV6MOps()
const {
555 bool hasV7Ops()
const {
559 bool hasV8Ops()
const {
563 bool hasV8MBaseline()
const {
567 bool hasV8MMainline()
const {
570 bool hasV8_1MMainline()
const {
573 bool hasMVE()
const {
576 bool hasMVEFloat()
const {
579 bool hasCDE()
const {
582 bool has8MSecExt()
const {
586 bool hasARM()
const {
590 bool hasDSP()
const {
594 bool hasD32()
const {
598 bool hasV8_1aOps()
const {
602 bool hasRAS()
const {
608 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
612 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
614 bool isMClass()
const {
621#define GET_ASSEMBLER_HEADER
622#include "ARMGenAsmMatcher.inc"
638 return parsePKHImm(O,
"lsl", 0, 31);
641 return parsePKHImm(O,
"asr", 1, 32);
665 bool isITBlockTerminator(
MCInst &Inst)
const;
668 bool Load,
bool ARMMode,
bool Writeback);
671 enum ARMMatchResultTy {
673 Match_RequiresNotITBlock,
675 Match_RequiresThumb2,
677 Match_RequiresFlagSetting,
678#define GET_OPERAND_DIAGNOSTIC_TYPES
679#include "ARMGenAsmMatcher.inc"
696 getTargetStreamer().emitTargetAttributes(STI);
699 ITState.CurPosition = ~0
U;
701 VPTState.CurPosition = ~0
U;
703 NextSymbolIsThumb =
false;
709 SMLoc &EndLoc)
override;
715 unsigned Kind)
override;
721 bool MatchingInlineAsm)
override;
724 bool MatchingInlineAsm,
bool &EmitInITBlock,
727 struct NearMissMessage {
732 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
758 k_InstSyncBarrierOpt,
759 k_TraceSyncBarrierOpt,
768 k_RegisterListWithAPSR,
771 k_FPSRegisterListWithVPR,
772 k_FPDRegisterListWithVPR,
774 k_VectorListAllLanes,
781 k_ConstantPoolImmediate,
782 k_BitfieldDescriptor,
786 SMLoc StartLoc, EndLoc, AlignmentLoc;
801 struct CoprocOptionOp {
843 struct VectorListOp {
850 struct VectorIndexOp {
864 unsigned OffsetRegNum;
869 unsigned isNegative : 1;
872 struct PostIdxRegOp {
879 struct ShifterImmOp {
884 struct RegShiftedRegOp {
891 struct RegShiftedImmOp {
915 struct CoprocOptionOp CoprocOption;
916 struct MBOptOp MBOpt;
917 struct ISBOptOp ISBOpt;
918 struct TSBOptOp TSBOpt;
919 struct ITMaskOp ITMask;
921 struct MMaskOp MMask;
922 struct BankedRegOp BankedReg;
925 struct VectorListOp VectorList;
926 struct VectorIndexOp VectorIndex;
929 struct PostIdxRegOp PostIdxReg;
930 struct ShifterImmOp ShifterImm;
931 struct RegShiftedRegOp RegShiftedReg;
932 struct RegShiftedImmOp RegShiftedImm;
933 struct RotImmOp RotImm;
934 struct ModImmOp ModImm;
939 ARMOperand(KindTy K) :
Kind(
K) {}
952 SMLoc getAlignmentLoc()
const {
953 assert(Kind == k_Memory &&
"Invalid access!");
958 assert(Kind == k_CondCode &&
"Invalid access!");
963 assert(isVPTPred() &&
"Invalid access!");
967 unsigned getCoproc()
const {
968 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
973 assert(Kind == k_Token &&
"Invalid access!");
977 unsigned getReg()
const override {
978 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
983 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
984 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
985 Kind == k_FPSRegisterListWithVPR ||
986 Kind == k_FPDRegisterListWithVPR) &&
991 const MCExpr *getImm()
const {
996 const MCExpr *getConstantPoolImm()
const {
997 assert(isConstantPoolImm() &&
"Invalid access!");
1001 unsigned getVectorIndex()
const {
1002 assert(Kind == k_VectorIndex &&
"Invalid access!");
1003 return VectorIndex.Val;
1007 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1012 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1017 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1022 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1026 unsigned getMSRMask()
const {
1027 assert(Kind == k_MSRMask &&
"Invalid access!");
1031 unsigned getBankedReg()
const {
1032 assert(Kind == k_BankedReg &&
"Invalid access!");
1033 return BankedReg.Val;
1036 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1037 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1038 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1039 bool isCondCode()
const {
return Kind == k_CondCode; }
1040 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1041 bool isCCOut()
const {
return Kind == k_CCOut; }
1042 bool isITMask()
const {
return Kind == k_ITCondMask; }
1043 bool isITCondCode()
const {
return Kind == k_CondCode; }
1044 bool isImm()
const override {
1045 return Kind == k_Immediate;
1048 bool isARMBranchTarget()
const {
1049 if (!
isImm())
return false;
1051 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1052 return CE->getValue() % 4 == 0;
1057 bool isThumbBranchTarget()
const {
1058 if (!
isImm())
return false;
1060 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1061 return CE->getValue() % 2 == 0;
1067 template<
unsigned w
idth,
unsigned scale>
1068 bool isUnsignedOffset()
const {
1069 if (!
isImm())
return false;
1070 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1072 int64_t Val =
CE->getValue();
1074 int64_t
Max =
Align * ((1LL << width) - 1);
1075 return ((Val %
Align) == 0) && (Val >= 0) && (Val <= Max);
1082 template<
unsigned w
idth,
unsigned scale>
1083 bool isSignedOffset()
const {
1084 if (!
isImm())
return false;
1085 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1087 int64_t Val =
CE->getValue();
1089 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1090 int64_t Min = -
Align * (1LL << (width-1));
1091 return ((Val %
Align) == 0) && (Val >= Min) && (Val <= Max);
1098 bool isLEOffset()
const {
1099 if (!
isImm())
return false;
1100 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1102 int64_t Val =
CE->getValue();
1103 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1112 bool isThumbMemPC()
const {
1115 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1117 if (!CE)
return false;
1118 Val =
CE->getValue();
1120 else if (isGPRMem()) {
1121 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
1122 if(
Memory.BaseRegNum != ARM::PC)
return false;
1123 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
1124 Val =
CE->getValue();
1129 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1132 bool isFPImm()
const {
1133 if (!
isImm())
return false;
1135 if (!CE)
return false;
1140 template<
int64_t N,
int64_t M>
1141 bool isImmediate()
const {
1142 if (!
isImm())
return false;
1144 if (!CE)
return false;
1145 int64_t
Value =
CE->getValue();
1149 template<
int64_t N,
int64_t M>
1150 bool isImmediateS4()
const {
1151 if (!
isImm())
return false;
1153 if (!CE)
return false;
1154 int64_t
Value =
CE->getValue();
1157 template<
int64_t N,
int64_t M>
1158 bool isImmediateS2()
const {
1159 if (!
isImm())
return false;
1161 if (!CE)
return false;
1162 int64_t
Value =
CE->getValue();
1165 bool isFBits16()
const {
1166 return isImmediate<0, 17>();
1168 bool isFBits32()
const {
1169 return isImmediate<1, 33>();
1171 bool isImm8s4()
const {
1172 return isImmediateS4<-1020, 1020>();
1174 bool isImm7s4()
const {
1175 return isImmediateS4<-508, 508>();
1177 bool isImm7Shift0()
const {
1178 return isImmediate<-127, 127>();
1180 bool isImm7Shift1()
const {
1181 return isImmediateS2<-255, 255>();
1183 bool isImm7Shift2()
const {
1184 return isImmediateS4<-511, 511>();
1186 bool isImm7()
const {
1187 return isImmediate<-127, 127>();
1189 bool isImm0_1020s4()
const {
1190 return isImmediateS4<0, 1020>();
1192 bool isImm0_508s4()
const {
1193 return isImmediateS4<0, 508>();
1195 bool isImm0_508s4Neg()
const {
1196 if (!
isImm())
return false;
1198 if (!CE)
return false;
1199 int64_t
Value = -
CE->getValue();
1204 bool isImm0_4095Neg()
const {
1205 if (!
isImm())
return false;
1207 if (!CE)
return false;
1212 if ((
CE->getValue() >> 32) > 0)
return false;
1217 bool isImm0_7()
const {
1218 return isImmediate<0, 7>();
1221 bool isImm1_16()
const {
1222 return isImmediate<1, 16>();
1225 bool isImm1_32()
const {
1226 return isImmediate<1, 32>();
1229 bool isImm8_255()
const {
1230 return isImmediate<8, 255>();
1233 bool isImm0_255Expr()
const {
1241 int64_t
Value =
CE->getValue();
1242 return isUInt<8>(
Value);
1245 bool isImm256_65535Expr()
const {
1246 if (!
isImm())
return false;
1250 if (!CE)
return true;
1251 int64_t
Value =
CE->getValue();
1255 bool isImm0_65535Expr()
const {
1256 if (!
isImm())
return false;
1260 if (!CE)
return true;
1261 int64_t
Value =
CE->getValue();
1265 bool isImm24bit()
const {
1266 return isImmediate<0, 0xffffff + 1>();
1269 bool isImmThumbSR()
const {
1270 return isImmediate<1, 33>();
1273 bool isPKHLSLImm()
const {
1274 return isImmediate<0, 32>();
1277 bool isPKHASRImm()
const {
1278 return isImmediate<0, 33>();
1281 bool isAdrLabel()
const {
1284 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1288 if (!
isImm())
return false;
1290 if (!CE)
return false;
1291 int64_t
Value =
CE->getValue();
1296 bool isT2SOImm()
const {
1299 if (
isImm() && !isa<MCConstantExpr>(getImm())) {
1302 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1306 if (!
isImm())
return false;
1308 if (!CE)
return false;
1309 int64_t
Value =
CE->getValue();
1313 bool isT2SOImmNot()
const {
1314 if (!
isImm())
return false;
1316 if (!CE)
return false;
1317 int64_t
Value =
CE->getValue();
1322 bool isT2SOImmNeg()
const {
1323 if (!
isImm())
return false;
1325 if (!CE)
return false;
1326 int64_t
Value =
CE->getValue();
1332 bool isSetEndImm()
const {
1333 if (!
isImm())
return false;
1335 if (!CE)
return false;
1336 int64_t
Value =
CE->getValue();
1340 bool isReg()
const override {
return Kind == k_Register; }
1341 bool isRegList()
const {
return Kind == k_RegisterList; }
1342 bool isRegListWithAPSR()
const {
1343 return Kind == k_RegisterListWithAPSR ||
Kind == k_RegisterList;
1345 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1346 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1347 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1348 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1349 bool isToken()
const override {
return Kind == k_Token; }
1350 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1351 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1352 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1353 bool isMem()
const override {
1354 return isGPRMem() || isMVEMem();
1356 bool isMVEMem()
const {
1357 if (Kind != k_Memory)
1360 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum) &&
1361 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
Memory.BaseRegNum))
1363 if (
Memory.OffsetRegNum &&
1364 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1369 bool isGPRMem()
const {
1370 if (Kind != k_Memory)
1373 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum))
1375 if (
Memory.OffsetRegNum &&
1376 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.OffsetRegNum))
1380 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1381 bool isRegShiftedReg()
const {
1382 return Kind == k_ShiftedRegister &&
1383 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1384 RegShiftedReg.SrcReg) &&
1385 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1386 RegShiftedReg.ShiftReg);
1388 bool isRegShiftedImm()
const {
1389 return Kind == k_ShiftedImmediate &&
1390 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1391 RegShiftedImm.SrcReg);
1393 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1395 template<
unsigned Min,
unsigned Max>
1396 bool isPowerTwoInRange()
const {
1397 if (!
isImm())
return false;
1399 if (!CE)
return false;
1400 int64_t
Value =
CE->getValue();
1404 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1406 bool isModImmNot()
const {
1407 if (!
isImm())
return false;
1409 if (!CE)
return false;
1410 int64_t
Value =
CE->getValue();
1414 bool isModImmNeg()
const {
1415 if (!
isImm())
return false;
1417 if (!CE)
return false;
1418 int64_t
Value =
CE->getValue();
1423 bool isThumbModImmNeg1_7()
const {
1424 if (!
isImm())
return false;
1426 if (!CE)
return false;
1427 int32_t
Value = -(int32_t)
CE->getValue();
1431 bool isThumbModImmNeg8_255()
const {
1432 if (!
isImm())
return false;
1434 if (!CE)
return false;
1435 int32_t
Value = -(int32_t)
CE->getValue();
1439 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1440 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1441 bool isPostIdxRegShifted()
const {
1442 return Kind == k_PostIndexRegister &&
1443 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1445 bool isPostIdxReg()
const {
1448 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1452 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1453 (alignOK ||
Memory.Alignment == Alignment);
1455 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1459 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1464 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1465 (alignOK ||
Memory.Alignment == Alignment);
1467 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1471 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].
contains(
1476 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1477 (alignOK ||
Memory.Alignment == Alignment);
1479 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1483 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].
contains(
1488 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1489 (alignOK ||
Memory.Alignment == Alignment);
1491 bool isMemPCRelImm12()
const {
1492 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1495 if (
Memory.BaseRegNum != ARM::PC)
1498 if (!
Memory.OffsetImm)
return true;
1499 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1500 int64_t Val =
CE->getValue();
1501 return (Val > -4096 && Val < 4096) ||
1502 (Val == std::numeric_limits<int32_t>::min());
1507 bool isAlignedMemory()
const {
1508 return isMemNoOffset(
true);
1511 bool isAlignedMemoryNone()
const {
1512 return isMemNoOffset(
false, 0);
1515 bool isDupAlignedMemoryNone()
const {
1516 return isMemNoOffset(
false, 0);
1519 bool isAlignedMemory16()
const {
1520 if (isMemNoOffset(
false, 2))
1522 return isMemNoOffset(
false, 0);
1525 bool isDupAlignedMemory16()
const {
1526 if (isMemNoOffset(
false, 2))
1528 return isMemNoOffset(
false, 0);
1531 bool isAlignedMemory32()
const {
1532 if (isMemNoOffset(
false, 4))
1534 return isMemNoOffset(
false, 0);
1537 bool isDupAlignedMemory32()
const {
1538 if (isMemNoOffset(
false, 4))
1540 return isMemNoOffset(
false, 0);
1543 bool isAlignedMemory64()
const {
1544 if (isMemNoOffset(
false, 8))
1546 return isMemNoOffset(
false, 0);
1549 bool isDupAlignedMemory64()
const {
1550 if (isMemNoOffset(
false, 8))
1552 return isMemNoOffset(
false, 0);
1555 bool isAlignedMemory64or128()
const {
1556 if (isMemNoOffset(
false, 8))
1558 if (isMemNoOffset(
false, 16))
1560 return isMemNoOffset(
false, 0);
1563 bool isDupAlignedMemory64or128()
const {
1564 if (isMemNoOffset(
false, 8))
1566 if (isMemNoOffset(
false, 16))
1568 return isMemNoOffset(
false, 0);
1571 bool isAlignedMemory64or128or256()
const {
1572 if (isMemNoOffset(
false, 8))
1574 if (isMemNoOffset(
false, 16))
1576 if (isMemNoOffset(
false, 32))
1578 return isMemNoOffset(
false, 0);
1581 bool isAddrMode2()
const {
1582 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1584 if (
Memory.OffsetRegNum)
return true;
1586 if (!
Memory.OffsetImm)
return true;
1587 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1588 int64_t Val =
CE->getValue();
1589 return Val > -4096 && Val < 4096;
1594 bool isAM2OffsetImm()
const {
1595 if (!
isImm())
return false;
1598 if (!CE)
return false;
1599 int64_t Val =
CE->getValue();
1600 return (Val == std::numeric_limits<int32_t>::min()) ||
1601 (Val > -4096 && Val < 4096);
1604 bool isAddrMode3()
const {
1608 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1610 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1614 if (
Memory.OffsetRegNum)
return true;
1616 if (!
Memory.OffsetImm)
return true;
1617 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1618 int64_t Val =
CE->getValue();
1621 return (Val > -256 && Val < 256) ||
1622 Val == std::numeric_limits<int32_t>::min();
1627 bool isAM3Offset()
const {
1634 if (!CE)
return false;
1635 int64_t Val =
CE->getValue();
1637 return (Val > -256 && Val < 256) ||
1638 Val == std::numeric_limits<int32_t>::min();
1641 bool isAddrMode5()
const {
1645 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1647 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1649 if (
Memory.OffsetRegNum)
return false;
1651 if (!
Memory.OffsetImm)
return true;
1652 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1653 int64_t Val =
CE->getValue();
1654 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1655 Val == std::numeric_limits<int32_t>::min();
1660 bool isAddrMode5FP16()
const {
1664 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1666 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1668 if (
Memory.OffsetRegNum)
return false;
1670 if (!
Memory.OffsetImm)
return true;
1671 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1672 int64_t Val =
CE->getValue();
1673 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1674 Val == std::numeric_limits<int32_t>::min();
1679 bool isMemTBB()
const {
1680 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1686 bool isMemTBH()
const {
1687 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1694 bool isMemRegOffset()
const {
1695 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1700 bool isT2MemRegOffset()
const {
1701 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1712 bool isMemThumbRR()
const {
1715 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1722 bool isMemThumbRIs4()
const {
1723 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1727 if (!
Memory.OffsetImm)
return true;
1728 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1729 int64_t Val =
CE->getValue();
1730 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1735 bool isMemThumbRIs2()
const {
1736 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1740 if (!
Memory.OffsetImm)
return true;
1741 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1742 int64_t Val =
CE->getValue();
1743 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1748 bool isMemThumbRIs1()
const {
1749 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1753 if (!
Memory.OffsetImm)
return true;
1754 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1755 int64_t Val =
CE->getValue();
1756 return Val >= 0 && Val <= 31;
1761 bool isMemThumbSPI()
const {
1762 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1766 if (!
Memory.OffsetImm)
return true;
1767 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1768 int64_t Val =
CE->getValue();
1769 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1774 bool isMemImm8s4Offset()
const {
1778 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1780 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1783 if (!
Memory.OffsetImm)
return true;
1784 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1785 int64_t Val =
CE->getValue();
1787 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1788 Val == std::numeric_limits<int32_t>::min();
1793 bool isMemImm7s4Offset()
const {
1797 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1799 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1800 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1804 if (!
Memory.OffsetImm)
return true;
1805 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1806 int64_t Val =
CE->getValue();
1808 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1813 bool isMemImm0_1020s4Offset()
const {
1814 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1817 if (!
Memory.OffsetImm)
return true;
1818 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1819 int64_t Val =
CE->getValue();
1820 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1825 bool isMemImm8Offset()
const {
1826 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1829 if (
Memory.BaseRegNum == ARM::PC)
return false;
1831 if (!
Memory.OffsetImm)
return true;
1832 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1833 int64_t Val =
CE->getValue();
1834 return (Val == std::numeric_limits<int32_t>::min()) ||
1835 (Val > -256 && Val < 256);
1840 template<
unsigned Bits,
unsigned RegClassID>
1841 bool isMemImm7ShiftedOffset()
const {
1842 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1843 !ARMMCRegisterClasses[RegClassID].contains(
Memory.BaseRegNum))
1849 if (!
Memory.OffsetImm)
return true;
1850 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1851 int64_t Val =
CE->getValue();
1855 if (Val == INT32_MIN)
1858 unsigned Divisor = 1U <<
Bits;
1861 if (Val % Divisor != 0)
1866 return (Val >= -127 && Val <= 127);
1871 template <
int shift>
bool isMemRegRQOffset()
const {
1872 if (!isMVEMem() ||
Memory.OffsetImm !=
nullptr ||
Memory.Alignment != 0)
1875 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1878 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1892 template <
int shift>
bool isMemRegQOffset()
const {
1893 if (!isMVEMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1896 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1902 static_assert(shift < 56,
1903 "Such that we dont shift by a value higher than 62");
1904 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1905 int64_t Val =
CE->getValue();
1908 if ((Val & ((1U << shift) - 1)) != 0)
1914 int64_t
Range = (1U << (7 + shift)) - 1;
1915 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1920 bool isMemPosImm8Offset()
const {
1921 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1924 if (!
Memory.OffsetImm)
return true;
1925 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1926 int64_t Val =
CE->getValue();
1927 return Val >= 0 && Val < 256;
1932 bool isMemNegImm8Offset()
const {
1933 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1936 if (
Memory.BaseRegNum == ARM::PC)
return false;
1938 if (!
Memory.OffsetImm)
return false;
1939 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1940 int64_t Val =
CE->getValue();
1941 return (Val == std::numeric_limits<int32_t>::min()) ||
1942 (Val > -256 && Val < 0);
1947 bool isMemUImm12Offset()
const {
1948 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1951 if (!
Memory.OffsetImm)
return true;
1952 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1953 int64_t Val =
CE->getValue();
1954 return (Val >= 0 && Val < 4096);
1959 bool isMemImm12Offset()
const {
1964 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1967 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1970 if (!
Memory.OffsetImm)
return true;
1971 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1972 int64_t Val =
CE->getValue();
1973 return (Val > -4096 && Val < 4096) ||
1974 (Val == std::numeric_limits<int32_t>::min());
1981 bool isConstPoolAsmImm()
const {
1984 return (isConstantPoolImm());
1987 bool isPostIdxImm8()
const {
1988 if (!
isImm())
return false;
1990 if (!CE)
return false;
1991 int64_t Val =
CE->getValue();
1992 return (Val > -256 && Val < 256) ||
1993 (Val == std::numeric_limits<int32_t>::min());
1996 bool isPostIdxImm8s4()
const {
1997 if (!
isImm())
return false;
1999 if (!CE)
return false;
2000 int64_t Val =
CE->getValue();
2001 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2002 (Val == std::numeric_limits<int32_t>::min());
2005 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2006 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2007 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2010 bool isSingleSpacedVectorList()
const {
2011 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2014 bool isDoubleSpacedVectorList()
const {
2015 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2018 bool isVecListOneD()
const {
2019 if (!isSingleSpacedVectorList())
return false;
2020 return VectorList.Count == 1;
2023 bool isVecListTwoMQ()
const {
2024 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2025 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2029 bool isVecListDPair()
const {
2030 if (!isSingleSpacedVectorList())
return false;
2031 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2035 bool isVecListThreeD()
const {
2036 if (!isSingleSpacedVectorList())
return false;
2037 return VectorList.Count == 3;
2040 bool isVecListFourD()
const {
2041 if (!isSingleSpacedVectorList())
return false;
2042 return VectorList.Count == 4;
2045 bool isVecListDPairSpaced()
const {
2046 if (Kind != k_VectorList)
return false;
2047 if (isSingleSpacedVectorList())
return false;
2048 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2052 bool isVecListThreeQ()
const {
2053 if (!isDoubleSpacedVectorList())
return false;
2054 return VectorList.Count == 3;
2057 bool isVecListFourQ()
const {
2058 if (!isDoubleSpacedVectorList())
return false;
2059 return VectorList.Count == 4;
2062 bool isVecListFourMQ()
const {
2063 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2064 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2068 bool isSingleSpacedVectorAllLanes()
const {
2069 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2072 bool isDoubleSpacedVectorAllLanes()
const {
2073 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2076 bool isVecListOneDAllLanes()
const {
2077 if (!isSingleSpacedVectorAllLanes())
return false;
2078 return VectorList.Count == 1;
2081 bool isVecListDPairAllLanes()
const {
2082 if (!isSingleSpacedVectorAllLanes())
return false;
2083 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2087 bool isVecListDPairSpacedAllLanes()
const {
2088 if (!isDoubleSpacedVectorAllLanes())
return false;
2089 return VectorList.Count == 2;
2092 bool isVecListThreeDAllLanes()
const {
2093 if (!isSingleSpacedVectorAllLanes())
return false;
2094 return VectorList.Count == 3;
2097 bool isVecListThreeQAllLanes()
const {
2098 if (!isDoubleSpacedVectorAllLanes())
return false;
2099 return VectorList.Count == 3;
2102 bool isVecListFourDAllLanes()
const {
2103 if (!isSingleSpacedVectorAllLanes())
return false;
2104 return VectorList.Count == 4;
2107 bool isVecListFourQAllLanes()
const {
2108 if (!isDoubleSpacedVectorAllLanes())
return false;
2109 return VectorList.Count == 4;
2112 bool isSingleSpacedVectorIndexed()
const {
2113 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2116 bool isDoubleSpacedVectorIndexed()
const {
2117 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2120 bool isVecListOneDByteIndexed()
const {
2121 if (!isSingleSpacedVectorIndexed())
return false;
2122 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2125 bool isVecListOneDHWordIndexed()
const {
2126 if (!isSingleSpacedVectorIndexed())
return false;
2127 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2130 bool isVecListOneDWordIndexed()
const {
2131 if (!isSingleSpacedVectorIndexed())
return false;
2132 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2135 bool isVecListTwoDByteIndexed()
const {
2136 if (!isSingleSpacedVectorIndexed())
return false;
2137 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2140 bool isVecListTwoDHWordIndexed()
const {
2141 if (!isSingleSpacedVectorIndexed())
return false;
2142 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2145 bool isVecListTwoQWordIndexed()
const {
2146 if (!isDoubleSpacedVectorIndexed())
return false;
2147 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2150 bool isVecListTwoQHWordIndexed()
const {
2151 if (!isDoubleSpacedVectorIndexed())
return false;
2152 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2155 bool isVecListTwoDWordIndexed()
const {
2156 if (!isSingleSpacedVectorIndexed())
return false;
2157 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2160 bool isVecListThreeDByteIndexed()
const {
2161 if (!isSingleSpacedVectorIndexed())
return false;
2162 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2165 bool isVecListThreeDHWordIndexed()
const {
2166 if (!isSingleSpacedVectorIndexed())
return false;
2167 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2170 bool isVecListThreeQWordIndexed()
const {
2171 if (!isDoubleSpacedVectorIndexed())
return false;
2172 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2175 bool isVecListThreeQHWordIndexed()
const {
2176 if (!isDoubleSpacedVectorIndexed())
return false;
2177 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2180 bool isVecListThreeDWordIndexed()
const {
2181 if (!isSingleSpacedVectorIndexed())
return false;
2182 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2185 bool isVecListFourDByteIndexed()
const {
2186 if (!isSingleSpacedVectorIndexed())
return false;
2187 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2190 bool isVecListFourDHWordIndexed()
const {
2191 if (!isSingleSpacedVectorIndexed())
return false;
2192 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2195 bool isVecListFourQWordIndexed()
const {
2196 if (!isDoubleSpacedVectorIndexed())
return false;
2197 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2200 bool isVecListFourQHWordIndexed()
const {
2201 if (!isDoubleSpacedVectorIndexed())
return false;
2202 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2205 bool isVecListFourDWordIndexed()
const {
2206 if (!isSingleSpacedVectorIndexed())
return false;
2207 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2210 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2212 template <
unsigned NumLanes>
2213 bool isVectorIndexInRange()
const {
2214 if (Kind != k_VectorIndex)
return false;
2215 return VectorIndex.Val < NumLanes;
2218 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2219 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2220 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2221 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2223 template<
int PermittedValue,
int OtherPermittedValue>
2224 bool isMVEPairVectorIndex()
const {
2225 if (Kind != k_VectorIndex)
return false;
2226 return VectorIndex.Val == PermittedValue ||
2227 VectorIndex.Val == OtherPermittedValue;
2230 bool isNEONi8splat()
const {
2231 if (!
isImm())
return false;
2234 if (!CE)
return false;
2235 int64_t
Value =
CE->getValue();
2242 if (isNEONByteReplicate(2))
2248 if (!CE)
return false;
2249 unsigned Value =
CE->getValue();
2253 bool isNEONi16splatNot()
const {
2258 if (!CE)
return false;
2259 unsigned Value =
CE->getValue();
2264 if (isNEONByteReplicate(4))
2270 if (!CE)
return false;
2271 unsigned Value =
CE->getValue();
2275 bool isNEONi32splatNot()
const {
2280 if (!CE)
return false;
2281 unsigned Value =
CE->getValue();
2285 static bool isValidNEONi32vmovImm(int64_t
Value) {
2288 return ((
Value & 0xffffffffffffff00) == 0) ||
2289 ((
Value & 0xffffffffffff00ff) == 0) ||
2290 ((
Value & 0xffffffffff00ffff) == 0) ||
2291 ((
Value & 0xffffffff00ffffff) == 0) ||
2292 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2293 ((
Value & 0xffffffffff00ffff) == 0xffff);
2296 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2297 assert((Width == 8 || Width == 16 || Width == 32) &&
2298 "Invalid element width");
2299 assert(NumElems * Width <= 64 &&
"Invalid result width");
2307 int64_t
Value =
CE->getValue();
2315 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2317 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2320 for (
unsigned i = 1; i < NumElems; ++i) {
2322 if ((
Value & Mask) != Elem)
2328 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2329 return isNEONReplicate(8, NumBytes,
false);
2332 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2333 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2334 "Invalid source width");
2335 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2336 "Invalid destination width");
2337 assert(FromW < ToW &&
"ToW is not less than FromW");
2340 template<
unsigned FromW,
unsigned ToW>
2341 bool isNEONmovReplicate()
const {
2342 checkNeonReplicateArgs(FromW, ToW);
2343 if (ToW == 64 && isNEONi64splat())
2345 return isNEONReplicate(FromW, ToW / FromW,
false);
2348 template<
unsigned FromW,
unsigned ToW>
2349 bool isNEONinvReplicate()
const {
2350 checkNeonReplicateArgs(FromW, ToW);
2351 return isNEONReplicate(FromW, ToW / FromW,
true);
2354 bool isNEONi32vmov()
const {
2355 if (isNEONByteReplicate(4))
2363 return isValidNEONi32vmovImm(
CE->getValue());
2366 bool isNEONi32vmovNeg()
const {
2367 if (!
isImm())
return false;
2370 if (!CE)
return false;
2371 return isValidNEONi32vmovImm(~
CE->getValue());
2374 bool isNEONi64splat()
const {
2375 if (!
isImm())
return false;
2378 if (!CE)
return false;
2381 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2382 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2386 template<
int64_t Angle,
int64_t Remainder>
2387 bool isComplexRotation()
const {
2388 if (!
isImm())
return false;
2391 if (!CE)
return false;
2394 return (
Value % Angle == Remainder &&
Value <= 270);
2397 bool isMVELongShift()
const {
2398 if (!
isImm())
return false;
2401 if (!CE)
return false;
2406 bool isMveSaturateOp()
const {
2407 if (!
isImm())
return false;
2409 if (!CE)
return false;
2414 bool isITCondCodeNoAL()
const {
2415 if (!isITCondCode())
return false;
2420 bool isITCondCodeRestrictedI()
const {
2421 if (!isITCondCode())
2427 bool isITCondCodeRestrictedS()
const {
2428 if (!isITCondCode())
2435 bool isITCondCodeRestrictedU()
const {
2436 if (!isITCondCode())
2442 bool isITCondCodeRestrictedFP()
const {
2443 if (!isITCondCode())
2454 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2460 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2461 assert(
N == 1 &&
"Invalid number of operands!");
2462 addExpr(Inst, getImm());
2465 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2466 assert(
N == 1 &&
"Invalid number of operands!");
2467 addExpr(Inst, getImm());
2470 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2471 assert(
N == 2 &&
"Invalid number of operands!");
2477 void addVPTPredNOperands(
MCInst &Inst,
unsigned N)
const {
2478 assert(
N == 3 &&
"Invalid number of operands!");
2480 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? 0: ARM::P0;
2485 void addVPTPredROperands(
MCInst &Inst,
unsigned N)
const {
2486 assert(
N == 4 &&
"Invalid number of operands!");
2487 addVPTPredNOperands(Inst,
N-1);
2497 "Inactive register in vpred_r is not tied to an output!");
2503 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
2504 assert(
N == 1 &&
"Invalid number of operands!");
2508 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
2509 assert(
N == 1 &&
"Invalid number of operands!");
2513 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
2514 assert(
N == 1 &&
"Invalid number of operands!");
2518 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
2519 assert(
N == 1 &&
"Invalid number of operands!");
2523 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2524 assert(
N == 1 &&
"Invalid number of operands!");
2528 void addITCondCodeInvOperands(
MCInst &Inst,
unsigned N)
const {
2529 assert(
N == 1 &&
"Invalid number of operands!");
2533 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
2534 assert(
N == 1 &&
"Invalid number of operands!");
2538 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
2539 assert(
N == 1 &&
"Invalid number of operands!");
2543 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
2544 assert(
N == 3 &&
"Invalid number of operands!");
2545 assert(isRegShiftedReg() &&
2546 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2553 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
2554 assert(
N == 2 &&
"Invalid number of operands!");
2555 assert(isRegShiftedImm() &&
2556 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2559 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2564 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
2565 assert(
N == 1 &&
"Invalid number of operands!");
2570 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
2571 assert(
N == 1 &&
"Invalid number of operands!");
2573 for (
unsigned Reg : RegList)
2577 void addRegListWithAPSROperands(
MCInst &Inst,
unsigned N)
const {
2578 assert(
N == 1 &&
"Invalid number of operands!");
2580 for (
unsigned Reg : RegList)
2584 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2585 addRegListOperands(Inst,
N);
2588 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2589 addRegListOperands(Inst,
N);
2592 void addFPSRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2593 addRegListOperands(Inst,
N);
2596 void addFPDRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2597 addRegListOperands(Inst,
N);
2600 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2601 assert(
N == 1 &&
"Invalid number of operands!");
2606 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2607 assert(
N == 1 &&
"Invalid number of operands!");
2611 return addImmOperands(Inst,
N);
2616 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2617 assert(
N == 1 &&
"Invalid number of operands!");
2623 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2624 assert(
N == 1 &&
"Invalid number of operands!");
2630 void addThumbModImmNeg8_255Operands(
MCInst &Inst,
unsigned N)
const {
2631 assert(
N == 1 &&
"Invalid number of operands!");
2637 void addThumbModImmNeg1_7Operands(
MCInst &Inst,
unsigned N)
const {
2638 assert(
N == 1 &&
"Invalid number of operands!");
2644 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2645 assert(
N == 1 &&
"Invalid number of operands!");
2651 (32 - (lsb + width)));
2655 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2656 assert(
N == 1 &&
"Invalid number of operands!");
2657 addExpr(Inst, getImm());
2660 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2661 assert(
N == 1 &&
"Invalid number of operands!");
2666 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2667 assert(
N == 1 &&
"Invalid number of operands!");
2672 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2673 assert(
N == 1 &&
"Invalid number of operands!");
2679 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2680 assert(
N == 1 &&
"Invalid number of operands!");
2687 void addImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
2688 assert(
N == 1 &&
"Invalid number of operands!");
2695 void addImm7Shift0Operands(
MCInst &Inst,
unsigned N)
const {
2696 assert(
N == 1 &&
"Invalid number of operands!");
2701 void addImm7Shift1Operands(
MCInst &Inst,
unsigned N)
const {
2702 assert(
N == 1 &&
"Invalid number of operands!");
2707 void addImm7Shift2Operands(
MCInst &Inst,
unsigned N)
const {
2708 assert(
N == 1 &&
"Invalid number of operands!");
2713 void addImm7Operands(
MCInst &Inst,
unsigned N)
const {
2714 assert(
N == 1 &&
"Invalid number of operands!");
2719 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2720 assert(
N == 1 &&
"Invalid number of operands!");
2727 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2728 assert(
N == 1 &&
"Invalid number of operands!");
2735 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2736 assert(
N == 1 &&
"Invalid number of operands!");
2743 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2744 assert(
N == 1 &&
"Invalid number of operands!");
2751 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2752 assert(
N == 1 &&
"Invalid number of operands!");
2759 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2760 assert(
N == 1 &&
"Invalid number of operands!");
2764 unsigned Imm =
CE->getValue();
2768 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2769 assert(
N == 1 &&
"Invalid number of operands!");
2773 int Val =
CE->getValue();
2777 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2778 assert(
N == 1 &&
"Invalid number of operands!");
2785 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2786 assert(
N == 1 &&
"Invalid number of operands!");
2793 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2794 assert(
N == 1 &&
"Invalid number of operands!");
2801 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2802 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2810 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2811 assert(
N == 1 &&
"Invalid number of operands!");
2823 assert(isGPRMem() &&
"Unknown value type!");
2824 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2825 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2831 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2832 assert(
N == 1 &&
"Invalid number of operands!");
2836 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2837 assert(
N == 1 &&
"Invalid number of operands!");
2841 void addTraceSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2842 assert(
N == 1 &&
"Invalid number of operands!");
2846 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2847 assert(
N == 1 &&
"Invalid number of operands!");
2851 void addMemNoOffsetT2Operands(
MCInst &Inst,
unsigned N)
const {
2852 assert(
N == 1 &&
"Invalid number of operands!");
2856 void addMemNoOffsetT2NoSpOperands(
MCInst &Inst,
unsigned N)
const {
2857 assert(
N == 1 &&
"Invalid number of operands!");
2861 void addMemNoOffsetTOperands(
MCInst &Inst,
unsigned N)
const {
2862 assert(
N == 1 &&
"Invalid number of operands!");
2866 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2867 assert(
N == 1 &&
"Invalid number of operands!");
2868 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2874 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2875 assert(
N == 1 &&
"Invalid number of operands!");
2880 if (!isa<MCConstantExpr>(getImm())) {
2886 int Val =
CE->getValue();
2890 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2891 assert(
N == 2 &&
"Invalid number of operands!");
2896 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2897 addAlignedMemoryOperands(Inst,
N);
2900 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2901 addAlignedMemoryOperands(Inst,
N);
2904 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2905 addAlignedMemoryOperands(Inst,
N);
2908 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2909 addAlignedMemoryOperands(Inst,
N);
2912 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2913 addAlignedMemoryOperands(Inst,
N);
2916 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2917 addAlignedMemoryOperands(Inst,
N);
2920 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2921 addAlignedMemoryOperands(Inst,
N);
2924 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2925 addAlignedMemoryOperands(Inst,
N);
2928 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2929 addAlignedMemoryOperands(Inst,
N);
2932 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2933 addAlignedMemoryOperands(Inst,
N);
2936 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2937 addAlignedMemoryOperands(Inst,
N);
2940 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
2941 assert(
N == 3 &&
"Invalid number of operands!");
2944 if (!
Memory.OffsetRegNum) {
2947 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
2948 int32_t Val =
CE->getValue();
2951 if (Val == std::numeric_limits<int32_t>::min())
2969 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
2970 assert(
N == 2 &&
"Invalid number of operands!");
2972 assert(CE &&
"non-constant AM2OffsetImm operand!");
2973 int32_t Val =
CE->getValue();
2976 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2977 if (Val < 0) Val = -Val;
2983 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
2984 assert(
N == 3 &&
"Invalid number of operands!");
2997 if (!
Memory.OffsetRegNum) {
3000 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3001 int32_t Val =
CE->getValue();
3004 if (Val == std::numeric_limits<int32_t>::min())
3021 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3022 assert(
N == 2 &&
"Invalid number of operands!");
3023 if (Kind == k_PostIndexRegister) {
3033 int32_t Val =
CE->getValue();
3036 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3037 if (Val < 0) Val = -Val;
3043 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
3044 assert(
N == 2 &&
"Invalid number of operands!");
3057 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3059 int32_t Val =
CE->getValue() / 4;
3062 if (Val == std::numeric_limits<int32_t>::min())
3072 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
3073 assert(
N == 2 &&
"Invalid number of operands!");
3087 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3088 int32_t Val =
CE->getValue() / 2;
3091 if (Val == std::numeric_limits<int32_t>::min())
3101 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3102 assert(
N == 2 &&
"Invalid number of operands!");
3113 addExpr(Inst,
Memory.OffsetImm);
3116 void addMemImm7s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3117 assert(
N == 2 &&
"Invalid number of operands!");
3128 addExpr(Inst,
Memory.OffsetImm);
3131 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3132 assert(
N == 2 &&
"Invalid number of operands!");
3136 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3143 void addMemImmOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3144 assert(
N == 2 &&
"Invalid number of operands!");
3146 addExpr(Inst,
Memory.OffsetImm);
3149 void addMemRegRQOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3150 assert(
N == 2 &&
"Invalid number of operands!");
3155 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3156 assert(
N == 2 &&
"Invalid number of operands!");
3159 addExpr(Inst, getImm());
3166 addExpr(Inst,
Memory.OffsetImm);
3169 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3170 assert(
N == 2 &&
"Invalid number of operands!");
3173 addExpr(Inst, getImm());
3180 addExpr(Inst,
Memory.OffsetImm);
3183 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
3184 assert(
N == 1 &&
"Invalid number of operands!");
3187 addExpr(Inst, getConstantPoolImm());
3190 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
3191 assert(
N == 2 &&
"Invalid number of operands!");
3196 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
3197 assert(
N == 2 &&
"Invalid number of operands!");
3202 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3203 assert(
N == 3 &&
"Invalid number of operands!");
3212 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3213 assert(
N == 3 &&
"Invalid number of operands!");
3219 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
3220 assert(
N == 2 &&
"Invalid number of operands!");
3225 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
3226 assert(
N == 2 &&
"Invalid number of operands!");
3230 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3237 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
3238 assert(
N == 2 &&
"Invalid number of operands!");
3242 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3248 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
3249 assert(
N == 2 &&
"Invalid number of operands!");
3251 addExpr(Inst,
Memory.OffsetImm);
3254 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
3255 assert(
N == 2 &&
"Invalid number of operands!");
3259 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3266 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
3267 assert(
N == 1 &&
"Invalid number of operands!");
3269 assert(CE &&
"non-constant post-idx-imm8 operand!");
3270 int Imm =
CE->getValue();
3271 bool isAdd =
Imm >= 0;
3272 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3277 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
3278 assert(
N == 1 &&
"Invalid number of operands!");
3280 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3281 int Imm =
CE->getValue();
3282 bool isAdd =
Imm >= 0;
3283 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3289 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
3290 assert(
N == 2 &&
"Invalid number of operands!");
3295 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
3296 assert(
N == 2 &&
"Invalid number of operands!");
3302 PostIdxReg.ShiftTy);
3306 void addPowerTwoOperands(
MCInst &Inst,
unsigned N)
const {
3307 assert(
N == 1 &&
"Invalid number of operands!");
3312 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
3313 assert(
N == 1 &&
"Invalid number of operands!");
3317 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
3318 assert(
N == 1 &&
"Invalid number of operands!");
3322 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
3323 assert(
N == 1 &&
"Invalid number of operands!");
3327 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
3328 assert(
N == 1 &&
"Invalid number of operands!");
3332 void addMVEVecListOperands(
MCInst &Inst,
unsigned N)
const {
3333 assert(
N == 1 &&
"Invalid number of operands!");
3349 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3351 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3352 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID];
3355 for (
I = 0;
I <
E;
I++)
3358 assert(
I <
E &&
"Invalid vector list start register!");
3363 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
3364 assert(
N == 2 &&
"Invalid number of operands!");
3369 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
3370 assert(
N == 1 &&
"Invalid number of operands!");
3374 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
3375 assert(
N == 1 &&
"Invalid number of operands!");
3379 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
3380 assert(
N == 1 &&
"Invalid number of operands!");
3384 void addVectorIndex64Operands(
MCInst &Inst,
unsigned N)
const {
3385 assert(
N == 1 &&
"Invalid number of operands!");
3389 void addMVEVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3390 assert(
N == 1 &&
"Invalid number of operands!");
3394 void addMVEPairVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3395 assert(
N == 1 &&
"Invalid number of operands!");
3399 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
3400 assert(
N == 1 &&
"Invalid number of operands!");
3407 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
3408 assert(
N == 1 &&
"Invalid number of operands!");
3411 unsigned Value =
CE->getValue();
3416 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3417 assert(
N == 1 &&
"Invalid number of operands!");
3420 unsigned Value =
CE->getValue();
3425 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
3426 assert(
N == 1 &&
"Invalid number of operands!");
3429 unsigned Value =
CE->getValue();
3434 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3435 assert(
N == 1 &&
"Invalid number of operands!");
3438 unsigned Value =
CE->getValue();
3443 void addNEONi8ReplicateOperands(
MCInst &Inst,
bool Inv)
const {
3448 "All instructions that wants to replicate non-zero byte "
3449 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3450 unsigned Value =
CE->getValue();
3453 unsigned B =
Value & 0xff;
3458 void addNEONinvi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3459 assert(
N == 1 &&
"Invalid number of operands!");
3460 addNEONi8ReplicateOperands(Inst,
true);
3463 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3466 else if (
Value > 0xffff &&
Value <= 0xffffff)
3468 else if (
Value > 0xffffff)
3473 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
3474 assert(
N == 1 &&
"Invalid number of operands!");
3477 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3481 void addNEONvmovi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3482 assert(
N == 1 &&
"Invalid number of operands!");
3483 addNEONi8ReplicateOperands(Inst,
false);
3486 void addNEONvmovi16ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3487 assert(
N == 1 &&
"Invalid number of operands!");
3493 "All instructions that want to replicate non-zero half-word "
3494 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3496 unsigned Elem =
Value & 0xffff;
3498 Elem = (Elem >> 8) | 0x200;
3502 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
3503 assert(
N == 1 &&
"Invalid number of operands!");
3506 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3510 void addNEONvmovi32ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3511 assert(
N == 1 &&
"Invalid number of operands!");
3517 "All instructions that want to replicate non-zero word "
3518 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3520 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3524 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
3525 assert(
N == 1 &&
"Invalid number of operands!");
3530 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3536 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
3537 assert(
N == 1 &&
"Invalid number of operands!");
3542 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
3543 assert(
N == 1 &&
"Invalid number of operands!");
3548 void addMveSaturateOperands(
MCInst &Inst,
unsigned N)
const {
3549 assert(
N == 1 &&
"Invalid number of operands!");
3551 unsigned Imm =
CE->getValue();
3552 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3558 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S) {
3559 auto Op = std::make_unique<ARMOperand>(k_ITCondMask);
3568 auto Op = std::make_unique<ARMOperand>(k_CondCode);
3577 auto Op = std::make_unique<ARMOperand>(k_VPTPred);
3584 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S) {
3585 auto Op = std::make_unique<ARMOperand>(k_CoprocNum);
3586 Op->Cop.Val = CopVal;
3592 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S) {
3593 auto Op = std::make_unique<ARMOperand>(k_CoprocReg);
3594 Op->Cop.Val = CopVal;
3600 static std::unique_ptr<ARMOperand> CreateCoprocOption(
unsigned Val,
SMLoc S,
3602 auto Op = std::make_unique<ARMOperand>(k_CoprocOption);
3609 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S) {
3610 auto Op = std::make_unique<ARMOperand>(k_CCOut);
3611 Op->Reg.RegNum = RegNum;
3617 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S) {
3618 auto Op = std::make_unique<ARMOperand>(k_Token);
3619 Op->Tok.Data = Str.data();
3620 Op->Tok.Length = Str.size();
3626 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
3628 auto Op = std::make_unique<ARMOperand>(k_Register);
3629 Op->Reg.RegNum = RegNum;
3635 static std::unique_ptr<ARMOperand>
3637 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
3639 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister);
3640 Op->RegShiftedReg.ShiftTy = ShTy;
3641 Op->RegShiftedReg.SrcReg = SrcReg;
3642 Op->RegShiftedReg.ShiftReg = ShiftReg;
3643 Op->RegShiftedReg.ShiftImm = ShiftImm;
3649 static std::unique_ptr<ARMOperand>
3652 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate);
3653 Op->RegShiftedImm.ShiftTy = ShTy;
3654 Op->RegShiftedImm.SrcReg = SrcReg;
3655 Op->RegShiftedImm.ShiftImm = ShiftImm;
3661 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3663 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate);
3664 Op->ShifterImm.isASR = isASR;
3665 Op->ShifterImm.Imm =
Imm;
3671 static std::unique_ptr<ARMOperand> CreateRotImm(
unsigned Imm,
SMLoc S,
3673 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate);
3674 Op->RotImm.Imm =
Imm;
3680 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3682 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate);
3684 Op->ModImm.Rot = Rot;
3690 static std::unique_ptr<ARMOperand>
3692 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate);
3699 static std::unique_ptr<ARMOperand>
3700 CreateBitfield(
unsigned LSB,
unsigned Width,
SMLoc S,
SMLoc E) {
3701 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor);
3702 Op->Bitfield.LSB = LSB;
3709 static std::unique_ptr<ARMOperand>
3712 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3713 KindTy
Kind = k_RegisterList;
3715 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
3716 Regs.front().second)) {
3717 if (Regs.back().second == ARM::VPR)
3718 Kind = k_FPDRegisterListWithVPR;
3720 Kind = k_DPRRegisterList;
3721 }
else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
3722 Regs.front().second)) {
3723 if (Regs.back().second == ARM::VPR)
3724 Kind = k_FPSRegisterListWithVPR;
3726 Kind = k_SPRRegisterList;
3729 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3730 Kind = k_RegisterListWithAPSR;
3734 auto Op = std::make_unique<ARMOperand>(Kind);
3735 for (
const auto &
P : Regs)
3736 Op->Registers.push_back(
P.second);
3738 Op->StartLoc = StartLoc;
3739 Op->EndLoc = EndLoc;
3743 static std::unique_ptr<ARMOperand> CreateVectorList(
unsigned RegNum,
3745 bool isDoubleSpaced,
3747 auto Op = std::make_unique<ARMOperand>(k_VectorList);
3748 Op->VectorList.RegNum = RegNum;
3749 Op->VectorList.Count = Count;
3750 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3756 static std::unique_ptr<ARMOperand>
3757 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
3759 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes);
3760 Op->VectorList.RegNum = RegNum;
3761 Op->VectorList.Count = Count;
3762 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3768 static std::unique_ptr<ARMOperand>
3769 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
3771 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed);
3772 Op->VectorList.RegNum = RegNum;
3773 Op->VectorList.Count = Count;
3774 Op->VectorList.LaneIndex =
Index;
3775 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3781 static std::unique_ptr<ARMOperand>
3783 auto Op = std::make_unique<ARMOperand>(k_VectorIndex);
3784 Op->VectorIndex.Val =
Idx;
3790 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
3792 auto Op = std::make_unique<ARMOperand>(k_Immediate);
3799 static std::unique_ptr<ARMOperand>
3800 CreateMem(
unsigned BaseRegNum,
const MCExpr *OffsetImm,
unsigned OffsetRegNum,
3803 auto Op = std::make_unique<ARMOperand>(k_Memory);
3804 Op->Memory.BaseRegNum = BaseRegNum;
3805 Op->Memory.OffsetImm = OffsetImm;
3806 Op->Memory.OffsetRegNum = OffsetRegNum;
3807 Op->Memory.ShiftType = ShiftType;
3808 Op->Memory.ShiftImm = ShiftImm;
3809 Op->Memory.Alignment = Alignment;
3810 Op->Memory.isNegative = isNegative;
3813 Op->AlignmentLoc = AlignmentLoc;
3817 static std::unique_ptr<ARMOperand>
3820 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister);
3821 Op->PostIdxReg.RegNum = RegNum;
3822 Op->PostIdxReg.isAdd = isAdd;
3823 Op->PostIdxReg.ShiftTy = ShiftTy;
3824 Op->PostIdxReg.ShiftImm = ShiftImm;
3830 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt,
3832 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt);
3833 Op->MBOpt.Val = Opt;
3839 static std::unique_ptr<ARMOperand>
3841 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3842 Op->ISBOpt.Val = Opt;
3848 static std::unique_ptr<ARMOperand>
3850 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3851 Op->TSBOpt.Val = Opt;
3857 static std::unique_ptr<ARMOperand> CreateProcIFlags(
ARM_PROC::IFlags IFlags,
3859 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags);
3866 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S) {
3867 auto Op = std::make_unique<ARMOperand>(k_MSRMask);
3868 Op->MMask.Val = MMask;
3874 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S) {
3875 auto Op = std::make_unique<ARMOperand>(k_BankedReg);
3876 Op->BankedReg.Val =
Reg;
3903 case k_ITCondMask: {
3904 static const char *
const MaskStr[] = {
3905 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
3906 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
3907 "(t)",
"(tett)",
"(tet)",
"(tete)",
3908 "(te)",
"(teet)",
"(tee)",
"(teee)",
3910 assert((ITMask.Mask & 0xf) == ITMask.Mask);
3911 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
3915 OS <<
"<coprocessor number: " << getCoproc() <<
">";
3918 OS <<
"<coprocessor register: " << getCoproc() <<
">";
3920 case k_CoprocOption:
3921 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
3924 OS <<
"<mask: " << getMSRMask() <<
">";
3927 OS <<
"<banked reg: " << getBankedReg() <<
">";
3932 case k_MemBarrierOpt:
3933 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
3935 case k_InstSyncBarrierOpt:
3936 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
3938 case k_TraceSyncBarrierOpt:
3939 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
3946 OS <<
" offset-imm:" << *
Memory.OffsetImm;
3948 OS <<
" offset-reg:" << (
Memory.isNegative ?
"-" :
"")
3952 OS <<
" shift-imm:" <<
Memory.ShiftImm;
3955 OS <<
" alignment:" <<
Memory.Alignment;
3958 case k_PostIndexRegister:
3959 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
3960 <<
RegName(PostIdxReg.RegNum);
3963 << PostIdxReg.ShiftImm;
3966 case k_ProcIFlags: {
3967 OS <<
"<ARM_PROC::";
3968 unsigned IFlags = getProcIFlags();
3969 for (
int i=2; i >= 0; --i)
3970 if (IFlags & (1 << i))
3978 case k_ShifterImmediate:
3979 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
3980 <<
" #" << ShifterImm.Imm <<
">";
3982 case k_ShiftedRegister:
3983 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
3985 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
3987 case k_ShiftedImmediate:
3988 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
3990 << RegShiftedImm.ShiftImm <<
">";
3992 case k_RotateImmediate:
3993 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
3995 case k_ModifiedImmediate:
3996 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
3997 << ModImm.Rot <<
")>";
3999 case k_ConstantPoolImmediate:
4000 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
4002 case k_BitfieldDescriptor:
4003 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4004 <<
", width: " <<
Bitfield.Width <<
">";
4006 case k_RegisterList:
4007 case k_RegisterListWithAPSR:
4008 case k_DPRRegisterList:
4009 case k_SPRRegisterList:
4010 case k_FPSRegisterListWithVPR:
4011 case k_FPDRegisterListWithVPR: {
4012 OS <<
"<register_list ";
4018 if (++
I <
E)
OS <<
", ";
4025 OS <<
"<vector_list " << VectorList.Count <<
" * "
4026 <<
RegName(VectorList.RegNum) <<
">";
4028 case k_VectorListAllLanes:
4029 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4030 <<
RegName(VectorList.RegNum) <<
">";
4032 case k_VectorListIndexed:
4033 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4034 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4037 OS <<
"'" << getToken() <<
"'";
4040 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4054 const AsmToken &Tok = getParser().getTok();
4057 Reg = tryParseRegister();
4064 if (parseRegister(
Reg, StartLoc, EndLoc))
4072int ARMAsmParser::tryParseRegister() {
4081 .
Case(
"r13", ARM::SP)
4082 .
Case(
"r14", ARM::LR)
4083 .
Case(
"r15", ARM::PC)
4084 .
Case(
"ip", ARM::R12)
4086 .
Case(
"a1", ARM::R0)
4087 .
Case(
"a2", ARM::R1)
4088 .
Case(
"a3", ARM::R2)
4089 .
Case(
"a4", ARM::R3)
4090 .
Case(
"v1", ARM::R4)
4091 .
Case(
"v2", ARM::R5)
4092 .
Case(
"v3", ARM::R6)
4093 .
Case(
"v4", ARM::R7)
4094 .
Case(
"v5", ARM::R8)
4095 .
Case(
"v6", ARM::R9)
4096 .
Case(
"v7", ARM::R10)
4097 .
Case(
"v8", ARM::R11)
4098 .
Case(
"sb", ARM::R9)
4099 .
Case(
"sl", ARM::R10)
4100 .
Case(
"fp", ARM::R11)
4109 if (Entry == RegisterReqs.
end())
4112 return Entry->getValue();
4116 if (!hasD32() && RegNum >=
ARM::D16 && RegNum <= ARM::D31)
4154 std::unique_ptr<ARMOperand> PrevOp(
4155 (ARMOperand *)
Operands.pop_back_val().release());
4156 if (!PrevOp->isReg())
4157 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4158 int SrcReg = PrevOp->getReg();
4174 const MCExpr *ShiftExpr =
nullptr;
4175 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4176 Error(ImmLoc,
"invalid immediate shift value");
4182 Error(ImmLoc,
"invalid immediate shift value");
4188 Imm =
CE->getValue();
4192 Error(ImmLoc,
"immediate shift value out of range");
4202 ShiftReg = tryParseRegister();
4203 if (ShiftReg == -1) {
4204 Error(L,
"expected immediate or register in shift operand");
4209 "expected immediate or register in shift operand");
4215 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
4219 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4235 int RegNo = tryParseRegister();
4239 Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
4257 if (getParser().parseExpression(ImmVal))
4261 return TokError(
"immediate value expected for vector index");
4289 if (
Name.size() < 2 ||
Name[0] != CoprocOp)
4293 switch (
Name.size()) {
4316 case '0':
return 10;
4317 case '1':
return 11;
4318 case '2':
return 12;
4319 case '3':
return 13;
4320 case '4':
return 14;
4321 case '5':
return 15;
4360 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
4379 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S));
4396 if (getParser().parseExpression(Expr))
4397 return Error(Loc,
"illegal expression");
4399 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4401 "coprocessor option must be an immediate in range [0, 255]");
4402 int Val =
CE->getValue();
4410 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E));
4421 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4425 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4426 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4427 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4428 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4429 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4430 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4431 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4432 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4440 unsigned Enc,
unsigned Reg) {
4441 Regs.emplace_back(Enc,
Reg);
4442 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4443 if (J->first == Enc) {
4444 Regs.erase(J.base());
4459 return TokError(
"Token is not a Left Curly Brace");
4466 int Reg = tryParseRegister();
4468 return Error(RegLoc,
"register expected");
4469 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4470 return Error(RegLoc,
"pseudo-register not allowed");
4477 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4478 Reg = getDRegFromQReg(
Reg);
4479 EReg =
MRI->getEncodingValue(
Reg);
4484 if (
Reg == ARM::RA_AUTH_CODE ||
4485 ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4486 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4487 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg))
4488 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4489 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
Reg))
4490 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4491 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4492 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4494 return Error(RegLoc,
"invalid register in register list");
4497 EReg =
MRI->getEncodingValue(
Reg);
4506 if (
Reg == ARM::RA_AUTH_CODE)
4507 return Error(RegLoc,
"pseudo-register not allowed");
4510 int EndReg = tryParseRegister();
4512 return Error(AfterMinusLoc,
"register expected");
4513 if (EndReg == ARM::RA_AUTH_CODE)
4514 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4516 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4517 EndReg = getDRegFromQReg(EndReg) + 1;
4524 return Error(AfterMinusLoc,
"invalid register in register list");
4526 if (
MRI->getEncodingValue(
Reg) >
MRI->getEncodingValue(EndReg))
4527 return Error(AfterMinusLoc,
"bad range in register list");
4530 while (
Reg != EndReg) {
4532 EReg =
MRI->getEncodingValue(
Reg);
4536 ") in register list");
4545 Reg = tryParseRegister();
4547 return Error(RegLoc,
"register expected");
4548 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4549 return Error(RegLoc,
"pseudo-register not allowed");
4551 bool isQReg =
false;
4552 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4553 Reg = getDRegFromQReg(
Reg);
4557 RC->
getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4558 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
Reg)) {
4561 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4563 if (
Reg == ARM::VPR &&
4564 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4565 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4566 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4567 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4568 EReg =
MRI->getEncodingValue(
Reg);
4571 ") in register list");
4576 if ((
Reg == ARM::RA_AUTH_CODE &&
4577 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
4579 return Error(RegLoc,
"invalid register in register list");
4585 MRI->getEncodingValue(
Reg) <
MRI->getEncodingValue(OldReg)) {
4586 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4587 Warning(RegLoc,
"register list not in ascending order");
4588 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4589 return Error(RegLoc,
"register list not in ascending order");
4592 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4593 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4595 return Error(RegLoc,
"non-contiguous register range");
4596 EReg =
MRI->getEncodingValue(
Reg);
4599 ") in register list");
4602 EReg =
MRI->getEncodingValue(++
Reg);
4625ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4633 LaneKind = AllLanes;
4646 if (getParser().parseExpression(LaneIndex))
4647 return Error(Loc,
"illegal expression");
4650 return Error(Loc,
"lane index must be empty or an integer");
4655 int64_t Val =
CE->getValue();
4658 if (Val < 0 || Val > 7)
4661 LaneKind = IndexedLane;
4671 VectorLaneTy LaneKind;
4679 int Reg = tryParseRegister();
4682 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg)) {
4683 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4688 Operands.push_back(ARMOperand::CreateVectorList(
Reg, 1,
false, S,
E));
4691 Operands.push_back(ARMOperand::CreateVectorListAllLanes(
Reg, 1,
false,
4695 Operands.push_back(ARMOperand::CreateVectorListIndexed(
Reg, 1,