71#define DEBUG_TYPE "asm-parser"
78enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
81 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
82 cl::desc(
"Allow conditional instructions outdside of an IT block"),
84 "Accept in both ISAs, emit implicit ITs in Thumb"),
86 "Warn in ARM, reject in Thumb"),
88 "Accept in ARM, reject in Thumb"),
89 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
90 "Warn in ARM, emit implicit ITs in Thumb")));
95enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
97static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
104 return (Mask >> (5 - Position) & 1);
113 Locs PersonalityLocs;
114 Locs PersonalityIndexLocs;
115 Locs HandlerDataLocs;
121 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
122 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
123 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
125 bool hasPersonality()
const {
126 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
129 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
130 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
131 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
132 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
133 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
135 void saveFPReg(
int Reg) { FPReg = Reg; }
136 int getFPReg()
const {
return FPReg; }
138 void emitFnStartLocNotes()
const {
139 for (
const SMLoc &Loc : FnStartLocs)
140 Parser.
Note(Loc,
".fnstart was specified here");
143 void emitCantUnwindLocNotes()
const {
144 for (
const SMLoc &Loc : CantUnwindLocs)
145 Parser.
Note(Loc,
".cantunwind was specified here");
148 void emitHandlerDataLocNotes()
const {
149 for (
const SMLoc &Loc : HandlerDataLocs)
150 Parser.
Note(Loc,
".handlerdata was specified here");
153 void emitPersonalityLocNotes()
const {
155 PE = PersonalityLocs.end(),
156 PII = PersonalityIndexLocs.begin(),
157 PIE = PersonalityIndexLocs.end();
158 PI != PE || PII != PIE;) {
159 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
160 Parser.
Note(*PI++,
".personality was specified here");
161 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
162 Parser.
Note(*PII++,
".personalityindex was specified here");
165 "at the same location");
170 FnStartLocs = Locs();
171 CantUnwindLocs = Locs();
172 PersonalityLocs = Locs();
173 HandlerDataLocs = Locs();
174 PersonalityIndexLocs = Locs();
180class ARMMnemonicSets {
191 return CDE.
count(Mnemonic);
196 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
199 return CDEWithVPTSuffix.
count(Mnemonic);
204 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
214 bool isCDEDualRegInstr(
StringRef Mnemonic) {
217 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
218 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
219 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
224 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
225 "cx2",
"cx2a",
"cx2d",
"cx2da",
226 "cx3",
"cx3a",
"cx3d",
"cx3da", })
227 CDE.insert(Mnemonic);
229 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
230 CDE.insert(Mnemonic);
231 CDEWithVPTSuffix.insert(Mnemonic);
232 CDEWithVPTSuffix.insert(std::string(Mnemonic) +
"t");
233 CDEWithVPTSuffix.insert(std::string(Mnemonic) +
"e");
244 "do not have a target streamer");
252 bool NextSymbolIsThumb;
254 bool useImplicitITThumb()
const {
255 return ImplicitItMode == ImplicitItModeTy::Always ||
256 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
259 bool useImplicitITARM()
const {
260 return ImplicitItMode == ImplicitItModeTy::Always ||
261 ImplicitItMode == ImplicitItModeTy::ARMOnly;
276 unsigned CurPosition;
292 if (!inImplicitITBlock()) {
306 for (
const MCInst &Inst : PendingConditionalInsts) {
309 PendingConditionalInsts.clear();
313 ITState.CurPosition = ~0U;
316 bool inITBlock() {
return ITState.CurPosition != ~0U; }
317 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
318 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
320 bool lastInITBlock() {
324 void forwardITPosition() {
325 if (!inITBlock())
return;
330 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
331 ITState.CurPosition = ~0U;
335 void rewindImplicitITPosition() {
336 assert(inImplicitITBlock());
337 assert(ITState.CurPosition > 1);
338 ITState.CurPosition--;
340 unsigned NewMask = 0;
341 NewMask |= ITState.Mask & (0xC << TZ);
342 NewMask |= 0x2 << TZ;
343 ITState.Mask = NewMask;
348 void discardImplicitITBlock() {
349 assert(inImplicitITBlock());
350 assert(ITState.CurPosition == 1);
351 ITState.CurPosition = ~0U;
356 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
362 void invertCurrentITCondition() {
363 if (ITState.CurPosition == 1) {
366 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
371 bool isITBlockFull() {
372 return inITBlock() && (ITState.Mask & 1);
378 assert(inImplicitITBlock());
383 unsigned NewMask = 0;
385 NewMask |= ITState.Mask & (0xE << TZ);
387 NewMask |= (
Cond != ITState.Cond) << TZ;
389 NewMask |= 1 << (TZ - 1);
390 ITState.Mask = NewMask;
394 void startImplicitITBlock() {
398 ITState.CurPosition = 1;
399 ITState.IsExplicit =
false;
410 ITState.CurPosition = 0;
411 ITState.IsExplicit =
true;
416 unsigned CurPosition;
418 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
419 void forwardVPTPosition() {
420 if (!inVPTBlock())
return;
422 if (++VPTState.CurPosition == 5 - TZ)
423 VPTState.CurPosition = ~0U;
439 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
440 bool IsARPop =
false);
442 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
447 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
448 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
449 bool AllowRAAC =
false,
450 bool AllowOutOfBoundReg =
false);
453 bool parseImmExpr(int64_t &Out);
456 unsigned &ShiftAmount);
457 bool parseLiteralValues(
unsigned Size,
SMLoc L);
458 bool parseDirectiveThumb(
SMLoc L);
459 bool parseDirectiveARM(
SMLoc L);
460 bool parseDirectiveThumbFunc(
SMLoc L);
461 bool parseDirectiveCode(
SMLoc L);
462 bool parseDirectiveSyntax(
SMLoc L);
464 bool parseDirectiveUnreq(
SMLoc L);
465 bool parseDirectiveArch(
SMLoc L);
466 bool parseDirectiveEabiAttr(
SMLoc L);
467 bool parseDirectiveCPU(
SMLoc L);
468 bool parseDirectiveFPU(
SMLoc L);
469 bool parseDirectiveFnStart(
SMLoc L);
470 bool parseDirectiveFnEnd(
SMLoc L);
471 bool parseDirectiveCantUnwind(
SMLoc L);
472 bool parseDirectivePersonality(
SMLoc L);
473 bool parseDirectiveHandlerData(
SMLoc L);
474 bool parseDirectiveSetFP(
SMLoc L);
475 bool parseDirectivePad(
SMLoc L);
476 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
477 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
478 bool parseDirectiveLtorg(
SMLoc L);
479 bool parseDirectiveEven(
SMLoc L);
480 bool parseDirectivePersonalityIndex(
SMLoc L);
481 bool parseDirectiveUnwindRaw(
SMLoc L);
482 bool parseDirectiveTLSDescSeq(
SMLoc L);
483 bool parseDirectiveMovSP(
SMLoc L);
484 bool parseDirectiveObjectArch(
SMLoc L);
485 bool parseDirectiveArchExtension(
SMLoc L);
486 bool parseDirectiveAlign(
SMLoc L);
487 bool parseDirectiveThumbSet(
SMLoc L);
489 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
490 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
491 bool parseDirectiveSEHSaveSP(
SMLoc L);
492 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
493 bool parseDirectiveSEHSaveLR(
SMLoc L);
494 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
495 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
496 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
497 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
498 bool parseDirectiveSEHCustom(
SMLoc L);
500 std::unique_ptr<ARMOperand> defaultCondCodeOp();
501 std::unique_ptr<ARMOperand> defaultCCOutOp();
502 std::unique_ptr<ARMOperand> defaultVPTPredOp();
508 bool &CarrySetting,
unsigned &ProcessorIMod,
511 StringRef FullInst,
bool &CanAcceptCarrySet,
512 bool &CanAcceptPredicationCode,
513 bool &CanAcceptVPTPredicationCode);
516 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
519 unsigned MnemonicOpsEndInd);
522 unsigned MnemonicOpsEndInd);
529 bool isThumbOne()
const {
533 bool isThumbTwo()
const {
537 bool hasThumb()
const {
541 bool hasThumb2()
const {
545 bool hasV6Ops()
const {
549 bool hasV6T2Ops()
const {
553 bool hasV6MOps()
const {
557 bool hasV7Ops()
const {
561 bool hasV8Ops()
const {
565 bool hasV8MBaseline()
const {
569 bool hasV8MMainline()
const {
572 bool hasV8_1MMainline()
const {
575 bool hasMVEFloat()
const {
578 bool hasCDE()
const {
581 bool has8MSecExt()
const {
585 bool hasARM()
const {
589 bool hasDSP()
const {
593 bool hasD32()
const {
597 bool hasV8_1aOps()
const {
601 bool hasRAS()
const {
607 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
611 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
613 bool isMClass()
const {
620#define GET_ASSEMBLER_HEADER
621#include "ARMGenAsmMatcher.inc"
661 unsigned MnemonicOpsEndInd);
664 bool shouldOmitVectorPredicateOperand(
StringRef Mnemonic,
666 unsigned MnemonicOpsEndInd);
667 bool isITBlockTerminator(
MCInst &Inst)
const;
670 unsigned MnemonicOpsEndInd);
672 bool ARMMode,
bool Writeback,
673 unsigned MnemonicOpsEndInd);
676 enum ARMMatchResultTy {
678 Match_RequiresNotITBlock,
680 Match_RequiresThumb2,
682 Match_RequiresFlagSetting,
683#define GET_OPERAND_DIAGNOSTIC_TYPES
684#include "ARMGenAsmMatcher.inc"
701 getTargetStreamer().emitTargetAttributes(STI);
704 ITState.CurPosition = ~0
U;
706 VPTState.CurPosition = ~0
U;
708 NextSymbolIsThumb =
false;
714 SMLoc &EndLoc)
override;
720 unsigned Kind)
override;
729 bool MatchingInlineAsm)
override;
732 bool MatchingInlineAsm,
bool &EmitInITBlock,
735 struct NearMissMessage {
740 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
755 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
756 return MII.get(Opcode);
762 unsigned getDRegFromQReg(
unsigned QReg)
const {
763 return MRI->getSubReg(QReg, ARM::dsub_0);
782 k_InstSyncBarrierOpt,
783 k_TraceSyncBarrierOpt,
792 k_RegisterListWithAPSR,
795 k_FPSRegisterListWithVPR,
796 k_FPDRegisterListWithVPR,
798 k_VectorListAllLanes,
805 k_ConstantPoolImmediate,
806 k_BitfieldDescriptor,
810 SMLoc StartLoc, EndLoc, AlignmentLoc;
813 ARMAsmParser *Parser;
827 struct CoprocOptionOp {
869 struct VectorListOp {
876 struct VectorIndexOp {
890 unsigned OffsetRegNum;
895 unsigned isNegative : 1;
898 struct PostIdxRegOp {
905 struct ShifterImmOp {
910 struct RegShiftedRegOp {
917 struct RegShiftedImmOp {
941 struct CoprocOptionOp CoprocOption;
942 struct MBOptOp MBOpt;
943 struct ISBOptOp ISBOpt;
944 struct TSBOptOp TSBOpt;
945 struct ITMaskOp ITMask;
947 struct MMaskOp MMask;
948 struct BankedRegOp BankedReg;
951 struct VectorListOp VectorList;
952 struct VectorIndexOp VectorIndex;
955 struct PostIdxRegOp PostIdxReg;
956 struct ShifterImmOp ShifterImm;
957 struct RegShiftedRegOp RegShiftedReg;
958 struct RegShiftedImmOp RegShiftedImm;
959 struct RotImmOp RotImm;
960 struct ModImmOp ModImm;
965 ARMOperand(KindTy K, ARMAsmParser &Parser) :
Kind(
K), Parser(&Parser) {}
978 SMLoc getAlignmentLoc()
const {
979 assert(Kind == k_Memory &&
"Invalid access!");
984 assert(Kind == k_CondCode &&
"Invalid access!");
989 assert(isVPTPred() &&
"Invalid access!");
993 unsigned getCoproc()
const {
994 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
999 assert(Kind == k_Token &&
"Invalid access!");
1004 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1009 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1010 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1011 Kind == k_FPSRegisterListWithVPR ||
1012 Kind == k_FPDRegisterListWithVPR) &&
1017 const MCExpr *getImm()
const {
1022 const MCExpr *getConstantPoolImm()
const {
1023 assert(isConstantPoolImm() &&
"Invalid access!");
1027 unsigned getVectorIndex()
const {
1028 assert(Kind == k_VectorIndex &&
"Invalid access!");
1029 return VectorIndex.Val;
1033 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1038 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1043 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1048 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1052 unsigned getMSRMask()
const {
1053 assert(Kind == k_MSRMask &&
"Invalid access!");
1057 unsigned getBankedReg()
const {
1058 assert(Kind == k_BankedReg &&
"Invalid access!");
1059 return BankedReg.Val;
1062 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1063 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1064 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1066 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1067 bool isCCOut()
const {
return Kind == k_CCOut; }
1068 bool isITMask()
const {
return Kind == k_ITCondMask; }
1069 bool isITCondCode()
const {
return Kind == k_CondCode; }
1070 bool isImm()
const override {
1071 return Kind == k_Immediate;
1074 bool isARMBranchTarget()
const {
1075 if (!
isImm())
return false;
1077 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1078 return CE->getValue() % 4 == 0;
1083 bool isThumbBranchTarget()
const {
1084 if (!
isImm())
return false;
1086 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
1087 return CE->getValue() % 2 == 0;
1093 template<
unsigned w
idth,
unsigned scale>
1094 bool isUnsignedOffset()
const {
1095 if (!
isImm())
return false;
1096 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1098 int64_t Val =
CE->getValue();
1100 int64_t
Max =
Align * ((1LL << width) - 1);
1101 return ((Val %
Align) == 0) && (Val >= 0) && (Val <= Max);
1108 template<
unsigned w
idth,
unsigned scale>
1109 bool isSignedOffset()
const {
1110 if (!
isImm())
return false;
1111 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1113 int64_t Val =
CE->getValue();
1115 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1116 int64_t Min = -
Align * (1LL << (width-1));
1117 return ((Val %
Align) == 0) && (Val >= Min) && (Val <= Max);
1124 bool isLEOffset()
const {
1125 if (!
isImm())
return false;
1126 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1128 int64_t Val =
CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1138 bool isThumbMemPC()
const {
1141 if (isa<MCSymbolRefExpr>(
Imm.Val))
return true;
1143 if (!CE)
return false;
1144 Val =
CE->getValue();
1146 else if (isGPRMem()) {
1147 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
1148 if(
Memory.BaseRegNum != ARM::PC)
return false;
1149 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
1150 Val =
CE->getValue();
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1158 bool isFPImm()
const {
1159 if (!
isImm())
return false;
1161 if (!CE)
return false;
1166 template<
int64_t N,
int64_t M>
1167 bool isImmediate()
const {
1168 if (!
isImm())
return false;
1170 if (!CE)
return false;
1171 int64_t
Value =
CE->getValue();
1175 template<
int64_t N,
int64_t M>
1176 bool isImmediateS4()
const {
1177 if (!
isImm())
return false;
1179 if (!CE)
return false;
1180 int64_t
Value =
CE->getValue();
1183 template<
int64_t N,
int64_t M>
1184 bool isImmediateS2()
const {
1185 if (!
isImm())
return false;
1187 if (!CE)
return false;
1188 int64_t
Value =
CE->getValue();
1191 bool isFBits16()
const {
1192 return isImmediate<0, 17>();
1194 bool isFBits32()
const {
1195 return isImmediate<1, 33>();
1197 bool isImm8s4()
const {
1198 return isImmediateS4<-1020, 1020>();
1200 bool isImm7s4()
const {
1201 return isImmediateS4<-508, 508>();
1203 bool isImm7Shift0()
const {
1204 return isImmediate<-127, 127>();
1206 bool isImm7Shift1()
const {
1207 return isImmediateS2<-255, 255>();
1209 bool isImm7Shift2()
const {
1210 return isImmediateS4<-511, 511>();
1212 bool isImm7()
const {
1213 return isImmediate<-127, 127>();
1215 bool isImm0_1020s4()
const {
1216 return isImmediateS4<0, 1020>();
1218 bool isImm0_508s4()
const {
1219 return isImmediateS4<0, 508>();
1221 bool isImm0_508s4Neg()
const {
1222 if (!
isImm())
return false;
1224 if (!CE)
return false;
1225 int64_t
Value = -
CE->getValue();
1230 bool isImm0_4095Neg()
const {
1231 if (!
isImm())
return false;
1233 if (!CE)
return false;
1238 if ((
CE->getValue() >> 32) > 0)
return false;
1243 bool isImm0_7()
const {
1244 return isImmediate<0, 7>();
1247 bool isImm1_16()
const {
1248 return isImmediate<1, 16>();
1251 bool isImm1_32()
const {
1252 return isImmediate<1, 32>();
1255 bool isImm8_255()
const {
1256 return isImmediate<8, 255>();
1259 bool isImm0_255Expr()
const {
1267 int64_t
Value =
CE->getValue();
1268 return isUInt<8>(
Value);
1271 bool isImm256_65535Expr()
const {
1272 if (!
isImm())
return false;
1276 if (!CE)
return true;
1277 int64_t
Value =
CE->getValue();
1281 bool isImm0_65535Expr()
const {
1282 if (!
isImm())
return false;
1286 if (!CE)
return true;
1287 int64_t
Value =
CE->getValue();
1291 bool isImm24bit()
const {
1292 return isImmediate<0, 0xffffff + 1>();
1295 bool isImmThumbSR()
const {
1296 return isImmediate<1, 33>();
1299 bool isPKHLSLImm()
const {
1300 return isImmediate<0, 32>();
1303 bool isPKHASRImm()
const {
1304 return isImmediate<0, 33>();
1307 bool isAdrLabel()
const {
1310 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1314 if (!
isImm())
return false;
1316 if (!CE)
return false;
1317 int64_t
Value =
CE->getValue();
1322 bool isT2SOImm()
const {
1325 if (
isImm() && !isa<MCConstantExpr>(getImm())) {
1328 const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
1332 if (!
isImm())
return false;
1334 if (!CE)
return false;
1335 int64_t
Value =
CE->getValue();
1339 bool isT2SOImmNot()
const {
1340 if (!
isImm())
return false;
1342 if (!CE)
return false;
1343 int64_t
Value =
CE->getValue();
1348 bool isT2SOImmNeg()
const {
1349 if (!
isImm())
return false;
1351 if (!CE)
return false;
1352 int64_t
Value =
CE->getValue();
1358 bool isSetEndImm()
const {
1359 if (!
isImm())
return false;
1361 if (!CE)
return false;
1362 int64_t
Value =
CE->getValue();
1366 bool isReg()
const override {
return Kind == k_Register; }
1367 bool isRegList()
const {
return Kind == k_RegisterList; }
1368 bool isRegListWithAPSR()
const {
1369 return Kind == k_RegisterListWithAPSR ||
Kind == k_RegisterList;
1371 bool isDReg()
const {
1373 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
Reg.RegNum);
1375 bool isQReg()
const {
1377 ARMMCRegisterClasses[ARM::QPRRegClassID].contains(
Reg.RegNum);
1379 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1380 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1381 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1382 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1383 bool isToken()
const override {
return Kind == k_Token; }
1384 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1385 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1386 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1387 bool isMem()
const override {
1388 return isGPRMem() || isMVEMem();
1390 bool isMVEMem()
const {
1391 if (Kind != k_Memory)
1394 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum) &&
1395 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
Memory.BaseRegNum))
1397 if (
Memory.OffsetRegNum &&
1398 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1403 bool isGPRMem()
const {
1404 if (Kind != k_Memory)
1407 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum))
1409 if (
Memory.OffsetRegNum &&
1410 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.OffsetRegNum))
1414 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1415 bool isRegShiftedReg()
const {
1416 return Kind == k_ShiftedRegister &&
1417 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1418 RegShiftedReg.SrcReg) &&
1419 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1420 RegShiftedReg.ShiftReg);
1422 bool isRegShiftedImm()
const {
1423 return Kind == k_ShiftedImmediate &&
1424 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1425 RegShiftedImm.SrcReg);
1427 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1429 template<
unsigned Min,
unsigned Max>
1430 bool isPowerTwoInRange()
const {
1431 if (!
isImm())
return false;
1433 if (!CE)
return false;
1434 int64_t
Value =
CE->getValue();
1438 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1440 bool isModImmNot()
const {
1441 if (!
isImm())
return false;
1443 if (!CE)
return false;
1444 int64_t
Value =
CE->getValue();
1448 bool isModImmNeg()
const {
1449 if (!
isImm())
return false;
1451 if (!CE)
return false;
1452 int64_t
Value =
CE->getValue();
1457 bool isThumbModImmNeg1_7()
const {
1458 if (!
isImm())
return false;
1460 if (!CE)
return false;
1461 int32_t
Value = -(int32_t)
CE->getValue();
1465 bool isThumbModImmNeg8_255()
const {
1466 if (!
isImm())
return false;
1468 if (!CE)
return false;
1469 int32_t
Value = -(int32_t)
CE->getValue();
1473 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1474 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1475 bool isPostIdxRegShifted()
const {
1476 return Kind == k_PostIndexRegister &&
1477 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1479 bool isPostIdxReg()
const {
1482 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1486 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1487 (alignOK ||
Memory.Alignment == Alignment);
1489 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1493 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1498 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1499 (alignOK ||
Memory.Alignment == Alignment);
1501 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1505 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].
contains(
1510 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1511 (alignOK ||
Memory.Alignment == Alignment);
1513 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1517 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].
contains(
1522 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1523 (alignOK ||
Memory.Alignment == Alignment);
1525 bool isMemPCRelImm12()
const {
1526 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1529 if (
Memory.BaseRegNum != ARM::PC)
1532 if (!
Memory.OffsetImm)
return true;
1533 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1534 int64_t Val =
CE->getValue();
1535 return (Val > -4096 && Val < 4096) ||
1536 (Val == std::numeric_limits<int32_t>::min());
1541 bool isAlignedMemory()
const {
1542 return isMemNoOffset(
true);
1545 bool isAlignedMemoryNone()
const {
1546 return isMemNoOffset(
false, 0);
1549 bool isDupAlignedMemoryNone()
const {
1550 return isMemNoOffset(
false, 0);
1553 bool isAlignedMemory16()
const {
1554 if (isMemNoOffset(
false, 2))
1556 return isMemNoOffset(
false, 0);
1559 bool isDupAlignedMemory16()
const {
1560 if (isMemNoOffset(
false, 2))
1562 return isMemNoOffset(
false, 0);
1565 bool isAlignedMemory32()
const {
1566 if (isMemNoOffset(
false, 4))
1568 return isMemNoOffset(
false, 0);
1571 bool isDupAlignedMemory32()
const {
1572 if (isMemNoOffset(
false, 4))
1574 return isMemNoOffset(
false, 0);
1577 bool isAlignedMemory64()
const {
1578 if (isMemNoOffset(
false, 8))
1580 return isMemNoOffset(
false, 0);
1583 bool isDupAlignedMemory64()
const {
1584 if (isMemNoOffset(
false, 8))
1586 return isMemNoOffset(
false, 0);
1589 bool isAlignedMemory64or128()
const {
1590 if (isMemNoOffset(
false, 8))
1592 if (isMemNoOffset(
false, 16))
1594 return isMemNoOffset(
false, 0);
1597 bool isDupAlignedMemory64or128()
const {
1598 if (isMemNoOffset(
false, 8))
1600 if (isMemNoOffset(
false, 16))
1602 return isMemNoOffset(
false, 0);
1605 bool isAlignedMemory64or128or256()
const {
1606 if (isMemNoOffset(
false, 8))
1608 if (isMemNoOffset(
false, 16))
1610 if (isMemNoOffset(
false, 32))
1612 return isMemNoOffset(
false, 0);
1615 bool isAddrMode2()
const {
1616 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1618 if (
Memory.OffsetRegNum)
return true;
1620 if (!
Memory.OffsetImm)
return true;
1621 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1622 int64_t Val =
CE->getValue();
1623 return Val > -4096 && Val < 4096;
1628 bool isAM2OffsetImm()
const {
1629 if (!
isImm())
return false;
1632 if (!CE)
return false;
1633 int64_t Val =
CE->getValue();
1634 return (Val == std::numeric_limits<int32_t>::min()) ||
1635 (Val > -4096 && Val < 4096);
1638 bool isAddrMode3()
const {
1642 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1644 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1648 if (
Memory.OffsetRegNum)
return true;
1650 if (!
Memory.OffsetImm)
return true;
1651 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1652 int64_t Val =
CE->getValue();
1655 return (Val > -256 && Val < 256) ||
1656 Val == std::numeric_limits<int32_t>::min();
1661 bool isAM3Offset()
const {
1668 if (!CE)
return false;
1669 int64_t Val =
CE->getValue();
1671 return (Val > -256 && Val < 256) ||
1672 Val == std::numeric_limits<int32_t>::min();
1675 bool isAddrMode5()
const {
1679 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1681 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1683 if (
Memory.OffsetRegNum)
return false;
1685 if (!
Memory.OffsetImm)
return true;
1686 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1687 int64_t Val =
CE->getValue();
1688 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1689 Val == std::numeric_limits<int32_t>::min();
1694 bool isAddrMode5FP16()
const {
1698 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1700 if (!isGPRMem() ||
Memory.Alignment != 0)
return false;
1702 if (
Memory.OffsetRegNum)
return false;
1704 if (!
Memory.OffsetImm)
return true;
1705 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1706 int64_t Val =
CE->getValue();
1707 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1708 Val == std::numeric_limits<int32_t>::min();
1713 bool isMemTBB()
const {
1714 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1720 bool isMemTBH()
const {
1721 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1728 bool isMemRegOffset()
const {
1729 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.Alignment != 0)
1734 bool isT2MemRegOffset()
const {
1735 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1746 bool isMemThumbRR()
const {
1749 if (!isGPRMem() || !
Memory.OffsetRegNum ||
Memory.isNegative ||
1756 bool isMemThumbRIs4()
const {
1757 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1761 if (!
Memory.OffsetImm)
return true;
1762 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1763 int64_t Val =
CE->getValue();
1764 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1769 bool isMemThumbRIs2()
const {
1770 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1774 if (!
Memory.OffsetImm)
return true;
1775 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1776 int64_t Val =
CE->getValue();
1777 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1782 bool isMemThumbRIs1()
const {
1783 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1787 if (!
Memory.OffsetImm)
return true;
1788 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1789 int64_t Val =
CE->getValue();
1790 return Val >= 0 && Val <= 31;
1795 bool isMemThumbSPI()
const {
1796 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
1800 if (!
Memory.OffsetImm)
return true;
1801 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1802 int64_t Val =
CE->getValue();
1803 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1808 bool isMemImm8s4Offset()
const {
1812 if (
isImm() && !isa<MCConstantExpr>(getImm()))
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();
1821 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1822 Val == std::numeric_limits<int32_t>::min();
1827 bool isMemImm7s4Offset()
const {
1831 if (
isImm() && !isa<MCConstantExpr>(getImm()))
1833 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1834 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1838 if (!
Memory.OffsetImm)
return true;
1839 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1840 int64_t Val =
CE->getValue();
1842 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1847 bool isMemImm0_1020s4Offset()
const {
1848 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1851 if (!
Memory.OffsetImm)
return true;
1852 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1853 int64_t Val =
CE->getValue();
1854 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1859 bool isMemImm8Offset()
const {
1860 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1863 if (
Memory.BaseRegNum == ARM::PC)
return false;
1865 if (!
Memory.OffsetImm)
return true;
1866 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1867 int64_t Val =
CE->getValue();
1868 return (Val == std::numeric_limits<int32_t>::min()) ||
1869 (Val > -256 && Val < 256);
1874 template<
unsigned Bits,
unsigned RegClassID>
1875 bool isMemImm7ShiftedOffset()
const {
1876 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0 ||
1877 !ARMMCRegisterClasses[RegClassID].contains(
Memory.BaseRegNum))
1883 if (!
Memory.OffsetImm)
return true;
1884 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1885 int64_t Val =
CE->getValue();
1889 if (Val == INT32_MIN)
1892 unsigned Divisor = 1U <<
Bits;
1895 if (Val % Divisor != 0)
1900 return (Val >= -127 && Val <= 127);
1905 template <
int shift>
bool isMemRegRQOffset()
const {
1906 if (!isMVEMem() ||
Memory.OffsetImm !=
nullptr ||
Memory.Alignment != 0)
1909 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1912 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1926 template <
int shift>
bool isMemRegQOffset()
const {
1927 if (!isMVEMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1930 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1936 static_assert(shift < 56,
1937 "Such that we dont shift by a value higher than 62");
1938 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1939 int64_t Val =
CE->getValue();
1942 if ((Val & ((1U << shift) - 1)) != 0)
1948 int64_t
Range = (1U << (7 + shift)) - 1;
1949 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1954 bool isMemPosImm8Offset()
const {
1955 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1958 if (!
Memory.OffsetImm)
return true;
1959 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1960 int64_t Val =
CE->getValue();
1961 return Val >= 0 && Val < 256;
1966 bool isMemNegImm8Offset()
const {
1967 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1970 if (
Memory.BaseRegNum == ARM::PC)
return false;
1972 if (!
Memory.OffsetImm)
return false;
1973 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1974 int64_t Val =
CE->getValue();
1975 return (Val == std::numeric_limits<int32_t>::min()) ||
1976 (Val > -256 && Val < 0);
1981 bool isMemUImm12Offset()
const {
1982 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
1985 if (!
Memory.OffsetImm)
return true;
1986 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
1987 int64_t Val =
CE->getValue();
1988 return (Val >= 0 && Val < 4096);
1993 bool isMemImm12Offset()
const {
1998 if (
isImm() && !isa<MCConstantExpr>(getImm()))
2001 if (!isGPRMem() ||
Memory.OffsetRegNum != 0 ||
Memory.Alignment != 0)
2004 if (!
Memory.OffsetImm)
return true;
2005 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
2006 int64_t Val =
CE->getValue();
2007 return (Val > -4096 && Val < 4096) ||
2008 (Val == std::numeric_limits<int32_t>::min());
2015 bool isConstPoolAsmImm()
const {
2018 return (isConstantPoolImm());
2021 bool isPostIdxImm8()
const {
2022 if (!
isImm())
return false;
2024 if (!CE)
return false;
2025 int64_t Val =
CE->getValue();
2026 return (Val > -256 && Val < 256) ||
2027 (Val == std::numeric_limits<int32_t>::min());
2030 bool isPostIdxImm8s4()
const {
2031 if (!
isImm())
return false;
2033 if (!CE)
return false;
2034 int64_t Val =
CE->getValue();
2035 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2036 (Val == std::numeric_limits<int32_t>::min());
2039 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2040 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2041 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2044 bool isAnyVectorList()
const {
2045 return Kind == k_VectorList ||
Kind == k_VectorListAllLanes ||
2046 Kind == k_VectorListIndexed;
2049 bool isVectorList()
const {
return Kind == k_VectorList; }
2051 bool isSingleSpacedVectorList()
const {
2052 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2055 bool isDoubleSpacedVectorList()
const {
2056 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2059 bool isVecListOneD()
const {
2061 if (isDReg() && !Parser->hasMVE())
2063 if (!isSingleSpacedVectorList())
return false;
2064 return VectorList.Count == 1;
2067 bool isVecListTwoMQ()
const {
2068 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2069 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2073 bool isVecListDPair()
const {
2076 if (isQReg() && !Parser->hasMVE())
2078 if (!isSingleSpacedVectorList())
return false;
2079 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2083 bool isVecListThreeD()
const {
2084 if (!isSingleSpacedVectorList())
return false;
2085 return VectorList.Count == 3;
2088 bool isVecListFourD()
const {
2089 if (!isSingleSpacedVectorList())
return false;
2090 return VectorList.Count == 4;
2093 bool isVecListDPairSpaced()
const {
2094 if (Kind != k_VectorList)
return false;
2095 if (isSingleSpacedVectorList())
return false;
2096 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2100 bool isVecListThreeQ()
const {
2101 if (!isDoubleSpacedVectorList())
return false;
2102 return VectorList.Count == 3;
2105 bool isVecListFourQ()
const {
2106 if (!isDoubleSpacedVectorList())
return false;
2107 return VectorList.Count == 4;
2110 bool isVecListFourMQ()
const {
2111 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2112 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2116 bool isSingleSpacedVectorAllLanes()
const {
2117 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2120 bool isDoubleSpacedVectorAllLanes()
const {
2121 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2124 bool isVecListOneDAllLanes()
const {
2125 if (!isSingleSpacedVectorAllLanes())
return false;
2126 return VectorList.Count == 1;
2129 bool isVecListDPairAllLanes()
const {
2130 if (!isSingleSpacedVectorAllLanes())
return false;
2131 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2135 bool isVecListDPairSpacedAllLanes()
const {
2136 if (!isDoubleSpacedVectorAllLanes())
return false;
2137 return VectorList.Count == 2;
2140 bool isVecListThreeDAllLanes()
const {
2141 if (!isSingleSpacedVectorAllLanes())
return false;
2142 return VectorList.Count == 3;
2145 bool isVecListThreeQAllLanes()
const {
2146 if (!isDoubleSpacedVectorAllLanes())
return false;
2147 return VectorList.Count == 3;
2150 bool isVecListFourDAllLanes()
const {
2151 if (!isSingleSpacedVectorAllLanes())
return false;
2152 return VectorList.Count == 4;
2155 bool isVecListFourQAllLanes()
const {
2156 if (!isDoubleSpacedVectorAllLanes())
return false;
2157 return VectorList.Count == 4;
2160 bool isSingleSpacedVectorIndexed()
const {
2161 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2164 bool isDoubleSpacedVectorIndexed()
const {
2165 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2168 bool isVecListOneDByteIndexed()
const {
2169 if (!isSingleSpacedVectorIndexed())
return false;
2170 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2173 bool isVecListOneDHWordIndexed()
const {
2174 if (!isSingleSpacedVectorIndexed())
return false;
2175 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2178 bool isVecListOneDWordIndexed()
const {
2179 if (!isSingleSpacedVectorIndexed())
return false;
2180 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2183 bool isVecListTwoDByteIndexed()
const {
2184 if (!isSingleSpacedVectorIndexed())
return false;
2185 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2188 bool isVecListTwoDHWordIndexed()
const {
2189 if (!isSingleSpacedVectorIndexed())
return false;
2190 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2193 bool isVecListTwoQWordIndexed()
const {
2194 if (!isDoubleSpacedVectorIndexed())
return false;
2195 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2198 bool isVecListTwoQHWordIndexed()
const {
2199 if (!isDoubleSpacedVectorIndexed())
return false;
2200 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2203 bool isVecListTwoDWordIndexed()
const {
2204 if (!isSingleSpacedVectorIndexed())
return false;
2205 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2208 bool isVecListThreeDByteIndexed()
const {
2209 if (!isSingleSpacedVectorIndexed())
return false;
2210 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2213 bool isVecListThreeDHWordIndexed()
const {
2214 if (!isSingleSpacedVectorIndexed())
return false;
2215 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2218 bool isVecListThreeQWordIndexed()
const {
2219 if (!isDoubleSpacedVectorIndexed())
return false;
2220 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2223 bool isVecListThreeQHWordIndexed()
const {
2224 if (!isDoubleSpacedVectorIndexed())
return false;
2225 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2228 bool isVecListThreeDWordIndexed()
const {
2229 if (!isSingleSpacedVectorIndexed())
return false;
2230 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2233 bool isVecListFourDByteIndexed()
const {
2234 if (!isSingleSpacedVectorIndexed())
return false;
2235 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2238 bool isVecListFourDHWordIndexed()
const {
2239 if (!isSingleSpacedVectorIndexed())
return false;
2240 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2243 bool isVecListFourQWordIndexed()
const {
2244 if (!isDoubleSpacedVectorIndexed())
return false;
2245 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2248 bool isVecListFourQHWordIndexed()
const {
2249 if (!isDoubleSpacedVectorIndexed())
return false;
2250 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2253 bool isVecListFourDWordIndexed()
const {
2254 if (!isSingleSpacedVectorIndexed())
return false;
2255 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2258 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2260 template <
unsigned NumLanes>
2261 bool isVectorIndexInRange()
const {
2262 if (Kind != k_VectorIndex)
return false;
2263 return VectorIndex.Val < NumLanes;
2266 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2267 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2268 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2269 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2271 template<
int PermittedValue,
int OtherPermittedValue>
2272 bool isMVEPairVectorIndex()
const {
2273 if (Kind != k_VectorIndex)
return false;
2274 return VectorIndex.Val == PermittedValue ||
2275 VectorIndex.Val == OtherPermittedValue;
2278 bool isNEONi8splat()
const {
2279 if (!
isImm())
return false;
2282 if (!CE)
return false;
2283 int64_t
Value =
CE->getValue();
2290 if (isNEONByteReplicate(2))
2296 if (!CE)
return false;
2297 unsigned Value =
CE->getValue();
2301 bool isNEONi16splatNot()
const {
2306 if (!CE)
return false;
2307 unsigned Value =
CE->getValue();
2312 if (isNEONByteReplicate(4))
2318 if (!CE)
return false;
2319 unsigned Value =
CE->getValue();
2323 bool isNEONi32splatNot()
const {
2328 if (!CE)
return false;
2329 unsigned Value =
CE->getValue();
2333 static bool isValidNEONi32vmovImm(int64_t
Value) {
2336 return ((
Value & 0xffffffffffffff00) == 0) ||
2337 ((
Value & 0xffffffffffff00ff) == 0) ||
2338 ((
Value & 0xffffffffff00ffff) == 0) ||
2339 ((
Value & 0xffffffff00ffffff) == 0) ||
2340 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2341 ((
Value & 0xffffffffff00ffff) == 0xffff);
2344 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2345 assert((Width == 8 || Width == 16 || Width == 32) &&
2346 "Invalid element width");
2347 assert(NumElems * Width <= 64 &&
"Invalid result width");
2355 int64_t
Value =
CE->getValue();
2363 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2365 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2368 for (
unsigned i = 1; i < NumElems; ++i) {
2370 if ((
Value & Mask) != Elem)
2376 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2377 return isNEONReplicate(8, NumBytes,
false);
2380 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2381 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2382 "Invalid source width");
2383 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2384 "Invalid destination width");
2385 assert(FromW < ToW &&
"ToW is not less than FromW");
2388 template<
unsigned FromW,
unsigned ToW>
2389 bool isNEONmovReplicate()
const {
2390 checkNeonReplicateArgs(FromW, ToW);
2391 if (ToW == 64 && isNEONi64splat())
2393 return isNEONReplicate(FromW, ToW / FromW,
false);
2396 template<
unsigned FromW,
unsigned ToW>
2397 bool isNEONinvReplicate()
const {
2398 checkNeonReplicateArgs(FromW, ToW);
2399 return isNEONReplicate(FromW, ToW / FromW,
true);
2402 bool isNEONi32vmov()
const {
2403 if (isNEONByteReplicate(4))
2411 return isValidNEONi32vmovImm(
CE->getValue());
2414 bool isNEONi32vmovNeg()
const {
2415 if (!
isImm())
return false;
2418 if (!CE)
return false;
2419 return isValidNEONi32vmovImm(~
CE->getValue());
2422 bool isNEONi64splat()
const {
2423 if (!
isImm())
return false;
2426 if (!CE)
return false;
2429 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2430 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2434 template<
int64_t Angle,
int64_t Remainder>
2435 bool isComplexRotation()
const {
2436 if (!
isImm())
return false;
2439 if (!CE)
return false;
2442 return (
Value % Angle == Remainder &&
Value <= 270);
2445 bool isMVELongShift()
const {
2446 if (!
isImm())
return false;
2449 if (!CE)
return false;
2454 bool isMveSaturateOp()
const {
2455 if (!
isImm())
return false;
2457 if (!CE)
return false;
2462 bool isITCondCodeNoAL()
const {
2463 if (!isITCondCode())
return false;
2468 bool isITCondCodeRestrictedI()
const {
2469 if (!isITCondCode())
2475 bool isITCondCodeRestrictedS()
const {
2476 if (!isITCondCode())
2483 bool isITCondCodeRestrictedU()
const {
2484 if (!isITCondCode())
2490 bool isITCondCodeRestrictedFP()
const {
2491 if (!isITCondCode())
2498 void setVecListDPair(
unsigned int DPair) {
2499 Kind = k_VectorList;
2500 VectorList.RegNum = DPair;
2501 VectorList.Count = 2;
2502 VectorList.isDoubleSpaced =
false;
2505 void setVecListOneD(
unsigned int DReg) {
2506 Kind = k_VectorList;
2507 VectorList.RegNum =
DReg;
2508 VectorList.Count = 1;
2509 VectorList.isDoubleSpaced =
false;
2516 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2522 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2523 assert(
N == 1 &&
"Invalid number of operands!");
2524 addExpr(Inst, getImm());
2527 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2528 assert(
N == 1 &&
"Invalid number of operands!");
2529 addExpr(Inst, getImm());
2532 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2533 assert(
N == 2 &&
"Invalid number of operands!");
2539 void addVPTPredNOperands(
MCInst &Inst,
unsigned N)
const {
2540 assert(
N == 3 &&
"Invalid number of operands!");
2542 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? 0: ARM::P0;
2547 void addVPTPredROperands(
MCInst &Inst,
unsigned N)
const {
2548 assert(
N == 4 &&
"Invalid number of operands!");
2549 addVPTPredNOperands(Inst,
N-1);
2555 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2556 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2558 "Inactive register in vpred_r is not tied to an output!");
2564 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
2565 assert(
N == 1 &&
"Invalid number of operands!");
2569 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
2570 assert(
N == 1 &&
"Invalid number of operands!");
2574 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
2575 assert(
N == 1 &&
"Invalid number of operands!");
2579 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
2580 assert(
N == 1 &&
"Invalid number of operands!");
2584 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2585 assert(
N == 1 &&
"Invalid number of operands!");
2589 void addITCondCodeInvOperands(
MCInst &Inst,
unsigned N)
const {
2590 assert(
N == 1 &&
"Invalid number of operands!");
2594 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
2595 assert(
N == 1 &&
"Invalid number of operands!");
2599 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
2600 assert(
N == 1 &&
"Invalid number of operands!");
2604 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
2605 assert(
N == 3 &&
"Invalid number of operands!");
2606 assert(isRegShiftedReg() &&
2607 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2614 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
2615 assert(
N == 2 &&
"Invalid number of operands!");
2616 assert(isRegShiftedImm() &&
2617 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2620 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2625 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
2626 assert(
N == 1 &&
"Invalid number of operands!");
2631 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
2632 assert(
N == 1 &&
"Invalid number of operands!");
2634 for (
unsigned Reg : RegList)
2638 void addRegListWithAPSROperands(
MCInst &Inst,
unsigned N)
const {
2639 assert(
N == 1 &&
"Invalid number of operands!");
2641 for (
unsigned Reg : RegList)
2645 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2646 addRegListOperands(Inst,
N);
2649 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2650 addRegListOperands(Inst,
N);
2653 void addFPSRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2654 addRegListOperands(Inst,
N);
2657 void addFPDRegListWithVPROperands(
MCInst &Inst,
unsigned N)
const {
2658 addRegListOperands(Inst,
N);
2661 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2662 assert(
N == 1 &&
"Invalid number of operands!");
2667 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2668 assert(
N == 1 &&
"Invalid number of operands!");
2672 return addImmOperands(Inst,
N);
2677 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2678 assert(
N == 1 &&
"Invalid number of operands!");
2684 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2685 assert(
N == 1 &&
"Invalid number of operands!");
2691 void addThumbModImmNeg8_255Operands(
MCInst &Inst,
unsigned N)
const {
2692 assert(
N == 1 &&
"Invalid number of operands!");
2698 void addThumbModImmNeg1_7Operands(
MCInst &Inst,
unsigned N)
const {
2699 assert(
N == 1 &&
"Invalid number of operands!");
2705 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2706 assert(
N == 1 &&
"Invalid number of operands!");
2712 (32 - (lsb + width)));
2716 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2717 assert(
N == 1 &&
"Invalid number of operands!");
2718 addExpr(Inst, getImm());
2721 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2722 assert(
N == 1 &&
"Invalid number of operands!");
2727 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2728 assert(
N == 1 &&
"Invalid number of operands!");
2733 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2734 assert(
N == 1 &&
"Invalid number of operands!");
2740 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2741 assert(
N == 1 &&
"Invalid number of operands!");
2748 void addImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
2749 assert(
N == 1 &&
"Invalid number of operands!");
2756 void addImm7Shift0Operands(
MCInst &Inst,
unsigned N)
const {
2757 assert(
N == 1 &&
"Invalid number of operands!");
2762 void addImm7Shift1Operands(
MCInst &Inst,
unsigned N)
const {
2763 assert(
N == 1 &&
"Invalid number of operands!");
2768 void addImm7Shift2Operands(
MCInst &Inst,
unsigned N)
const {
2769 assert(
N == 1 &&
"Invalid number of operands!");
2774 void addImm7Operands(
MCInst &Inst,
unsigned N)
const {
2775 assert(
N == 1 &&
"Invalid number of operands!");
2780 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2781 assert(
N == 1 &&
"Invalid number of operands!");
2788 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2789 assert(
N == 1 &&
"Invalid number of operands!");
2796 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2797 assert(
N == 1 &&
"Invalid number of operands!");
2804 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2805 assert(
N == 1 &&
"Invalid number of operands!");
2812 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2813 assert(
N == 1 &&
"Invalid number of operands!");
2820 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2821 assert(
N == 1 &&
"Invalid number of operands!");
2825 unsigned Imm =
CE->getValue();
2829 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2830 assert(
N == 1 &&
"Invalid number of operands!");
2834 int Val =
CE->getValue();
2838 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2839 assert(
N == 1 &&
"Invalid number of operands!");
2846 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2847 assert(
N == 1 &&
"Invalid number of operands!");
2854 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2855 assert(
N == 1 &&
"Invalid number of operands!");
2862 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2863 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2871 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2872 assert(
N == 1 &&
"Invalid number of operands!");
2884 assert(isGPRMem() &&
"Unknown value type!");
2885 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2886 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2892 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2893 assert(
N == 1 &&
"Invalid number of operands!");
2897 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2898 assert(
N == 1 &&
"Invalid number of operands!");
2902 void addTraceSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2903 assert(
N == 1 &&
"Invalid number of operands!");
2907 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2908 assert(
N == 1 &&
"Invalid number of operands!");
2912 void addMemNoOffsetT2Operands(
MCInst &Inst,
unsigned N)
const {
2913 assert(
N == 1 &&
"Invalid number of operands!");
2917 void addMemNoOffsetT2NoSpOperands(
MCInst &Inst,
unsigned N)
const {
2918 assert(
N == 1 &&
"Invalid number of operands!");
2922 void addMemNoOffsetTOperands(
MCInst &Inst,
unsigned N)
const {
2923 assert(
N == 1 &&
"Invalid number of operands!");
2927 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2928 assert(
N == 1 &&
"Invalid number of operands!");
2929 if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
2935 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2936 assert(
N == 1 &&
"Invalid number of operands!");
2941 if (!isa<MCConstantExpr>(getImm())) {
2947 int Val =
CE->getValue();
2951 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2952 assert(
N == 2 &&
"Invalid number of operands!");
2957 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2958 addAlignedMemoryOperands(Inst,
N);
2961 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2962 addAlignedMemoryOperands(Inst,
N);
2965 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2966 addAlignedMemoryOperands(Inst,
N);
2969 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2970 addAlignedMemoryOperands(Inst,
N);
2973 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2974 addAlignedMemoryOperands(Inst,
N);
2977 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2978 addAlignedMemoryOperands(Inst,
N);
2981 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2982 addAlignedMemoryOperands(Inst,
N);
2985 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2986 addAlignedMemoryOperands(Inst,
N);
2989 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2990 addAlignedMemoryOperands(Inst,
N);
2993 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2994 addAlignedMemoryOperands(Inst,
N);
2997 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2998 addAlignedMemoryOperands(Inst,
N);
3001 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
3002 assert(
N == 3 &&
"Invalid number of operands!");
3005 if (!
Memory.OffsetRegNum) {
3008 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3009 int32_t Val =
CE->getValue();
3012 if (Val == std::numeric_limits<int32_t>::min())
3030 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
3031 assert(
N == 2 &&
"Invalid number of operands!");
3033 assert(CE &&
"non-constant AM2OffsetImm operand!");
3034 int32_t Val =
CE->getValue();
3037 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3038 if (Val < 0) Val = -Val;
3044 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
3045 assert(
N == 3 &&
"Invalid number of operands!");
3058 if (!
Memory.OffsetRegNum) {
3061 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3062 int32_t Val =
CE->getValue();
3065 if (Val == std::numeric_limits<int32_t>::min())
3082 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3083 assert(
N == 2 &&
"Invalid number of operands!");
3084 if (Kind == k_PostIndexRegister) {
3094 int32_t Val =
CE->getValue();
3097 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3098 if (Val < 0) Val = -Val;
3104 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
3105 assert(
N == 2 &&
"Invalid number of operands!");
3118 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3120 int32_t Val =
CE->getValue() / 4;
3123 if (Val == std::numeric_limits<int32_t>::min())
3133 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
3134 assert(
N == 2 &&
"Invalid number of operands!");
3148 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm)) {
3149 int32_t Val =
CE->getValue() / 2;
3152 if (Val == std::numeric_limits<int32_t>::min())
3162 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3163 assert(
N == 2 &&
"Invalid number of operands!");
3174 addExpr(Inst,
Memory.OffsetImm);
3177 void addMemImm7s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3178 assert(
N == 2 &&
"Invalid number of operands!");
3189 addExpr(Inst,
Memory.OffsetImm);
3192 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3193 assert(
N == 2 &&
"Invalid number of operands!");
3197 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3204 void addMemImmOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3205 assert(
N == 2 &&
"Invalid number of operands!");
3207 addExpr(Inst,
Memory.OffsetImm);
3210 void addMemRegRQOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3211 assert(
N == 2 &&
"Invalid number of operands!");
3216 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3217 assert(
N == 2 &&
"Invalid number of operands!");
3220 addExpr(Inst, getImm());
3227 addExpr(Inst,
Memory.OffsetImm);
3230 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
3231 assert(
N == 2 &&
"Invalid number of operands!");
3234 addExpr(Inst, getImm());
3241 addExpr(Inst,
Memory.OffsetImm);
3244 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
3245 assert(
N == 1 &&
"Invalid number of operands!");
3248 addExpr(Inst, getConstantPoolImm());
3251 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
3252 assert(
N == 2 &&
"Invalid number of operands!");
3257 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
3258 assert(
N == 2 &&
"Invalid number of operands!");
3263 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3264 assert(
N == 3 &&
"Invalid number of operands!");
3273 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
3274 assert(
N == 3 &&
"Invalid number of operands!");
3280 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
3281 assert(
N == 2 &&
"Invalid number of operands!");
3286 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
3287 assert(
N == 2 &&
"Invalid number of operands!");
3291 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3298 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
3299 assert(
N == 2 &&
"Invalid number of operands!");
3303 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3309 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
3310 assert(
N == 2 &&
"Invalid number of operands!");
3312 addExpr(Inst,
Memory.OffsetImm);
3315 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
3316 assert(
N == 2 &&
"Invalid number of operands!");
3320 else if (
const auto *CE = dyn_cast<MCConstantExpr>(
Memory.OffsetImm))
3327 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
3328 assert(
N == 1 &&
"Invalid number of operands!");
3330 assert(CE &&
"non-constant post-idx-imm8 operand!");
3331 int Imm =
CE->getValue();
3332 bool isAdd =
Imm >= 0;
3333 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3338 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
3339 assert(
N == 1 &&
"Invalid number of operands!");
3341 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3342 int Imm =
CE->getValue();
3343 bool isAdd =
Imm >= 0;
3344 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3350 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
3351 assert(
N == 2 &&
"Invalid number of operands!");
3356 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
3357 assert(
N == 2 &&
"Invalid number of operands!");
3363 PostIdxReg.ShiftTy);
3367 void addPowerTwoOperands(
MCInst &Inst,
unsigned N)
const {
3368 assert(
N == 1 &&
"Invalid number of operands!");
3373 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
3374 assert(
N == 1 &&
"Invalid number of operands!");
3378 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
3379 assert(
N == 1 &&
"Invalid number of operands!");
3383 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
3384 assert(
N == 1 &&
"Invalid number of operands!");
3388 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
3389 assert(
N == 1 &&
"Invalid number of operands!");
3391 if (isAnyVectorList())
3393 else if (isDReg() && !Parser->hasMVE()) {
3395 }
else if (isQReg() && !Parser->hasMVE()) {
3396 auto DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3397 DPair = Parser->getMRI()->getMatchingSuperReg(
3398 DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3403 "attempted to add a vector list register with wrong type!");
3407 void addMVEVecListOperands(
MCInst &Inst,
unsigned N)
const {
3408 assert(
N == 1 &&
"Invalid number of operands!");
3424 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3426 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3427 : &ARMMCRegisterClasses[ARM::MQQQQPRRegClassID];
3430 for (
I = 0;
I <
E;
I++)
3433 assert(
I <
E &&
"Invalid vector list start register!");
3438 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
3439 assert(
N == 2 &&
"Invalid number of operands!");
3444 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
3445 assert(
N == 1 &&
"Invalid number of operands!");
3449 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
3450 assert(
N == 1 &&
"Invalid number of operands!");
3454 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
3455 assert(
N == 1 &&
"Invalid number of operands!");
3459 void addVectorIndex64Operands(
MCInst &Inst,
unsigned N)
const {
3460 assert(
N == 1 &&
"Invalid number of operands!");
3464 void addMVEVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3465 assert(
N == 1 &&
"Invalid number of operands!");
3469 void addMVEPairVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
3470 assert(
N == 1 &&
"Invalid number of operands!");
3474 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
3475 assert(
N == 1 &&
"Invalid number of operands!");
3482 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
3483 assert(
N == 1 &&
"Invalid number of operands!");
3486 unsigned Value =
CE->getValue();
3491 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3492 assert(
N == 1 &&
"Invalid number of operands!");
3495 unsigned Value =
CE->getValue();
3500 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
3501 assert(
N == 1 &&
"Invalid number of operands!");
3504 unsigned Value =
CE->getValue();
3509 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
3510 assert(
N == 1 &&
"Invalid number of operands!");
3513 unsigned Value =
CE->getValue();
3518 void addNEONi8ReplicateOperands(
MCInst &Inst,
bool Inv)
const {
3523 "All instructions that wants to replicate non-zero byte "
3524 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3525 unsigned Value =
CE->getValue();
3528 unsigned B =
Value & 0xff;
3533 void addNEONinvi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3534 assert(
N == 1 &&
"Invalid number of operands!");
3535 addNEONi8ReplicateOperands(Inst,
true);
3538 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3541 else if (
Value > 0xffff &&
Value <= 0xffffff)
3543 else if (
Value > 0xffffff)
3548 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
3549 assert(
N == 1 &&
"Invalid number of operands!");
3552 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3556 void addNEONvmovi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3557 assert(
N == 1 &&
"Invalid number of operands!");
3558 addNEONi8ReplicateOperands(Inst,
false);
3561 void addNEONvmovi16ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3562 assert(
N == 1 &&
"Invalid number of operands!");
3568 "All instructions that want to replicate non-zero half-word "
3569 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3571 unsigned Elem =
Value & 0xffff;
3573 Elem = (Elem >> 8) | 0x200;
3577 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
3578 assert(
N == 1 &&
"Invalid number of operands!");
3581 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3585 void addNEONvmovi32ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
3586 assert(
N == 1 &&
"Invalid number of operands!");
3592 "All instructions that want to replicate non-zero word "
3593 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3595 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3599 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
3600 assert(
N == 1 &&
"Invalid number of operands!");
3605 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3611 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
3612 assert(
N == 1 &&
"Invalid number of operands!");
3617 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
3618 assert(
N == 1 &&
"Invalid number of operands!");
3623 void addMveSaturateOperands(
MCInst &Inst,
unsigned N)
const {
3624 assert(
N == 1 &&
"Invalid number of operands!");
3626 unsigned Imm =
CE->getValue();
3627 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3633 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S,
3634 ARMAsmParser &Parser) {
3635 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3642 static std::unique_ptr<ARMOperand>
3644 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3652 ARMAsmParser &Parser) {
3653 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3660 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S,
3661 ARMAsmParser &Parser) {
3662 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3663 Op->Cop.Val = CopVal;
3669 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S,
3670 ARMAsmParser &Parser) {
3671 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3672 Op->Cop.Val = CopVal;
3678 static std::unique_ptr<ARMOperand>
3679 CreateCoprocOption(
unsigned Val,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3680 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3687 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S,
3688 ARMAsmParser &Parser) {
3689 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3690 Op->Reg.RegNum = RegNum;
3696 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S,
3697 ARMAsmParser &Parser) {
3698 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3699 Op->Tok.Data = Str.data();
3700 Op->Tok.Length = Str.size();
3706 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
3707 SMLoc E, ARMAsmParser &Parser) {
3708 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3709 Op->Reg.RegNum = RegNum;
3715 static std::unique_ptr<ARMOperand>
3717 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
SMLoc E,
3718 ARMAsmParser &Parser) {
3719 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3720 Op->RegShiftedReg.ShiftTy = ShTy;
3721 Op->RegShiftedReg.SrcReg = SrcReg;
3722 Op->RegShiftedReg.ShiftReg = ShiftReg;
3723 Op->RegShiftedReg.ShiftImm = ShiftImm;
3729 static std::unique_ptr<ARMOperand>
3732 ARMAsmParser &Parser) {
3733 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3734 Op->RegShiftedImm.ShiftTy = ShTy;
3735 Op->RegShiftedImm.SrcReg = SrcReg;
3736 Op->RegShiftedImm.ShiftImm = ShiftImm;
3742 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3744 ARMAsmParser &Parser) {
3745 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3746 Op->ShifterImm.isASR = isASR;
3747 Op->ShifterImm.Imm =
Imm;
3753 static std::unique_ptr<ARMOperand>
3754 CreateRotImm(
unsigned Imm,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3755 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3756 Op->RotImm.Imm =
Imm;
3762 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3764 ARMAsmParser &Parser) {
3765 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3767 Op->ModImm.Rot = Rot;
3773 static std::unique_ptr<ARMOperand>
3775 ARMAsmParser &Parser) {
3776 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3783 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3784 unsigned Width,
SMLoc S,
3786 ARMAsmParser &Parser) {
3787 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3788 Op->Bitfield.LSB = LSB;
3789 Op->Bitfield.Width = Width;
3795 static std::unique_ptr<ARMOperand>
3797 SMLoc StartLoc,
SMLoc EndLoc, ARMAsmParser &Parser) {
3798 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3799 KindTy
Kind = k_RegisterList;
3801 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
3802 Regs.front().second)) {
3803 if (Regs.back().second == ARM::VPR)
3804 Kind = k_FPDRegisterListWithVPR;
3806 Kind = k_DPRRegisterList;
3807 }
else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
3808 Regs.front().second)) {
3809 if (Regs.back().second == ARM::VPR)
3810 Kind = k_FPSRegisterListWithVPR;
3812 Kind = k_SPRRegisterList;
3815 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3816 Kind = k_RegisterListWithAPSR;
3820 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3821 for (
const auto &
P : Regs)
3822 Op->Registers.push_back(
P.second);
3824 Op->StartLoc = StartLoc;
3825 Op->EndLoc = EndLoc;
3829 static std::unique_ptr<ARMOperand>
3830 CreateVectorList(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
3832 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3833 Op->VectorList.RegNum = RegNum;
3834 Op->VectorList.Count = Count;
3835 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3841 static std::unique_ptr<ARMOperand>
3842 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
3844 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3845 Op->VectorList.RegNum = RegNum;
3846 Op->VectorList.Count = Count;
3847 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3853 static std::unique_ptr<ARMOperand>
3854 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
3856 ARMAsmParser &Parser) {
3857 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3858 Op->VectorList.RegNum = RegNum;
3859 Op->VectorList.Count = Count;
3860 Op->VectorList.LaneIndex =
Index;
3861 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3867 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx,
SMLoc S,
3869 ARMAsmParser &Parser) {
3870 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3871 Op->VectorIndex.Val =
Idx;
3877 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
3878 SMLoc E, ARMAsmParser &Parser) {
3879 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3886 static std::unique_ptr<ARMOperand>
3887 CreateMem(
unsigned BaseRegNum,
const MCExpr *OffsetImm,
unsigned OffsetRegNum,
3889 bool isNegative,
SMLoc S,
SMLoc E, ARMAsmParser &Parser,
3891 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3892 Op->Memory.BaseRegNum = BaseRegNum;
3893 Op->Memory.OffsetImm = OffsetImm;
3894 Op->Memory.OffsetRegNum = OffsetRegNum;
3895 Op->Memory.ShiftType = ShiftType;
3896 Op->Memory.ShiftImm = ShiftImm;
3897 Op->Memory.Alignment = Alignment;
3898 Op->Memory.isNegative = isNegative;
3901 Op->AlignmentLoc = AlignmentLoc;
3905 static std::unique_ptr<ARMOperand>
3907 unsigned ShiftImm,
SMLoc S,
SMLoc E, ARMAsmParser &Parser) {
3908 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3909 Op->PostIdxReg.RegNum = RegNum;
3910 Op->PostIdxReg.isAdd = isAdd;
3911 Op->PostIdxReg.ShiftTy = ShiftTy;
3912 Op->PostIdxReg.ShiftImm = ShiftImm;
3918 static std::unique_ptr<ARMOperand>
3920 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3921 Op->MBOpt.Val = Opt;
3927 static std::unique_ptr<ARMOperand>
3929 ARMAsmParser &Parser) {
3930 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3931 Op->ISBOpt.Val = Opt;
3937 static std::unique_ptr<ARMOperand>
3939 ARMAsmParser &Parser) {
3940 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3941 Op->TSBOpt.Val = Opt;
3947 static std::unique_ptr<ARMOperand>
3949 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3956 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S,
3957 ARMAsmParser &Parser) {
3958 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3959 Op->MMask.Val = MMask;
3965 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S,
3966 ARMAsmParser &Parser) {
3967 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3968 Op->BankedReg.Val =
Reg;
3995 case k_ITCondMask: {
3996 static const char *
const MaskStr[] = {
3997 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
3998 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
3999 "(t)",
"(tett)",
"(tet)",
"(tete)",
4000 "(te)",
"(teet)",
"(tee)",
"(teee)",
4002 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4003 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4007 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4010 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4012 case k_CoprocOption:
4013 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4016 OS <<
"<mask: " << getMSRMask() <<
">";
4019 OS <<
"<banked reg: " << getBankedReg() <<
">";
4024 case k_MemBarrierOpt:
4025 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4027 case k_InstSyncBarrierOpt:
4028 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4030 case k_TraceSyncBarrierOpt:
4031 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4038 OS <<
" offset-imm:" << *
Memory.OffsetImm;
4040 OS <<
" offset-reg:" << (
Memory.isNegative ?
"-" :
"")
4044 OS <<
" shift-imm:" <<
Memory.ShiftImm;
4047 OS <<
" alignment:" <<
Memory.Alignment;
4050 case k_PostIndexRegister:
4051 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4052 <<
RegName(PostIdxReg.RegNum);
4055 << PostIdxReg.ShiftImm;
4058 case k_ProcIFlags: {
4059 OS <<
"<ARM_PROC::";
4060 unsigned IFlags = getProcIFlags();
4061 for (
int i=2; i >= 0; --i)
4062 if (IFlags & (1 << i))
4070 case k_ShifterImmediate:
4071 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4072 <<
" #" << ShifterImm.Imm <<
">";
4074 case k_ShiftedRegister:
4075 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4077 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4079 case k_ShiftedImmediate:
4080 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4082 << RegShiftedImm.ShiftImm <<
">";
4084 case k_RotateImmediate:
4085 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4087 case k_ModifiedImmediate:
4088 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4089 << ModImm.Rot <<
")>";
4091 case k_ConstantPoolImmediate:
4092 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
4094 case k_BitfieldDescriptor:
4095 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4096 <<
", width: " <<
Bitfield.Width <<
">";
4098 case k_RegisterList:
4099 case k_RegisterListWithAPSR:
4100 case k_DPRRegisterList:
4101 case k_SPRRegisterList:
4102 case k_FPSRegisterListWithVPR:
4103 case k_FPDRegisterListWithVPR: {
4104 OS <<
"<register_list ";
4110 if (++
I <
E)
OS <<
", ";
4117 OS <<
"<vector_list " << VectorList.Count <<
" * "
4118 <<
RegName(VectorList.RegNum) <<
">";
4120 case k_VectorListAllLanes:
4121 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4122 <<
RegName(VectorList.RegNum) <<
">";
4124 case k_VectorListIndexed:
4125 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4126 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4129 OS <<
"'" << getToken() <<
"'";
4132 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4146 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4147 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4148 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4153 unsigned MnemonicOpsEndInd = 1;
4157 static_cast<ARMOperand &
>(*
Operands[0]).getToken() ==
"cps") {
4159 static_cast<ARMOperand &
>(*
Operands[1]).getImm()->getKind() ==
4161 (dyn_cast<MCConstantExpr>(
4162 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4164 dyn_cast<MCConstantExpr>(
4165 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4167 ++MnemonicOpsEndInd;
4171 bool RHSCondCode =
false;
4172 while (MnemonicOpsEndInd <
Operands.size()) {
4173 auto Op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
4175 if (
Op.isITMask()) {
4177 MnemonicOpsEndInd++;
4178 }
else if (
Op.isToken() &&
4182 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4183 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4189 MnemonicOpsEndInd++;
4192 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4193 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4194 MnemonicOpsEndInd++;
4198 return MnemonicOpsEndInd;
4203 const AsmToken &Tok = getParser().getTok();
4206 Reg = tryParseRegister();
4213 if (parseRegister(
Reg, StartLoc, EndLoc))
4221int ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4230 .
Case(
"r13", ARM::SP)
4231 .
Case(
"r14", ARM::LR)
4232 .
Case(
"r15", ARM::PC)
4233 .
Case(
"ip", ARM::R12)
4235 .
Case(
"a1", ARM::R0)
4236 .
Case(
"a2", ARM::R1)
4237 .
Case(
"a3", ARM::R2)
4238 .
Case(
"a4", ARM::R3)
4239 .
Case(
"v1", ARM::R4)
4240 .
Case(
"v2", ARM::R5)
4241 .
Case(
"v3", ARM::R6)
4242 .
Case(
"v4", ARM::R7)
4243 .
Case(
"v5", ARM::R8)
4244 .
Case(
"v6", ARM::R9)
4245 .
Case(
"v7", ARM::R10)
4246 .
Case(
"v8", ARM::R11)
4247 .
Case(
"sb", ARM::R9)
4248 .
Case(
"sl", ARM::R10)
4249 .
Case(
"fp", ARM::R11)
4258 if (Entry == RegisterReqs.
end())
4261 return Entry->getValue();
4265 if (!AllowOutOfBoundReg && !hasD32() && RegNum >=
ARM::D16 &&
4274std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4278 return std::nullopt;
4300 auto ShiftTyOpt = tryParseShiftToken();
4301 if (ShiftTyOpt == std::nullopt)
4303 auto ShiftTy = ShiftTyOpt.value();
4310 std::unique_ptr<ARMOperand> PrevOp(
4311 (ARMOperand *)
Operands.pop_back_val().release());
4312 if (!PrevOp->isReg())
4313 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4314 int SrcReg = PrevOp->getReg();
4330 const MCExpr *ShiftExpr =
nullptr;
4331 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4332 Error(ImmLoc,
"invalid immediate shift value");
4338 Error(ImmLoc,
"invalid immediate shift value");
4344 Imm =
CE->getValue();
4348 Error(ImmLoc,
"immediate shift value out of range");
4358 ShiftReg = tryParseRegister();
4359 if (ShiftReg == -1) {
4360 Error(L,
"expected immediate or register in shift operand");
4365 "expected immediate or register in shift operand");
4371 Operands.push_back(ARMOperand::CreateShiftedRegister(
4372 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *
this));
4374 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4390 int RegNo = tryParseRegister();
4395 ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc, *
this));
4400 ExclaimTok.
getLoc(), *
this));
4413 if (getParser().parseExpression(ImmVal))
4417 return TokError(
"immediate value expected for vector index");
4426 getContext(), *
this));
4444 if (
Name.size() < 2 ||
Name[0] != CoprocOp)
4448 switch (
Name.size()) {
4471 case '0':
return 10;
4472 case '1':
return 11;
4473 case '2':
return 12;
4474 case '3':
return 13;
4475 case '4':
return 14;
4476 case '5':
return 15;
4516 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4535 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4552 if (getParser().parseExpression(Expr))
4553 return Error(Loc,
"illegal expression");
4555 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4557 "coprocessor option must be an immediate in range [0, 255]");
4558 int Val =
CE->getValue();
4566 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4577 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4581 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4582 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4583 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4584 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4585 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4586 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4587 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4588 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4596 unsigned Enc,
unsigned Reg) {
4597 Regs.emplace_back(Enc,
Reg);
4598 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4599 if (J->first == Enc) {
4600 Regs.erase(J.base());
4612 bool AllowRAAC,
bool AllowOutOfBoundReg) {
4615 return TokError(
"Token is not a Left Curly Brace");
4622 int Reg = tryParseRegister();
4624 return Error(RegLoc,
"register expected");
4625 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4626 return Error(RegLoc,
"pseudo-register not allowed");
4633 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4634 Reg = getDRegFromQReg(
Reg);
4635 EReg =
MRI->getEncodingValue(
Reg);
4640 if (
Reg == ARM::RA_AUTH_CODE ||
4641 ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4642 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4643 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg))
4644 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4645 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
Reg))
4646 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4647 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4648 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4650 return Error(RegLoc,
"invalid register in register list");
4653 EReg =
MRI->getEncodingValue(
Reg);
4662 if (
Reg == ARM::RA_AUTH_CODE)
4663 return Error(RegLoc,
"pseudo-register not allowed");
4666 int EndReg = tryParseRegister(AllowOutOfBoundReg);
4668 return Error(AfterMinusLoc,
"register expected");
4669 if (EndReg == ARM::RA_AUTH_CODE)
4670 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4672 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4673 EndReg = getDRegFromQReg(EndReg) + 1;
4680 return Error(AfterMinusLoc,
"invalid register in register list");
4682 if (
MRI->getEncodingValue(
Reg) >
MRI->getEncodingValue(EndReg))
4683 return Error(AfterMinusLoc,
"bad range in register list");
4686 while (
Reg != EndReg) {
4688 EReg =
MRI->getEncodingValue(
Reg);
4692 ") in register list");
4701 Reg = tryParseRegister(AllowOutOfBoundReg);
4703 return Error(RegLoc,
"register expected");
4704 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4705 return Error(RegLoc,
"pseudo-register not allowed");
4707 bool isQReg =
false;
4708 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4709 Reg = getDRegFromQReg(
Reg);
4713 RC->
getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4714 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
Reg)) {
4717 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4719 if (
Reg == ARM::VPR &&
4720 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4721 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4722 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4723 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4724 EReg =
MRI->getEncodingValue(
Reg);
4727 ") in register list");
4732 if ((
Reg == ARM::RA_AUTH_CODE &&
4733 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
4735 return Error(RegLoc,
"invalid register in register list");