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")));
97static cl::opt<bool> AddBuildAttributes(
"arm-add-build-attributes",
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"
639 return parsePKHImm(O,
"lsl", 0, 31);
642 return parsePKHImm(O,
"asr", 1, 32);
666 bool isITBlockTerminator(
MCInst &Inst)
const;
669 bool Load,
bool ARMMode,
bool Writeback);
672 enum ARMMatchResultTy {
674 Match_RequiresNotITBlock,
676 Match_RequiresThumb2,
678 Match_RequiresFlagSetting,
679#define GET_OPERAND_DIAGNOSTIC_TYPES
680#include "ARMGenAsmMatcher.inc"
696 if (AddBuildAttributes)
697 getTargetStreamer().emitTargetAttributes(STI);
700 ITState.CurPosition = ~0
U;
702 VPTState.CurPosition = ~0
U;
704 NextSymbolIsThumb =
false;
709 SMLoc &EndLoc)
override;
711 SMLoc &EndLoc)
override;
717 unsigned Kind)
override;
723 bool MatchingInlineAsm)
override;
726 bool MatchingInlineAsm,
bool &EmitInITBlock,
729 struct NearMissMessage {
734 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
760 k_InstSyncBarrierOpt,
761 k_TraceSyncBarrierOpt,
770 k_RegisterListWithAPSR,
773 k_FPSRegisterListWithVPR,
774 k_FPDRegisterListWithVPR,
776 k_VectorListAllLanes,
783 k_ConstantPoolImmediate,
784 k_BitfieldDescriptor,
788 SMLoc StartLoc, EndLoc, AlignmentLoc;
803 struct CoprocOptionOp {
845 struct VectorListOp {
852 struct VectorIndexOp {
866 unsigned OffsetRegNum;
871 unsigned isNegative : 1;
874 struct PostIdxRegOp {
881 struct ShifterImmOp {
886 struct RegShiftedRegOp {
893 struct RegShiftedImmOp {
917 struct CoprocOptionOp CoprocOption;
918 struct MBOptOp MBOpt;
919 struct ISBOptOp ISBOpt;
920 struct TSBOptOp TSBOpt;
921 struct ITMaskOp ITMask;
923 struct MMaskOp MMask;
924 struct BankedRegOp BankedReg;
927 struct VectorListOp VectorList;
928 struct VectorIndexOp VectorIndex;
931 struct PostIdxRegOp PostIdxReg;
932 struct ShifterImmOp ShifterImm;
933 struct RegShiftedRegOp RegShiftedReg;
934 struct RegShiftedImmOp RegShiftedImm;
935 struct RotImmOp RotImm;
936 struct ModImmOp ModImm;
941 ARMOperand(KindTy K) :
Kind(
K) {}
954 SMLoc getAlignmentLoc()
const {
955 assert(Kind == k_Memory &&
"Invalid access!");
960 assert(Kind == k_CondCode &&
"Invalid access!");
965 assert(isVPTPred() &&
"Invalid access!");
969 unsigned getCoproc()
const {
970 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
975 assert(Kind == k_Token &&
"Invalid access!");
979 unsigned getReg()
const override {
980 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
985 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
986 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
987 Kind == k_FPSRegisterListWithVPR ||
988 Kind == k_FPDRegisterListWithVPR) &&
993 const MCExpr *getImm()
const {
998 const MCExpr *getConstantPoolImm()
const {
999 assert(isConstantPoolImm() &&
"Invalid access!");
1003 unsigned getVectorIndex()
const {
1004 assert(Kind == k_VectorIndex &&
"Invalid access!");
1005 return VectorIndex.Val;
1009 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1014 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1019 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1024 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1028 unsigned getMSRMask()
const {
1029 assert(Kind == k_MSRMask &&
"Invalid access!");
1033 unsigned getBankedReg()
const {
1034 assert(Kind == k_BankedReg &&
"Invalid access!");
1035 return BankedReg.Val;
1038 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1039 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1040 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1041 bool isCondCode()
const {
return Kind == k_CondCode; }
1042 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1043 bool isCCOut()
const {
return Kind == k_CCOut; }
1044 bool isITMask()
const {
return Kind == k_ITCondMask; }
1045 bool isITCondCode()
const {
return Kind == k_CondCode; }
1046 bool isImm()
const override {
1047 return Kind == k_Immediate;
1050 bool isARMBranchTarget()
const {
1051 if (!
isImm())
return false;
1053 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1054 return CE->getValue() % 4 == 0;
1059 bool isThumbBranchTarget()
const {
1060 if (!
isImm())
return false;
1062 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1063 return CE->getValue() % 2 == 0;
1069 template<
unsigned w
idth,
unsigned scale>
1070 bool isUnsignedOffset()
const {
1071 if (!
isImm())
return false;
1072 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1074 int64_t Val =
CE->getValue();
1076 int64_t
Max =
Align * ((1LL << width) - 1);
1077 return ((Val %
Align) == 0) && (Val >= 0) && (Val <= Max);
1084 template<
unsigned w
idth,
unsigned scale>
1085 bool isSignedOffset()
const {
1086 if (!
isImm())
return false;
1087 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1089 int64_t Val =
CE->getValue();
1091 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1092 int64_t Min = -
Align * (1LL << (width-1));
1093 return ((Val %
Align) == 0) && (Val >= Min) && (Val <= Max);
1100 bool isLEOffset()
const {
1101 if (!
isImm())
return false;
1102 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1104 int64_t Val =
CE->getValue();
1105 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1114 bool isThumbMemPC()
const {
1117 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1119 if (!CE)
return false;
1120 Val =
CE->getValue();
1122 else if (isGPRMem()) {
1123 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
1124 if(
Memory.BaseRegNum != ARM::PC)
return false;
1125 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
1126 Val =
CE->getValue();
1131 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1134 bool isFPImm()
const {
1135 if (!
isImm())
return false;
1137 if (!CE)
return false;
1142 template<
int64_t N,
int64_t M>
1143 bool isImmediate()
const {
1144 if (!
isImm())
return false;
1146 if (!CE)
return false;
1147 int64_t
Value =
CE->getValue();
1151 template<
int64_t N,
int64_t M>
1152 bool isImmediateS4()
const {
1153 if (!
isImm())
return false;
1155 if (!CE)
return false;
1156 int64_t
Value =
CE->getValue();
1159 template<
int64_t N,
int64_t M>
1160 bool isImmediateS2()
const {
1161 if (!
isImm())
return false;
1163 if (!CE)
return false;
1164 int64_t
Value =
CE->getValue();
1167 bool isFBits16()
const {
1168 return isImmediate<0, 17>();
1170 bool isFBits32()
const {
1171 return isImmediate<1, 33>();
1173 bool isImm8s4()
const {
1174 return isImmediateS4<-1020, 1020>();
1176 bool isImm7s4()
const {
1177 return isImmediateS4<-508, 508>();
1179 bool isImm7Shift0()
const {
1180 return isImmediate<-127, 127>();
1182 bool isImm7Shift1()
const {
1183 return isImmediateS2<-255, 255>();
1185 bool isImm7Shift2()
const {
1186 return isImmediateS4<-511, 511>();
1188 bool isImm7()
const {
1189 return isImmediate<-127, 127>();
1191 bool isImm0_1020s4()
const {
1192 return isImmediateS4<0, 1020>();
1194 bool isImm0_508s4()
const {
1195 return isImmediateS4<0, 508>();
1197 bool isImm0_508s4Neg()
const {
1198 if (!
isImm())
return false;
1200 if (!CE)
return false;
1201 int64_t
Value = -
CE->getValue();
1206 bool isImm0_4095Neg()
const {
1207 if (!
isImm())
return false;
1209 if (!CE)
return false;
1214 if ((
CE->getValue() >> 32) > 0)
return false;
1219 bool isImm0_7()
const {
1220 return isImmediate<0, 7>();
1223 bool isImm1_16()
const {
1224 return isImmediate<1, 16>();
1227 bool isImm1_32()
const {
1228 return isImmediate<1, 32>();
1231 bool isImm8_255()
const {
1232 return isImmediate<8, 255>();
1235 bool isImm256_65535Expr()
const {
1236 if (!
isImm())
return false;
1240 if (!CE)
return true;
1241 int64_t
Value =
CE->getValue();
1245 bool isImm0_65535Expr()
const {
1246 if (!
isImm())
return false;
1250 if (!CE)
return true;
1251 int64_t
Value =
CE->getValue();
1255 bool isImm24bit()
const {
1256 return isImmediate<0, 0xffffff + 1>();
1259 bool isImmThumbSR()
const {
1260 return isImmediate<1, 33>();
1266 if ((
Value & mask) != 0 || (
Value >> shift) > 0xff)
1272 bool isExpImm()
const {
1273 if (!
isImm())
return false;
1275 if (!CE)
return false;
1277 return isExpImmValue<shift>(
CE->getValue());
1280 template<
int shift,
int size>
1281 bool isInvertedExpImm()
const {
1282 if (!
isImm())
return false;
1284 if (!CE)
return false;
1288 return isExpImmValue<shift>(InvertedValue);
1291 bool isPKHLSLImm()
const {
1292 return isImmediate<0, 32>();
1295 bool isPKHASRImm()
const {
1296 return isImmediate<0, 33>();
1299 bool isAdrLabel()
const {
1302 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1306 if (!
isImm())
return false;
1308 if (!CE)
return false;
1309 int64_t
Value =
CE->getValue();
1314 bool isT2SOImm()
const {
1317 if (
isImm() && !isa<MCConstantExpr>(getImm())) {
1320 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1324 if (!
isImm())
return false;
1326 if (!CE)
return false;
1327 int64_t
Value =
CE->getValue();
1331 bool isT2SOImmNot()
const {
1332 if (!
isImm())
return false;
1334 if (!CE)
return false;
1335 int64_t
Value =
CE->getValue();
1340 bool isT2SOImmNeg()
const {
1341 if (!
isImm())
return false;
1343 if (!CE)
return false;
1344 int64_t
Value =
CE->getValue();
1350 bool isSetEndImm()
const {
1351 if (!
isImm())
return false;
1353 if (!CE)
return false;
1354 int64_t
Value =
CE->getValue();
1358 bool isReg()
const override {
return Kind == k_Register; }
1359 bool isRegList()
const {
return Kind == k_RegisterList; }
1360 bool isRegListWithAPSR()
const {
1361 return Kind == k_RegisterListWithAPSR ||
Kind == k_RegisterList;
1363 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1364 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1365 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1366 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1367 bool isToken()
const override {
return Kind == k_Token; }
1368 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1369 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1370 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1371 bool isMem()
const override {
1372 return isGPRMem() || isMVEMem();
1374 bool isMVEMem()
const {
1375 if (Kind != k_Memory)
1378 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum) &&
1379 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
Memory.BaseRegNum))
1381 if (
Memory.OffsetRegNum &&
1382 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1387 bool isGPRMem()
const {
1388 if (Kind != k_Memory)
1391 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum))
1393 if (
Memory.OffsetRegNum &&
1394 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.OffsetRegNum))
1398 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1399 bool isRegShiftedReg()
const {
1400 return Kind == k_ShiftedRegister &&
1401 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1402 RegShiftedReg.SrcReg) &&
1403 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1404 RegShiftedReg.ShiftReg);
1406 bool isRegShiftedImm()
const {
1407 return Kind == k_ShiftedImmediate &&
1408 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1409 RegShiftedImm.SrcReg);
1411 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1413 template<
unsigned Min,
unsigned Max>
1414 bool isPowerTwoInRange()
const {
1415 if (!
isImm())
return false;
1417 if (!CE)
return false;
1418 int64_t
Value =
CE->getValue();
1422 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1424 bool isModImmNot()
const {
1425 if (!
isImm())
return false;
1427 if (!CE)
return false;
1428 int64_t
Value =
CE->getValue();
1432 bool isModImmNeg()
const {
1433 if (!
isImm())
return false;
1435 if (!CE)
return false;
1436 int64_t
Value =
CE->getValue();
1441 bool isThumbModImmNeg1_7()
const {
1442 if (!
isImm())
return false;
1444 if (!CE)
return false;
1445 int32_t
Value = -(int32_t)
CE->getValue();
1449 bool isThumbModImmNeg8_255()
const {
1450 if (!
isImm())
return false;
1452 if (!CE)
return false;
1453 int32_t
Value = -(int32_t)
CE->getValue();
1457 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1458 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1459 bool isPostIdxRegShifted()
const {
1460 return Kind == k_PostIndexRegister &&
1461 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1463 bool isPostIdxReg()
const {
1466 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1470 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1471 (alignOK ||
Memory.Alignment == Alignment);
1473 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1477 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1482 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1483 (alignOK ||
Memory.Alignment == Alignment);
1485 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1489 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].
contains(
1494 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1495 (alignOK ||
Memory.Alignment == Alignment);
1497 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1501 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].
contains(
1506 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1507 (alignOK ||
Memory.Alignment == Alignment);
1509 bool isMemPCRelImm12()
const {
1510 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1513 if (
Memory.BaseRegNum != ARM::PC)
1516 if (!
Memory.OffsetImm)
return true;
1517 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1518 int64_t Val =
CE->getValue();
1519 return (Val > -4096 && Val < 4096) ||
1520 (Val == std::numeric_limits<int32_t>::min());
1525 bool isAlignedMemory()
const {
1526 return isMemNoOffset(
true);
1529 bool isAlignedMemoryNone()
const {
1530 return isMemNoOffset(
false, 0);
1533 bool isDupAlignedMemoryNone()
const {
1534 return isMemNoOffset(
false, 0);
1537 bool isAlignedMemory16()
const {
1538 if (isMemNoOffset(
false, 2))
1540 return isMemNoOffset(
false, 0);
1543 bool isDupAlignedMemory16()
const {
1544 if (isMemNoOffset(
false, 2))
1546 return isMemNoOffset(
false, 0);
1549 bool isAlignedMemory32()
const {
1550 if (isMemNoOffset(
false, 4))
1552 return isMemNoOffset(
false, 0);
1555 bool isDupAlignedMemory32()
const {
1556 if (isMemNoOffset(
false, 4))
1558 return isMemNoOffset(
false, 0);
1561 bool isAlignedMemory64()
const {
1562 if (isMemNoOffset(
false, 8))
1564 return isMemNoOffset(
false, 0);
1567 bool isDupAlignedMemory64()
const {
1568 if (isMemNoOffset(
false, 8))
1570 return isMemNoOffset(
false, 0);
1573 bool isAlignedMemory64or128()
const {
1574 if (isMemNoOffset(
false, 8))
1576 if (isMemNoOffset(
false, 16))
1578 return isMemNoOffset(
false, 0);
1581 bool isDupAlignedMemory64or128()
const {
1582 if (isMemNoOffset(
false, 8))
1584 if (isMemNoOffset(
false, 16))
1586 return isMemNoOffset(
false, 0);
1589 bool isAlignedMemory64or128or256()
const {
1590 if (isMemNoOffset(
false, 8))
1592 if (isMemNoOffset(
false, 16))
1594 if (isMemNoOffset(
false, 32))
1596 return isMemNoOffset(
false, 0);
1599 bool isAddrMode2()
const {
1600 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1602 if (
Memory.OffsetRegNum)
return true;
1604 if (!
Memory.OffsetImm)
return true;
1605 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1606 int64_t Val =
CE->getValue();
1607 return Val > -4096 && Val < 4096;
1612 bool isAM2OffsetImm()
const {
1613 if (!
isImm())
return false;
1616 if (!CE)
return false;
1617 int64_t Val =
CE->getValue();
1618 return (Val == std::numeric_limits<int32_t>::min()) ||
1619 (Val > -4096 && Val < 4096);
1622 bool isAddrMode3()
const {
1626 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1628 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1632 if (
Memory.OffsetRegNum)
return true;
1634 if (!
Memory.OffsetImm)
return true;
1635 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1636 int64_t Val =
CE->getValue();
1639 return (Val > -256 && Val < 256) ||
1640 Val == std::numeric_limits<int32_t>::min();
1645 bool isAM3Offset()
const {
1652 if (!CE)
return false;
1653 int64_t Val =
CE->getValue();
1655 return (Val > -256 && Val < 256) ||
1656 Val == std::numeric_limits<int32_t>::min();
1659 bool isAddrMode5()
const {
1663 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1665 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1667 if (
Memory.OffsetRegNum)
return false;
1669 if (!
Memory.OffsetImm)
return true;
1670 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1671 int64_t Val =
CE->getValue();
1672 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1673 Val == std::numeric_limits<int32_t>::min();
1678 bool isAddrMode5FP16()
const {
1682 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1684 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1686 if (
Memory.OffsetRegNum)
return false;
1688 if (!
Memory.OffsetImm)
return true;
1689 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1690 int64_t Val =
CE->getValue();
1691 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1692 Val == std::numeric_limits<int32_t>::min();
1697 bool isMemTBB()
const {
1698 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1704 bool isMemTBH()
const {
1705 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1712 bool isMemRegOffset()
const {
1713 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1718 bool isT2MemRegOffset()
const {
1719 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1730 bool isMemThumbRR()
const {
1733 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1740 bool isMemThumbRIs4()
const {
1741 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1745 if (!
Memory.OffsetImm)
return true;
1746 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1747 int64_t Val =
CE->getValue();
1748 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1753 bool isMemThumbRIs2()
const {
1754 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1758 if (!
Memory.OffsetImm)
return true;
1759 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1760 int64_t Val =
CE->getValue();
1761 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1766 bool isMemThumbRIs1()
const {
1767 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1771 if (!
Memory.OffsetImm)
return true;
1772 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1773 int64_t Val =
CE->getValue();
1774 return Val >= 0 && Val <= 31;
1779 bool isMemThumbSPI()
const {
1780 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1784 if (!
Memory.OffsetImm)
return true;
1785 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1786 int64_t Val =
CE->getValue();
1787 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1792 bool isMemImm8s4Offset()
const {
1796 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1798 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1801 if (!
Memory.OffsetImm)
return true;
1802 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1803 int64_t Val =
CE->getValue();
1805 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1806 Val == std::numeric_limits<int32_t>::min();
1811 bool isMemImm7s4Offset()
const {
1815 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1817 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1818 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1822 if (!
Memory.OffsetImm)
return true;
1823 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1824 int64_t Val =
CE->getValue();
1826 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1831 bool isMemImm0_1020s4Offset()
const {
1832 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1835 if (!
Memory.OffsetImm)
return true;
1836 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1837 int64_t Val =
CE->getValue();
1838 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1843 bool isMemImm8Offset()
const {
1844 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1847 if (
Memory.BaseRegNum == ARM::PC)
return false;
1849 if (!
Memory.OffsetImm)
return true;
1850 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1851 int64_t Val =
CE->getValue();
1852 return (Val == std::numeric_limits<int32_t>::min()) ||
1853 (Val > -256 && Val < 256);
1858 template<
unsigned Bits,
unsigned RegClassID>
1859 bool isMemImm7ShiftedOffset()
const {
1860 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1861 !ARMMCRegisterClasses[RegClassID].contains(
Memory.BaseRegNum))
1867 if (!
Memory.OffsetImm)
return true;
1868 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1869 int64_t Val =
CE->getValue();
1873 if (Val == INT32_MIN)
1876 unsigned Divisor = 1U <<
Bits;
1879 if (Val % Divisor != 0)
1884 return (Val >= -127 && Val <= 127);
1889 template <
int shift>
bool isMemRegRQOffset()
const {
1890 if (!isMVEMem() ||
Memory.OffsetImm !=
nullptr ||
Memory.Alignment != 0)
1893 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1896 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1910 template <
int shift>
bool isMemRegQOffset()
const {
1911 if (!isMVEMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1914 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1920 static_assert(shift < 56,
1921 "Such that we dont shift by a value higher than 62");
1922 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1923 int64_t Val =
CE->getValue();
1926 if ((Val & ((1U << shift) - 1)) != 0)
1932 int64_t
Range = (1U << (7 + shift)) - 1;
1933 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1938 bool isMemPosImm8Offset()
const {
1939 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1942 if (!
Memory.OffsetImm)
return true;
1943 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1944 int64_t Val =
CE->getValue();
1945 return Val >= 0 && Val < 256;
1950 bool isMemNegImm8Offset()
const {
1951 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1954 if (
Memory.BaseRegNum == ARM::PC)
return false;
1956 if (!
Memory.OffsetImm)
return false;
1957 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1958 int64_t Val =
CE->getValue();
1959 return (Val == std::numeric_limits<int32_t>::min()) ||
1960 (Val > -256 && Val < 0);
1965 bool isMemUImm12Offset()
const {
1966 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1969 if (!
Memory.OffsetImm)
return true;
1970 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1971 int64_t Val =
CE->getValue();
1972 return (Val >= 0 && Val < 4096);
1977 bool isMemImm12Offset()
const {
1982 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1985 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1988 if (!
Memory.OffsetImm)
return true;
1989 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1990 int64_t Val =
CE->getValue();
1991 return (Val > -4096 && Val < 4096) ||
1992 (Val == std::numeric_limits<int32_t>::min());
1999 bool isConstPoolAsmImm()
const {
2002 return (isConstantPoolImm());
2005 bool isPostIdxImm8()
const {
2006 if (!
isImm())
return false;
2008 if (!CE)
return false;
2009 int64_t Val =
CE->getValue();
2010 return (Val > -256 && Val < 256) ||
2011 (Val == std::numeric_limits<int32_t>::min());
2014 bool isPostIdxImm8s4()
const {
2015 if (!
isImm())
return false;
2017 if (!CE)
return false;
2018 int64_t Val =
CE->getValue();
2019 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2020 (Val == std::numeric_limits<int32_t>::min());
2023 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2024 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2025 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2028 bool isSingleSpacedVectorList()
const {
2029 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2032 bool isDoubleSpacedVectorList()
const {
2033 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2036 bool isVecListOneD()
const {
2037 if (!isSingleSpacedVectorList())
return false;
2038 return VectorList.Count == 1;
2041 bool isVecListTwoMQ()
const {
2042 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2043 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2047 bool isVecListDPair()
const {
2048 if (!isSingleSpacedVectorList())
return false;
2049 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2053 bool isVecListThreeD()
const {
2054 if (!isSingleSpacedVectorList())
return false;
2055 return VectorList.Count == 3;
2058 bool isVecListFourD()
const {
2059 if (!isSingleSpacedVectorList())
return false;
2060 return VectorList.Count == 4;
2063 bool isVecListDPairSpaced()
const {
2064 if (Kind != k_VectorList)
return false;
2065 if (isSingleSpacedVectorList())
return false;
2066 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2070 bool isVecListThreeQ()
const {
2071 if (!isDoubleSpacedVectorList())
return false;
2072 return VectorList.Count == 3;
2075 bool isVecListFourQ()
const {
2076 if (!isDoubleSpacedVectorList())
return false;
2077 return VectorList.Count == 4;
2080 bool isVecListFourMQ()
const {
2081 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2082 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2086 bool isSingleSpacedVectorAllLanes()
const {
2087 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2090 bool isDoubleSpacedVectorAllLanes()
const {
2091 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2094 bool isVecListOneDAllLanes()
const {
2095 if (!isSingleSpacedVectorAllLanes())
return false;
2096 return VectorList.Count == 1;
2099 bool isVecListDPairAllLanes()
const {
2100 if (!isSingleSpacedVectorAllLanes())
return false;
2101 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2105 bool isVecListDPairSpacedAllLanes()
const {
2106 if (!isDoubleSpacedVectorAllLanes())
return false;
2107 return VectorList.Count == 2;
2110 bool isVecListThreeDAllLanes()
const {
2111 if (!isSingleSpacedVectorAllLanes())
return false;
2112 return VectorList.Count == 3;
2115 bool isVecListThreeQAllLanes()
const {
2116 if (!isDoubleSpacedVectorAllLanes())
return false;
2117 return VectorList.Count == 3;
2120 bool isVecListFourDAllLanes()
const {
2121 if (!isSingleSpacedVectorAllLanes())
return false;
2122 return VectorList.Count == 4;
2125 bool isVecListFourQAllLanes()
const {
2126 if (!isDoubleSpacedVectorAllLanes())
return false;
2127 return VectorList.Count == 4;
2130 bool isSingleSpacedVectorIndexed()
const {
2131 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2134 bool isDoubleSpacedVectorIndexed()
const {
2135 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2138 bool isVecListOneDByteIndexed()
const {
2139 if (!isSingleSpacedVectorIndexed())
return false;
2140 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2143 bool isVecListOneDHWordIndexed()
const {
2144 if (!isSingleSpacedVectorIndexed())
return false;
2145 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2148 bool isVecListOneDWordIndexed()
const {
2149 if (!isSingleSpacedVectorIndexed())
return false;
2150 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2153 bool isVecListTwoDByteIndexed()
const {
2154 if (!isSingleSpacedVectorIndexed())
return false;
2155 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2158 bool isVecListTwoDHWordIndexed()
const {
2159 if (!isSingleSpacedVectorIndexed())
return false;
2160 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2163 bool isVecListTwoQWordIndexed()
const {
2164 if (!isDoubleSpacedVectorIndexed())
return false;
2165 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2168 bool isVecListTwoQHWordIndexed()
const {
2169 if (!isDoubleSpacedVectorIndexed())
return false;
2170 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2173 bool isVecListTwoDWordIndexed()
const {
2174 if (!isSingleSpacedVectorIndexed())
return false;
2175 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2178 bool isVecListThreeDByteIndexed()
const {
2179 if (!isSingleSpacedVectorIndexed())
return false;
2180 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2183 bool isVecListThreeDHWordIndexed()
const {
2184 if (!isSingleSpacedVectorIndexed())
return false;
2185 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2188 bool isVecListThreeQWordIndexed()
const {
2189 if (!isDoubleSpacedVectorIndexed())
return false;
2190 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2193 bool isVecListThreeQHWordIndexed()
const {
2194 if (!isDoubleSpacedVectorIndexed())
return false;
2195 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2198 bool isVecListThreeDWordIndexed()
const {
2199 if (!isSingleSpacedVectorIndexed())
return false;
2200 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2203 bool isVecListFourDByteIndexed()
const {
2204 if (!isSingleSpacedVectorIndexed())
return false;
2205 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2208 bool isVecListFourDHWordIndexed()
const {
2209 if (!isSingleSpacedVectorIndexed())
return false;
2210 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2213 bool isVecListFourQWordIndexed()
const {
2214 if (!isDoubleSpacedVectorIndexed())
return false;
2215 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2218 bool isVecListFourQHWordIndexed()
const {
2219 if (!isDoubleSpacedVectorIndexed())
return false;
2220 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2223 bool isVecListFourDWordIndexed()
const {
2224 if (!isSingleSpacedVectorIndexed())
return false;
2225 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2228 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2230 template <
unsigned NumLanes>
2231 bool isVectorIndexInRange()
const {
2232 if (Kind != k_VectorIndex)
return false;
2233 return VectorIndex.Val < NumLanes;
2236 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2237 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2238 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2239 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2241 template<
int PermittedValue,
int OtherPermittedValue>
2242 bool isMVEPairVectorIndex()
const {
2243 if (Kind != k_VectorIndex)
return false;
2244 return VectorIndex.Val == PermittedValue ||
2245 VectorIndex.Val == OtherPermittedValue;
2248 bool isNEONi8splat()
const {
2249 if (!
isImm())
return false;
2252 if (!CE)
return false;
2253 int64_t
Value =
CE->getValue();
2260 if (isNEONByteReplicate(2))
2266 if (!CE)
return false;
2267 unsigned Value =
CE->getValue();
2271 bool isNEONi16splatNot()
const {
2276 if (!CE)
return false;
2277 unsigned Value =
CE->getValue();
2282 if (isNEONByteReplicate(4))
2288 if (!CE)
return false;
2289 unsigned Value =
CE->getValue();
2293 bool isNEONi32splatNot()
const {
2298 if (!CE)
return false;
2299 unsigned Value =
CE->getValue();
2303 static bool isValidNEONi32vmovImm(int64_t
Value) {
2306 return ((
Value & 0xffffffffffffff00) == 0) ||
2307 ((
Value & 0xffffffffffff00ff) == 0) ||
2308 ((
Value & 0xffffffffff00ffff) == 0) ||
2309 ((
Value & 0xffffffff00ffffff) == 0) ||
2310 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2311 ((
Value & 0xffffffffff00ffff) == 0xffff);
2314 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2315 assert((Width == 8 || Width == 16 || Width == 32) &&
2316 "Invalid element width");
2317 assert(NumElems * Width <= 64 &&
"Invalid result width");
2325 int64_t
Value =
CE->getValue();
2333 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2335 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2338 for (
unsigned i = 1; i < NumElems; ++i) {
2340 if ((
Value & Mask) != Elem)
2346 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2347 return isNEONReplicate(8, NumBytes,
false);
2350 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2351 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2352 "Invalid source width");
2353 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2354 "Invalid destination width");
2355 assert(FromW < ToW &&
"ToW is not less than FromW");
2358 template<
unsigned FromW,
unsigned ToW>
2359 bool isNEONmovReplicate()
const {
2360 checkNeonReplicateArgs(FromW, ToW);
2361 if (ToW == 64 && isNEONi64splat())
2363 return isNEONReplicate(FromW, ToW / FromW,
false);
2366 template<
unsigned FromW,
unsigned ToW>
2367 bool isNEONinvReplicate()
const {
2368 checkNeonReplicateArgs(FromW, ToW);
2369 return isNEONReplicate(FromW, ToW / FromW,
true);
2372 bool isNEONi32vmov()
const {
2373 if (isNEONByteReplicate(4))
2381 return isValidNEONi32vmovImm(
CE->getValue());
2384 bool isNEONi32vmovNeg()
const {
2385 if (!
isImm())
return false;
2388 if (!CE)
return false;
2389 return isValidNEONi32vmovImm(~
CE->getValue());
2392 bool isNEONi64splat()
const {
2393 if (!
isImm())
return false;
2396 if (!CE)
return false;
2399 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2400 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2404 template<
int64_t Angle,
int64_t Remainder>
2405 bool isComplexRotation()
const {
2406 if (!
isImm())
return false;
2409 if (!CE)
return false;
2412 return (
Value % Angle == Remainder &&
Value <= 270);
2415 bool isMVELongShift()
const {
2416 if (!
isImm())
return false;
2419 if (!CE)
return false;
2424 bool isMveSaturateOp()
const {
2425 if (!
isImm())
return false;
2427 if (!CE)
return false;
2432 bool isITCondCodeNoAL()
const {
2433 if (!isITCondCode())
return false;
2438 bool isITCondCodeRestrictedI()
const {
2439 if (!isITCondCode())
2445 bool isITCondCodeRestrictedS()
const {
2446 if (!isITCondCode())
2453 bool isITCondCodeRestrictedU()
const {
2454 if (!isITCondCode())
2460 bool isITCondCodeRestrictedFP()
const {
2461 if (!isITCondCode())
2472 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2478 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2479 assert(
N == 1 &&
"Invalid number of operands!");
2480 addExpr(Inst, getImm());
2483 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2484 assert(
N == 1 &&
"Invalid number of operands!");
2485 addExpr(Inst, getImm());
2488 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2489 assert(
N == 2 &&
"Invalid number of operands!");
2495 void addVPTPredNOperands(
MCInst &Inst,
unsigned N)
const {
2496 assert(
N == 3 &&
"Invalid number of operands!");
2498 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? 0: ARM::P0;
2503 void addVPTPredROperands(
MCInst &Inst,
unsigned N)
const {
2504 assert(
N == 4 &&
"Invalid number of operands!");
2505 addVPTPredNOperands(Inst,
N-1);
2515 "Inactive register in vpred_r is not tied to an output!");
2521 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
2522 assert(
N == 1 &&
"Invalid number of operands!");
2526 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
2527 assert(
N == 1 &&
"Invalid number of operands!");
2531 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
2532 assert(
N == 1 &&
"Invalid number of operands!");
2536 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
2537 assert(
N == 1 &&
"Invalid number of operands!");
2541 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2542 assert(
N == 1 &&
"Invalid number of operands!");
2546 void addITCondCodeInvOperands(
MCInst &Inst,
unsigned N)
const {
2547 assert(
N == 1 &&
"Invalid number of operands!");
2551 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
2552 assert(
N == 1 &&
"Invalid number of operands!");
2556 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
2557 assert(
N == 1 &&
"Invalid number of operands!");
2561 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
2562 assert(
N == 3 &&
"Invalid number of operands!");
2563 assert(isRegShiftedReg() &&
2564 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2571 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
2572 assert(
N == 2 &&
"Invalid number of operands!");
2573 assert(isRegShiftedImm() &&
2574 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2577 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2582 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
2583 assert(
N == 1 &&
"Invalid number of operands!");
2588 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
2589 assert(
N == 1 &&
"Invalid number of operands!");
2591 for (
unsigned Reg : RegList)
2595 void addRegListWithAPSROperands(
MCInst &Inst,
unsigned N)
const {
2596 assert(
N == 1 &&
"Invalid number of operands!");
2598 for (
unsigned Reg : RegList)
2602 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2603 addRegListOperands(Inst,
N);
2606 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2607 addRegListOperands(Inst,
N);
2610 void addFPSRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2611 addRegListOperands(Inst,
N);
2614 void addFPDRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2615 addRegListOperands(Inst,
N);
2618 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2619 assert(
N == 1 &&
"Invalid number of operands!");
2624 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2625 assert(
N == 1 &&
"Invalid number of operands!");
2629 return addImmOperands(Inst,
N);
2634 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2635 assert(
N == 1 &&
"Invalid number of operands!");
2641 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2642 assert(
N == 1 &&
"Invalid number of operands!");
2648 void addThumbModImmNeg8_255Operands(
MCInst &Inst,
unsigned N)
const {
2649 assert(
N == 1 &&
"Invalid number of operands!");
2655 void addThumbModImmNeg1_7Operands(
MCInst &Inst,
unsigned N)
const {
2656 assert(
N == 1 &&
"Invalid number of operands!");
2662 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2663 assert(
N == 1 &&
"Invalid number of operands!");
2669 (32 - (lsb + width)));
2673 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2674 assert(
N == 1 &&
"Invalid number of operands!");
2675 addExpr(Inst, getImm());
2678 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2679 assert(
N == 1 &&
"Invalid number of operands!");
2684 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2685 assert(
N == 1 &&
"Invalid number of operands!");
2690 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2691 assert(
N == 1 &&
"Invalid number of operands!");
2697 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2698 assert(
N == 1 &&
"Invalid number of operands!");
2705 void addImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
2706 assert(
N == 1 &&
"Invalid number of operands!");
2713 void addImm7Shift0Operands(
MCInst &Inst,
unsigned N)
const {
2714 assert(
N == 1 &&
"Invalid number of operands!");
2719 void addImm7Shift1Operands(
MCInst &Inst,
unsigned N)
const {
2720 assert(
N == 1 &&
"Invalid number of operands!");
2725 void addImm7Shift2Operands(
MCInst &Inst,
unsigned N)
const {
2726 assert(
N == 1 &&
"Invalid number of operands!");
2731 void addImm7Operands(
MCInst &Inst,
unsigned N)
const {
2732 assert(
N == 1 &&
"Invalid number of operands!");
2737 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2738 assert(
N == 1 &&
"Invalid number of operands!");
2745 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2746 assert(
N == 1 &&
"Invalid number of operands!");
2753 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2754 assert(
N == 1 &&
"Invalid number of operands!");
2761 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2762 assert(
N == 1 &&
"Invalid number of operands!");
2769 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2770 assert(
N == 1 &&
"Invalid number of operands!");
2777 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2778 assert(
N == 1 &&
"Invalid number of operands!");
2782 unsigned Imm =
CE->getValue();
2786 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2787 assert(
N == 1 &&
"Invalid number of operands!");
2791 int Val =
CE->getValue();
2795 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2796 assert(
N == 1 &&
"Invalid number of operands!");
2803 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2804 assert(
N == 1 &&
"Invalid number of operands!");
2811 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2812 assert(
N == 1 &&
"Invalid number of operands!");
2819 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2820 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2828 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2829 assert(
N == 1 &&
"Invalid number of operands!");
2841 assert(isGPRMem() &&
"Unknown value type!");
2842 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2843 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2849 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2850 assert(
N == 1 &&
"Invalid number of operands!");
2854 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2855 assert(
N == 1 &&
"Invalid number of operands!");
2859 void addTraceSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2860 assert(
N == 1 &&
"Invalid number of operands!");
2864 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2865 assert(
N == 1 &&
"Invalid number of operands!");
2869 void addMemNoOffsetT2Operands(
MCInst &Inst,
unsigned N)
const {
2870 assert(
N == 1 &&
"Invalid number of operands!");
2874 void addMemNoOffsetT2NoSpOperands(
MCInst &Inst,
unsigned N)
const {
2875 assert(
N == 1 &&
"Invalid number of operands!");
2879 void addMemNoOffsetTOperands(
MCInst &Inst,
unsigned N)
const {
2880 assert(
N == 1 &&
"Invalid number of operands!");
2884 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2885 assert(
N == 1 &&
"Invalid number of operands!");
2886 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2892 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2893 assert(
N == 1 &&
"Invalid number of operands!");
2898 if (!isa<MCConstantExpr>(getImm())) {
2904 int Val =
CE->getValue();
2908 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2909 assert(
N == 2 &&
"Invalid number of operands!");
2914 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2915 addAlignedMemoryOperands(Inst,
N);
2918 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2919 addAlignedMemoryOperands(Inst,
N);
2922 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2923 addAlignedMemoryOperands(Inst,
N);
2926 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2927 addAlignedMemoryOperands(Inst,
N);
2930 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2931 addAlignedMemoryOperands(Inst,
N);
2934 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2935 addAlignedMemoryOperands(Inst,
N);
2938 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2939 addAlignedMemoryOperands(Inst,
N);
2942 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2943 addAlignedMemoryOperands(Inst,
N);
2946 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2947 addAlignedMemoryOperands(Inst,
N);
2950 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2951 addAlignedMemoryOperands(Inst,
N);
2954 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2955 addAlignedMemoryOperands(Inst,
N);
2958 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
2959 assert(
N == 3 &&
"Invalid number of operands!");
2962 if (!
Memory.OffsetRegNum) {
2965 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
2966 int32_t Val =
CE->getValue();
2969 if (Val == std::numeric_limits<int32_t>::min())
2987 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
2988 assert(
N == 2 &&
"Invalid number of operands!");
2990 assert(CE &&
"non-constant AM2OffsetImm operand!");
2991 int32_t Val =
CE->getValue();
2994 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2995 if (Val < 0) Val = -Val;
3001 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
3002 assert(
N == 3 &&
"Invalid number of operands!");
3015 if (!
Memory.OffsetRegNum) {
3018 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3019 int32_t Val =
CE->getValue();
3022 if (Val == std::numeric_limits<int32_t>::min())
3039 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3040 assert(
N == 2 &&
"Invalid number of operands!");
3041 if (Kind == k_PostIndexRegister) {
3051 int32_t Val =
CE->getValue();
3054 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3055 if (Val < 0) Val = -Val;
3061 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
3062 assert(
N == 2 &&
"Invalid number of operands!");
3075 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3077 int32_t Val =
CE->getValue() / 4;
3080 if (Val == std::numeric_limits<int32_t>::min())
3090 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
3091 assert(
N == 2 &&
"Invalid number of operands!");
3105 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3106 int32_t Val =
CE->getValue() / 2;
3109 if (Val == std::numeric_limits<int32_t>::min())
3119 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3120 assert(
N == 2 &&
"Invalid number of operands!");
3131 addExpr(Inst,
Memory.OffsetImm);
3134 void addMemImm7s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3135 assert(
N == 2 &&
"Invalid number of operands!");
3146 addExpr(Inst,
Memory.OffsetImm);
3149 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3150 assert(
N == 2 &&
"Invalid number of operands!");
3154 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3161 void addMemImmOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3162 assert(
N == 2 &&
"Invalid number of operands!");
3164 addExpr(Inst,
Memory.OffsetImm);
3167 void addMemRegRQOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3168 assert(
N == 2 &&
"Invalid number of operands!");
3173 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3174 assert(
N == 2 &&
"Invalid number of operands!");
3177 addExpr(Inst, getImm());
3184 addExpr(Inst,
Memory.OffsetImm);
3187 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3188 assert(
N == 2 &&
"Invalid number of operands!");
3191 addExpr(Inst, getImm());
3198 addExpr(Inst,
Memory.OffsetImm);
3201 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
3202 assert(
N == 1 &&
"Invalid number of operands!");
3205 addExpr(Inst, getConstantPoolImm());
3208 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
3209 assert(
N == 2 &&
"Invalid number of operands!");
3214 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
3215 assert(
N == 2 &&
"Invalid number of operands!");
3220 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3221 assert(
N == 3 &&
"Invalid number of operands!");
3230 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3231 assert(
N == 3 &&
"Invalid number of operands!");
3237 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
3238 assert(
N == 2 &&
"Invalid number of operands!");
3243 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
3244 assert(
N == 2 &&
"Invalid number of operands!");
3248 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3255 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
3256 assert(
N == 2 &&
"Invalid number of operands!");
3260 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3266 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
3267 assert(
N == 2 &&
"Invalid number of operands!");
3269 addExpr(Inst,
Memory.OffsetImm);
3272 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
3273 assert(
N == 2 &&
"Invalid number of operands!");
3277 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3284 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
3285 assert(
N == 1 &&
"Invalid number of operands!");
3287 assert(CE &&
"non-constant post-idx-imm8 operand!");
3288 int Imm =
CE->getValue();
3289 bool isAdd =
Imm >= 0;
3290 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3295 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
3296 assert(
N == 1 &&
"Invalid number of operands!");
3298 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3299 int Imm =
CE->getValue();
3300 bool isAdd =
Imm >= 0;
3301 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3307 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
3308 assert(
N == 2 &&
"Invalid number of operands!");
3313 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
3314 assert(
N == 2 &&
"Invalid number of operands!");
3320 PostIdxReg.ShiftTy);
3324 void addPowerTwoOperands(
MCInst &Inst,
unsigned N)
const {
3325 assert(
N == 1 &&
"Invalid number of operands!");
3330 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
3331 assert(
N == 1 &&
"Invalid number of operands!");
3335 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
3336 assert(
N == 1 &&
"Invalid number of operands!");
3340 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
3341 assert(
N == 1 &&
"Invalid number of operands!");
3345 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
3346 assert(
N == 1 &&
"Invalid number of operands!");
3350 void addMVEVecListOperands(
MCInst &Inst,
unsigned N)
const {
3351 assert(
N == 1 &&
"Invalid number of operands!");
3367 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3369 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3370 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID];
3373 for (
I = 0;
I <
E;
I++)
3376 assert(
I <
E &&
"Invalid vector list start register!");
3381 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
3382 assert(
N == 2 &&
"Invalid number of operands!");
3387 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
3388 assert(
N == 1 &&
"Invalid number of operands!");
3392 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
3393 assert(
N == 1 &&
"Invalid number of operands!");
3397 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
3398 assert(
N == 1 &&
"Invalid number of operands!");
3402 void addVectorIndex64Operands(
MCInst &Inst,
unsigned N)
const {
3403 assert(
N == 1 &&
"Invalid number of operands!");
3407 void addMVEVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3408 assert(
N == 1 &&
"Invalid number of operands!");
3412 void addMVEPairVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3413 assert(
N == 1 &&
"Invalid number of operands!");
3417 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
3418 assert(
N == 1 &&
"Invalid number of operands!");
3425 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
3426 assert(
N == 1 &&
"Invalid number of operands!");
3429 unsigned Value =
CE->getValue();
3434 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3435 assert(
N == 1 &&
"Invalid number of operands!");
3438 unsigned Value =
CE->getValue();
3443 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
3444 assert(
N == 1 &&
"Invalid number of operands!");
3447 unsigned Value =
CE->getValue();
3452 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3453 assert(
N == 1 &&
"Invalid number of operands!");
3456 unsigned Value =
CE->getValue();
3461 void addNEONi8ReplicateOperands(
MCInst &Inst,
bool Inv)
const {
3466 "All instructions that wants to replicate non-zero byte "
3467 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3468 unsigned Value =
CE->getValue();
3471 unsigned B =
Value & 0xff;
3476 void addNEONinvi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3477 assert(
N == 1 &&
"Invalid number of operands!");
3478 addNEONi8ReplicateOperands(Inst,
true);
3481 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3484 else if (
Value > 0xffff &&
Value <= 0xffffff)
3486 else if (
Value > 0xffffff)
3491 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
3492 assert(
N == 1 &&
"Invalid number of operands!");
3495 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3499 void addNEONvmovi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3500 assert(
N == 1 &&
"Invalid number of operands!");
3501 addNEONi8ReplicateOperands(Inst,
false);
3504 void addNEONvmovi16ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3505 assert(
N == 1 &&
"Invalid number of operands!");
3511 "All instructions that want to replicate non-zero half-word "
3512 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3514 unsigned Elem =
Value & 0xffff;
3516 Elem = (Elem >> 8) | 0x200;
3520 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
3521 assert(
N == 1 &&
"Invalid number of operands!");
3524 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3528 void addNEONvmovi32ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3529 assert(
N == 1 &&
"Invalid number of operands!");
3535 "All instructions that want to replicate non-zero word "
3536 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3538 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3542 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
3543 assert(
N == 1 &&
"Invalid number of operands!");
3548 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3554 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
3555 assert(
N == 1 &&
"Invalid number of operands!");
3560 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
3561 assert(
N == 1 &&
"Invalid number of operands!");
3566 void addMveSaturateOperands(
MCInst &Inst,
unsigned N)
const {
3567 assert(
N == 1 &&
"Invalid number of operands!");
3569 unsigned Imm =
CE->getValue();
3570 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3576 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S) {
3577 auto Op = std::make_unique<ARMOperand>(k_ITCondMask);
3586 auto Op = std::make_unique<ARMOperand>(k_CondCode);
3595 auto Op = std::make_unique<ARMOperand>(k_VPTPred);
3602 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S) {
3603 auto Op = std::make_unique<ARMOperand>(k_CoprocNum);
3604 Op->Cop.Val = CopVal;
3610 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S) {
3611 auto Op = std::make_unique<ARMOperand>(k_CoprocReg);
3612 Op->Cop.Val = CopVal;
3618 static std::unique_ptr<ARMOperand> CreateCoprocOption(
unsigned Val,
SMLoc S,
3620 auto Op = std::make_unique<ARMOperand>(k_CoprocOption);
3627 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S) {
3628 auto Op = std::make_unique<ARMOperand>(k_CCOut);
3629 Op->Reg.RegNum = RegNum;
3635 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S) {
3636 auto Op = std::make_unique<ARMOperand>(k_Token);
3637 Op->Tok.Data = Str.data();
3638 Op->Tok.Length = Str.size();
3644 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
3646 auto Op = std::make_unique<ARMOperand>(k_Register);
3647 Op->Reg.RegNum = RegNum;
3653 static std::unique_ptr<ARMOperand>
3655 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
3657 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister);
3658 Op->RegShiftedReg.ShiftTy = ShTy;
3659 Op->RegShiftedReg.SrcReg = SrcReg;
3660 Op->RegShiftedReg.ShiftReg = ShiftReg;
3661 Op->RegShiftedReg.ShiftImm = ShiftImm;
3667 static std::unique_ptr<ARMOperand>
3670 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate);
3671 Op->RegShiftedImm.ShiftTy = ShTy;
3672 Op->RegShiftedImm.SrcReg = SrcReg;
3673 Op->RegShiftedImm.ShiftImm = ShiftImm;
3679 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3681 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate);
3682 Op->ShifterImm.isASR = isASR;
3683 Op->ShifterImm.Imm =
Imm;
3689 static std::unique_ptr<ARMOperand> CreateRotImm(
unsigned Imm,
SMLoc S,
3691 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate);
3692 Op->RotImm.Imm =
Imm;
3698 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3700 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate);
3702 Op->ModImm.Rot = Rot;
3708 static std::unique_ptr<ARMOperand>
3710 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate);
3717 static std::unique_ptr<ARMOperand>
3718 CreateBitfield(
unsigned LSB,
unsigned Width,
SMLoc S,
SMLoc E) {
3719 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor);
3720 Op->Bitfield.LSB = LSB;
3727 static std::unique_ptr<ARMOperand>
3730 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3731 KindTy
Kind = k_RegisterList;
3733 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
3734 Regs.front().second)) {
3735 if (Regs.back().second == ARM::VPR)
3736 Kind = k_FPDRegisterListWithVPR;
3738 Kind = k_DPRRegisterList;
3739 }
else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
3740 Regs.front().second)) {
3741 if (Regs.back().second == ARM::VPR)
3742 Kind = k_FPSRegisterListWithVPR;
3744 Kind = k_SPRRegisterList;
3747 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3748 Kind = k_RegisterListWithAPSR;
3752 auto Op = std::make_unique<ARMOperand>(Kind);
3753 for (
const auto &
P : Regs)
3754 Op->Registers.push_back(
P.second);
3756 Op->StartLoc = StartLoc;
3757 Op->EndLoc = EndLoc;
3761 static std::unique_ptr<ARMOperand> CreateVectorList(
unsigned RegNum,
3763 bool isDoubleSpaced,
3765 auto Op = std::make_unique<ARMOperand>(k_VectorList);
3766 Op->VectorList.RegNum = RegNum;
3767 Op->VectorList.Count = Count;
3768 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3774 static std::unique_ptr<ARMOperand>
3775 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
3777 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes);
3778 Op->VectorList.RegNum = RegNum;
3779 Op->VectorList.Count = Count;
3780 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3786 static std::unique_ptr<ARMOperand>
3787 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
3789 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed);
3790 Op->VectorList.RegNum = RegNum;
3791 Op->VectorList.Count = Count;
3792 Op->VectorList.LaneIndex =
Index;
3793 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3799 static std::unique_ptr<ARMOperand>
3801 auto Op = std::make_unique<ARMOperand>(k_VectorIndex);
3802 Op->VectorIndex.Val =
Idx;
3808 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
3810 auto Op = std::make_unique<ARMOperand>(k_Immediate);
3817 static std::unique_ptr<ARMOperand>
3818 CreateMem(
unsigned BaseRegNum,
const MCExpr *OffsetImm,
unsigned OffsetRegNum,
3821 auto Op = std::make_unique<ARMOperand>(k_Memory);
3822 Op->Memory.BaseRegNum = BaseRegNum;
3823 Op->Memory.OffsetImm = OffsetImm;
3824 Op->Memory.OffsetRegNum = OffsetRegNum;
3825 Op->Memory.ShiftType = ShiftType;
3826 Op->Memory.ShiftImm = ShiftImm;
3827 Op->Memory.Alignment = Alignment;
3828 Op->Memory.isNegative = isNegative;
3831 Op->AlignmentLoc = AlignmentLoc;
3835 static std::unique_ptr<ARMOperand>
3838 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister);
3839 Op->PostIdxReg.RegNum = RegNum;
3840 Op->PostIdxReg.isAdd = isAdd;
3841 Op->PostIdxReg.ShiftTy = ShiftTy;
3842 Op->PostIdxReg.ShiftImm = ShiftImm;
3848 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt,
3850 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt);
3851 Op->MBOpt.Val = Opt;
3857 static std::unique_ptr<ARMOperand>
3859 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3860 Op->ISBOpt.Val = Opt;
3866 static std::unique_ptr<ARMOperand>
3868 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3869 Op->TSBOpt.Val = Opt;
3875 static std::unique_ptr<ARMOperand> CreateProcIFlags(
ARM_PROC::IFlags IFlags,
3877 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags);
3884 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S) {
3885 auto Op = std::make_unique<ARMOperand>(k_MSRMask);
3886 Op->MMask.Val = MMask;
3892 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S) {
3893 auto Op = std::make_unique<ARMOperand>(k_BankedReg);
3894 Op->BankedReg.Val =
Reg;
3921 case k_ITCondMask: {
3922 static const char *
const MaskStr[] = {
3923 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
3924 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
3925 "(t)",
"(tett)",
"(tet)",
"(tete)",
3926 "(te)",
"(teet)",
"(tee)",
"(teee)",
3928 assert((ITMask.Mask & 0xf) == ITMask.Mask);
3929 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
3933 OS <<
"<coprocessor number: " << getCoproc() <<
">";
3936 OS <<
"<coprocessor register: " << getCoproc() <<
">";
3938 case k_CoprocOption:
3939 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
3942 OS <<
"<mask: " << getMSRMask() <<
">";
3945 OS <<
"<banked reg: " << getBankedReg() <<
">";
3950 case k_MemBarrierOpt:
3951 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
3953 case k_InstSyncBarrierOpt:
3954 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
3956 case k_TraceSyncBarrierOpt:
3957 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
3964 OS <<
" offset-imm:" << *
Memory.OffsetImm;
3966 OS <<
" offset-reg:" << (
Memory.isNegative ?
"-" :
"")
3970 OS <<
" shift-imm:" <<
Memory.ShiftImm;
3973 OS <<
" alignment:" <<
Memory.Alignment;
3976 case k_PostIndexRegister:
3977 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
3978 <<
RegName(PostIdxReg.RegNum);
3981 << PostIdxReg.ShiftImm;
3984 case k_ProcIFlags: {
3985 OS <<
"<ARM_PROC::";
3986 unsigned IFlags = getProcIFlags();
3987 for (
int i=2; i >= 0; --i)
3988 if (IFlags & (1 << i))
3996 case k_ShifterImmediate:
3997 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
3998 <<
" #" << ShifterImm.Imm <<
">";
4000 case k_ShiftedRegister:
4001 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4003 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4005 case k_ShiftedImmediate:
4006 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4008 << RegShiftedImm.ShiftImm <<
">";
4010 case k_RotateImmediate:
4011 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4013 case k_ModifiedImmediate:
4014 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4015 << ModImm.Rot <<
")>";
4017 case k_ConstantPoolImmediate:
4018 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
4020 case k_BitfieldDescriptor:
4021 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4022 <<
", width: " <<
Bitfield.Width <<
">";
4024 case k_RegisterList:
4025 case k_RegisterListWithAPSR:
4026 case k_DPRRegisterList:
4027 case k_SPRRegisterList:
4028 case k_FPSRegisterListWithVPR:
4029 case k_FPDRegisterListWithVPR: {
4030 OS <<
"<register_list ";
4036 if (++
I <
E)
OS <<
", ";
4043 OS <<
"<vector_list " << VectorList.Count <<
" * "
4044 <<
RegName(VectorList.RegNum) <<
">";
4046 case k_VectorListAllLanes:
4047 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4048 <<
RegName(VectorList.RegNum) <<
">";
4050 case k_VectorListIndexed:
4051 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4052 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4055 OS <<
"'" << getToken() <<
"'";
4058 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4072 const AsmToken &Tok = getParser().getTok();
4075 RegNo = tryParseRegister();
4077 return (RegNo == (
unsigned)-1);
4083 if (parseRegister(RegNo, StartLoc, EndLoc))
4091int ARMAsmParser::tryParseRegister() {
4100 .
Case(
"r13", ARM::SP)
4101 .
Case(
"r14", ARM::LR)
4102 .
Case(
"r15", ARM::PC)
4103 .
Case(
"ip", ARM::R12)
4105 .
Case(
"a1", ARM::R0)
4106 .
Case(
"a2", ARM::R1)
4107 .
Case(
"a3", ARM::R2)
4108 .
Case(
"a4", ARM::R3)
4109 .
Case(
"v1", ARM::R4)
4110 .
Case(
"v2", ARM::R5)
4111 .
Case(
"v3", ARM::R6)
4112 .
Case(
"v4", ARM::R7)
4113 .
Case(
"v5", ARM::R8)
4114 .
Case(
"v6", ARM::R9)
4115 .
Case(
"v7", ARM::R10)
4116 .
Case(
"v8", ARM::R11)
4117 .
Case(
"sb", ARM::R9)
4118 .
Case(
"sl", ARM::R10)
4119 .
Case(
"fp", ARM::R11)
4128 if (Entry == RegisterReqs.
end())
4131 return Entry->getValue();
4135 if (!hasD32() && RegNum >=
ARM::D16 && RegNum <= ARM::D31)
4173 std::unique_ptr<ARMOperand> PrevOp(
4174 (ARMOperand *)
Operands.pop_back_val().release());
4175 if (!PrevOp->isReg())
4176 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4177 int SrcReg = PrevOp->getReg();
4193 const MCExpr *ShiftExpr =
nullptr;
4194 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4195 Error(ImmLoc,
"invalid immediate shift value");
4201 Error(ImmLoc,
"invalid immediate shift value");
4207 Imm =
CE->getValue();
4211 Error(ImmLoc,
"immediate shift value out of range");
4221 ShiftReg = tryParseRegister();
4222 if (ShiftReg == -1) {
4223 Error(L,
"expected immediate or register in shift operand");
4228 "expected immediate or register in shift operand");
4234 Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
4238 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4254 int RegNo = tryParseRegister();
4258 Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
4276 if (getParser().parseExpression(ImmVal))
4280 return TokError(
"immediate value expected for vector index");
4308 if (
Name.size() < 2 ||
Name[0] != CoprocOp)
4312 switch (
Name.size()) {
4335 case '0':
return 10;
4336 case '1':
return 11;
4337 case '2':
return 12;
4338 case '3':
return 13;
4339 case '4':
return 14;
4340 case '5':
return 15;
4381 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
4401 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S));
4419 if (getParser().parseExpression(Expr)) {
4420 Error(Loc,
"illegal expression");
4424 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255) {
4425 Error(Loc,
"coprocessor option must be an immediate in range [0, 255]");
4428 int Val =
CE->getValue();
4436 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E));
4447 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4451 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4452 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4453 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4454 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4455 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4456 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4457 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4458 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4466 unsigned Enc,
unsigned Reg) {
4467 Regs.emplace_back(Enc,
Reg);
4468 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4469 if (J->first == Enc) {
4470 Regs.erase(J.base());
4485 return TokError(
"Token is not a Left Curly Brace");
4492 int Reg = tryParseRegister();
4494 return Error(RegLoc,
"register expected");
4495 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4496 return Error(RegLoc,
"pseudo-register not allowed");
4503 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4504 Reg = getDRegFromQReg(
Reg);
4505 EReg =
MRI->getEncodingValue(
Reg);
4510 if (
Reg == ARM::RA_AUTH_CODE ||
4511 ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4512 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4513 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg))
4514 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4515 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
Reg))
4516 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4517 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4518 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4520 return Error(RegLoc,
"invalid register in register list");
4523 EReg =
MRI->getEncodingValue(
Reg);
4532 if (
Reg == ARM::RA_AUTH_CODE)
4533 return Error(RegLoc,
"pseudo-register not allowed");
4536 int EndReg = tryParseRegister();
4538 return Error(AfterMinusLoc,
"register expected");
4539 if (EndReg == ARM::RA_AUTH_CODE)
4540 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4542 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4543 EndReg = getDRegFromQReg(EndReg) + 1;
4550 return Error(AfterMinusLoc,
"invalid register in register list");
4552 if (
MRI->getEncodingValue(
Reg) >
MRI->getEncodingValue(EndReg))
4553 return Error(AfterMinusLoc,
"bad range in register list");
4556 while (
Reg != EndReg) {
4558 EReg =
MRI->getEncodingValue(
Reg);
4562 ") in register list");
4571 Reg = tryParseRegister();
4573 return Error(RegLoc,
"register expected");
4574 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4575 return Error(RegLoc,
"pseudo-register not allowed");
4577 bool isQReg =
false;
4578 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4579 Reg = getDRegFromQReg(
Reg);
4583 RC->
getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4584 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
Reg)) {
4587 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4589 if (
Reg == ARM::VPR &&
4590 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4591 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4592 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4593 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4594 EReg =
MRI->getEncodingValue(
Reg);
4597 ") in register list");
4602 if ((
Reg == ARM::RA_AUTH_CODE &&
4603 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
4605 return Error(RegLoc,
"invalid register in register list");
4611 MRI->getEncodingValue(
Reg) <
MRI->getEncodingValue(OldReg)) {
4612 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4613 Warning(RegLoc,
"register list not in ascending order");
4614 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4615 return Error(RegLoc,
"register list not in ascending order");
4618 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4619 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4621 return Error(RegLoc,
"non-contiguous register range");
4622 EReg =
MRI->getEncodingValue(
Reg);
4625 ") in register list");
4628 EReg =
MRI->getEncodingValue(++
Reg);
4652parseVectorLane(VectorLaneTy &LaneKind,
unsigned &
Index,
SMLoc &EndLoc) {
4659 LaneKind = AllLanes;
4672 if (getParser().parseExpression(LaneIndex)) {
4673 Error(Loc,
"illegal expression");
4678 Error(Loc,
"lane index must be empty or an integer");