70#define DEBUG_TYPE "asm-parser"
77enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
80 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
81 cl::desc(
"Allow conditional instructions outside of an IT block"),
83 "Accept in both ISAs, emit implicit ITs in Thumb"),
85 "Warn in ARM, reject in Thumb"),
87 "Accept in ARM, reject in Thumb"),
88 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
89 "Warn in ARM, emit implicit ITs in Thumb")));
94enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
96static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
103 return (Mask >> (5 - Position) & 1);
112 Locs PersonalityLocs;
113 Locs PersonalityIndexLocs;
114 Locs HandlerDataLocs;
120 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
121 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
122 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
124 bool hasPersonality()
const {
125 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
128 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
129 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
130 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
131 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
132 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
137 void emitFnStartLocNotes()
const {
139 Parser.
Note(
Loc,
".fnstart was specified here");
142 void emitCantUnwindLocNotes()
const {
144 Parser.
Note(
Loc,
".cantunwind was specified here");
147 void emitHandlerDataLocNotes()
const {
149 Parser.
Note(
Loc,
".handlerdata was specified here");
152 void emitPersonalityLocNotes()
const {
154 PE = PersonalityLocs.end(),
155 PII = PersonalityIndexLocs.begin(),
156 PIE = PersonalityIndexLocs.end();
157 PI != PE || PII != PIE;) {
158 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
159 Parser.
Note(*PI++,
".personality was specified here");
160 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
161 Parser.
Note(*PII++,
".personalityindex was specified here");
164 "at the same location");
169 FnStartLocs = Locs();
170 CantUnwindLocs = Locs();
171 PersonalityLocs = Locs();
172 HandlerDataLocs = Locs();
173 PersonalityIndexLocs = Locs();
179class ARMMnemonicSets {
190 return CDE.
count(Mnemonic);
195 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
198 return CDEWithVPTSuffix.
count(Mnemonic);
203 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
213 bool isCDEDualRegInstr(
StringRef Mnemonic) {
216 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
217 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
218 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
223 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
224 "cx2",
"cx2a",
"cx2d",
"cx2da",
225 "cx3",
"cx3a",
"cx3d",
"cx3da", })
228 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
230 CDEWithVPTSuffix.
insert(Mnemonic);
231 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"t");
232 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"e");
242 assert(getParser().getStreamer().getTargetStreamer() &&
243 "do not have a target streamer");
251 bool NextSymbolIsThumb;
253 bool useImplicitITThumb()
const {
254 return ImplicitItMode == ImplicitItModeTy::Always ||
255 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
258 bool useImplicitITARM()
const {
259 return ImplicitItMode == ImplicitItModeTy::Always ||
260 ImplicitItMode == ImplicitItModeTy::ARMOnly;
275 unsigned CurPosition;
290 void onEndOfFile()
override {
291 flushPendingInstructions(getParser().getStreamer());
294 void flushPendingInstructions(
MCStreamer &Out)
override {
295 if (!inImplicitITBlock()) {
309 for (
const MCInst &Inst : PendingConditionalInsts) {
312 PendingConditionalInsts.clear();
316 ITState.CurPosition = ~0U;
319 bool inITBlock() {
return ITState.CurPosition != ~0U; }
320 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
321 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
323 bool lastInITBlock() {
327 void forwardITPosition() {
328 if (!inITBlock())
return;
333 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
334 ITState.CurPosition = ~0U;
338 void rewindImplicitITPosition() {
339 assert(inImplicitITBlock());
340 assert(ITState.CurPosition > 1);
341 ITState.CurPosition--;
343 unsigned NewMask = 0;
344 NewMask |= ITState.Mask & (0xC << TZ);
345 NewMask |= 0x2 << TZ;
346 ITState.Mask = NewMask;
351 void discardImplicitITBlock() {
352 assert(inImplicitITBlock());
353 assert(ITState.CurPosition == 1);
354 ITState.CurPosition = ~0U;
359 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
365 void invertCurrentITCondition() {
366 if (ITState.CurPosition == 1) {
369 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
374 bool isITBlockFull() {
375 return inITBlock() && (ITState.Mask & 1);
381 assert(inImplicitITBlock());
386 unsigned NewMask = 0;
388 NewMask |= ITState.Mask & (0xE << TZ);
390 NewMask |= (
Cond != ITState.Cond) << TZ;
392 NewMask |= 1 << (TZ - 1);
393 ITState.Mask = NewMask;
397 void startImplicitITBlock() {
401 ITState.CurPosition = 1;
402 ITState.IsExplicit =
false;
413 ITState.CurPosition = 0;
414 ITState.IsExplicit =
true;
419 unsigned CurPosition;
421 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
422 void forwardVPTPosition() {
423 if (!inVPTBlock())
return;
425 if (++VPTState.CurPosition == 5 - TZ)
426 VPTState.CurPosition = ~0U;
430 return getParser().Note(L,
Msg,
Range);
434 return getParser().Warning(L,
Msg,
Range);
438 return getParser().Error(L,
Msg,
Range);
442 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
443 bool IsARPop =
false);
445 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
447 MCRegister tryParseRegister(
bool AllowOutofBoundReg =
false);
450 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
451 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
452 bool AllowRAAC =
false,
bool IsLazyLoadStore =
false,
453 bool IsVSCCLRM =
false);
456 bool parseImmExpr(int64_t &Out);
459 unsigned &ShiftAmount);
460 bool parseLiteralValues(
unsigned Size,
SMLoc L);
461 bool parseDirectiveThumb(
SMLoc L);
462 bool parseDirectiveARM(
SMLoc L);
463 bool parseDirectiveThumbFunc(
SMLoc L);
464 bool parseDirectiveCode(
SMLoc L);
465 bool parseDirectiveSyntax(
SMLoc L);
467 bool parseDirectiveUnreq(
SMLoc L);
468 bool parseDirectiveArch(
SMLoc L);
469 bool parseDirectiveEabiAttr(
SMLoc L);
470 bool parseDirectiveCPU(
SMLoc L);
471 bool parseDirectiveFPU(
SMLoc L);
472 bool parseDirectiveFnStart(
SMLoc L);
473 bool parseDirectiveFnEnd(
SMLoc L);
474 bool parseDirectiveCantUnwind(
SMLoc L);
475 bool parseDirectivePersonality(
SMLoc L);
476 bool parseDirectiveHandlerData(
SMLoc L);
477 bool parseDirectiveSetFP(
SMLoc L);
478 bool parseDirectivePad(
SMLoc L);
479 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
480 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
481 bool parseDirectiveLtorg(
SMLoc L);
482 bool parseDirectiveEven(
SMLoc L);
483 bool parseDirectivePersonalityIndex(
SMLoc L);
484 bool parseDirectiveUnwindRaw(
SMLoc L);
485 bool parseDirectiveTLSDescSeq(
SMLoc L);
486 bool parseDirectiveMovSP(
SMLoc L);
487 bool parseDirectiveObjectArch(
SMLoc L);
488 bool parseDirectiveArchExtension(
SMLoc L);
489 bool parseDirectiveAlign(
SMLoc L);
490 bool parseDirectiveThumbSet(
SMLoc L);
492 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
493 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
494 bool parseDirectiveSEHSaveSP(
SMLoc L);
495 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
496 bool parseDirectiveSEHSaveLR(
SMLoc L);
497 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
498 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
499 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
500 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
501 bool parseDirectiveSEHCustom(
SMLoc L);
503 std::unique_ptr<ARMOperand> defaultCondCodeOp();
504 std::unique_ptr<ARMOperand> defaultCCOutOp();
505 std::unique_ptr<ARMOperand> defaultVPTPredOp();
511 bool &CarrySetting,
unsigned &ProcessorIMod,
514 StringRef FullInst,
bool &CanAcceptCarrySet,
515 bool &CanAcceptPredicationCode,
516 bool &CanAcceptVPTPredicationCode);
519 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
522 unsigned MnemonicOpsEndInd);
525 unsigned MnemonicOpsEndInd);
529 return getSTI().hasFeature(ARM::ModeThumb);
532 bool isThumbOne()
const {
533 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
536 bool isThumbTwo()
const {
537 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
540 bool hasThumb()
const {
541 return getSTI().hasFeature(ARM::HasV4TOps);
544 bool hasThumb2()
const {
545 return getSTI().hasFeature(ARM::FeatureThumb2);
548 bool hasV6Ops()
const {
549 return getSTI().hasFeature(ARM::HasV6Ops);
552 bool hasV6T2Ops()
const {
553 return getSTI().hasFeature(ARM::HasV6T2Ops);
556 bool hasV6MOps()
const {
557 return getSTI().hasFeature(ARM::HasV6MOps);
560 bool hasV7Ops()
const {
561 return getSTI().hasFeature(ARM::HasV7Ops);
564 bool hasV8Ops()
const {
565 return getSTI().hasFeature(ARM::HasV8Ops);
568 bool hasV8MBaseline()
const {
569 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
572 bool hasV8MMainline()
const {
573 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
575 bool hasV8_1MMainline()
const {
576 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
578 bool hasMVEFloat()
const {
579 return getSTI().hasFeature(ARM::HasMVEFloatOps);
581 bool hasCDE()
const {
582 return getSTI().hasFeature(ARM::HasCDEOps);
584 bool has8MSecExt()
const {
585 return getSTI().hasFeature(ARM::Feature8MSecExt);
588 bool hasARM()
const {
589 return !getSTI().hasFeature(ARM::FeatureNoARM);
592 bool hasDSP()
const {
593 return getSTI().hasFeature(ARM::FeatureDSP);
596 bool hasD32()
const {
597 return getSTI().hasFeature(ARM::FeatureD32);
600 bool hasV8_1aOps()
const {
601 return getSTI().hasFeature(ARM::HasV8_1aOps);
604 bool hasRAS()
const {
605 return getSTI().hasFeature(ARM::FeatureRAS);
610 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
611 setAvailableFeatures(FB);
614 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
616 bool isMClass()
const {
617 return getSTI().hasFeature(ARM::FeatureMClass);
623#define GET_ASSEMBLER_HEADER
624#include "ARMGenAsmMatcher.inc"
655 ParseStatus parseVectorLane(VectorLaneTy &LaneKind,
unsigned &Index,
664 unsigned MnemonicOpsEndInd);
666 unsigned MnemonicOpsEndInd, MCStreamer &Out);
667 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
669 unsigned MnemonicOpsEndInd);
670 bool isITBlockTerminator(MCInst &Inst)
const;
673 unsigned MnemonicOpsEndInd);
675 bool ARMMode,
bool Writeback,
676 unsigned MnemonicOpsEndInd);
679 enum ARMMatchResultTy {
680 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
681 Match_RequiresNotITBlock,
683 Match_RequiresThumb2,
685 Match_RequiresFlagSetting,
686#define GET_OPERAND_DIAGNOSTIC_TYPES
687#include "ARMGenAsmMatcher.inc"
691 ARMAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
692 const MCInstrInfo &MII)
693 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
700 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
704 getTargetStreamer().emitTargetAttributes(STI);
707 ITState.CurPosition = ~0
U;
709 VPTState.CurPosition = ~0
U;
711 NextSymbolIsThumb =
false;
715 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
716 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
717 SMLoc &EndLoc)
override;
718 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
720 bool ParseDirective(AsmToken DirectiveID)
override;
722 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
723 unsigned Kind)
override;
724 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
726 checkEarlyTargetMatchPredicate(MCInst &Inst,
729 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
732 bool MatchingInlineAsm)
override;
734 SmallVectorImpl<NearMissInfo> &NearMisses,
735 bool MatchingInlineAsm,
bool &EmitInITBlock,
738 struct NearMissMessage {
740 SmallString<128> Message;
743 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
745 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
746 SmallVectorImpl<NearMissMessage> &NearMissesOut,
748 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
751 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
753 void onLabelParsed(MCSymbol *Symbol)
override;
755 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
756 return MII.get(Opcode);
759 bool hasMVE()
const {
return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
762 MCRegister getDRegFromQReg(MCRegister QReg)
const {
763 return MRI->
getSubReg(QReg, ARM::dsub_0);
766 const MCRegisterInfo *getMRI()
const {
return MRI; }
771class ARMOperand :
public MCParsedAsmOperand {
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 {
886 MCRegister BaseRegNum;
889 const MCExpr *OffsetImm;
890 MCRegister 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;
954 struct MemoryOp Memory;
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) {}
968 SMLoc getStartLoc()
const override {
return StartLoc; }
971 SMLoc getEndLoc()
const override {
return EndLoc; }
975 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
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!");
1000 return StringRef(Tok.Data, Tok.Length);
1003 MCRegister
getReg()
const override {
1004 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1008 const SmallVectorImpl<MCRegister> &getRegList()
const {
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 {
1018 assert(isImm() &&
"Invalid access!");
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;
1078 return CE->getValue() % 4 == 0;
1083 bool isThumbBranchTarget()
const {
1084 if (!isImm())
return false;
1087 return CE->getValue() % 2 == 0;
1093 template<
unsigned w
idth,
unsigned scale>
1094 bool isUnsignedOffset()
const {
1095 if (!isImm())
return false;
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;
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;
1128 int64_t Val =
CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1138 bool isThumbMemPC()
const {
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;
1150 Val =
CE->getValue();
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1158 bool isFPImm()
const {
1159 if (!isImm())
return false;
1167 template<
int64_t N,
int64_t M>
1168 bool isImmediate()
const {
1169 if (!isImm())
return false;
1171 if (!CE)
return false;
1172 int64_t
Value =
CE->getValue();
1176 template<
int64_t N,
int64_t M>
1177 bool isImmediateS4()
const {
1178 if (!isImm())
return false;
1180 if (!CE)
return false;
1181 int64_t
Value =
CE->getValue();
1187 Value == std::numeric_limits<int32_t>::min();
1189 template<
int64_t N,
int64_t M>
1190 bool isImmediateS2()
const {
1191 if (!isImm())
return false;
1193 if (!CE)
return false;
1194 int64_t
Value =
CE->getValue();
1197 bool isFBits16()
const {
1198 return isImmediate<0, 17>();
1200 bool isFBits32()
const {
1201 return isImmediate<1, 33>();
1203 bool isImm8s4()
const {
1204 return isImmediateS4<-1020, 1020>();
1206 bool isImm7s4()
const {
1207 return isImmediateS4<-508, 508>();
1209 bool isImm7Shift0()
const {
1210 return isImmediate<-127, 127>();
1212 bool isImm7Shift1()
const {
1213 return isImmediateS2<-255, 255>();
1215 bool isImm7Shift2()
const {
1216 return isImmediateS4<-511, 511>();
1218 bool isImm7()
const {
1219 return isImmediate<-127, 127>();
1221 bool isImm0_1020s4()
const {
1222 return isImmediateS4<0, 1020>();
1224 bool isImm0_508s4()
const {
1225 return isImmediateS4<0, 508>();
1227 bool isImm0_508s4Neg()
const {
1228 if (!isImm())
return false;
1230 if (!CE)
return false;
1231 int64_t
Value = -
CE->getValue();
1236 bool isImm0_4095Neg()
const {
1237 if (!isImm())
return false;
1239 if (!CE)
return false;
1244 if ((
CE->getValue() >> 32) > 0)
return false;
1245 uint32_t
Value = -
static_cast<uint32_t
>(
CE->getValue());
1249 bool isImm0_7()
const {
1250 return isImmediate<0, 7>();
1253 bool isImm1_16()
const {
1254 return isImmediate<1, 16>();
1257 bool isImm1_32()
const {
1258 return isImmediate<1, 32>();
1261 bool isImm8_255()
const {
1262 return isImmediate<8, 255>();
1265 bool isImm0_255Expr()
const {
1273 int64_t
Value =
CE->getValue();
1277 bool isImm256_65535Expr()
const {
1278 if (!isImm())
return false;
1282 if (!CE)
return true;
1283 int64_t
Value =
CE->getValue();
1287 bool isImm0_65535Expr()
const {
1288 if (!isImm())
return false;
1292 if (!CE)
return true;
1293 int64_t
Value =
CE->getValue();
1297 bool isImm24bit()
const {
1298 return isImmediate<0, 0xffffff + 1>();
1301 bool isImmThumbSR()
const {
1302 return isImmediate<1, 33>();
1305 bool isPKHLSLImm()
const {
1306 return isImmediate<0, 32>();
1309 bool isPKHASRImm()
const {
1310 return isImmediate<0, 33>();
1313 bool isAdrLabel()
const {
1320 if (!isImm())
return false;
1322 if (!CE)
return false;
1323 int64_t
Value =
CE->getValue();
1328 bool isT2SOImm()
const {
1335 return (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
1338 if (!isImm())
return false;
1340 if (!CE)
return false;
1341 int64_t
Value =
CE->getValue();
1345 bool isT2SOImmNot()
const {
1346 if (!isImm())
return false;
1348 if (!CE)
return false;
1349 int64_t
Value =
CE->getValue();
1354 bool isT2SOImmNeg()
const {
1355 if (!isImm())
return false;
1357 if (!CE)
return false;
1358 int64_t
Value =
CE->getValue();
1364 bool isSetEndImm()
const {
1365 if (!isImm())
return false;
1367 if (!CE)
return false;
1368 int64_t
Value =
CE->getValue();
1372 bool isReg()
const override {
return Kind == k_Register; }
1373 bool isRegList()
const {
return Kind == k_RegisterList; }
1374 bool isRegListWithAPSR()
const {
1375 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1377 bool isDReg()
const {
1379 getARMMCRegisterClass(ARM::DPRRegClassID).contains(
Reg.RegNum);
1381 bool isQReg()
const {
1383 getARMMCRegisterClass(ARM::QPRRegClassID).contains(
Reg.RegNum);
1385 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1386 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1387 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1388 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1389 bool isToken()
const override {
return Kind == k_Token; }
1390 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1391 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1392 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1393 bool isMem()
const override {
1394 return isGPRMem() || isMVEMem();
1396 bool isMVEMem()
const {
1397 if (Kind != k_Memory)
1399 if (Memory.BaseRegNum &&
1400 !getARMMCRegisterClass(ARM::GPRRegClassID)
1402 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1404 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1409 bool isGPRMem()
const {
1410 if (Kind != k_Memory)
1412 if (Memory.BaseRegNum &&
1413 !getARMMCRegisterClass(ARM::GPRRegClassID).
contains(Memory.BaseRegNum))
1415 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1420 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg()
const {
1422 return Kind == k_ShiftedRegister &&
1423 getARMMCRegisterClass(ARM::GPRRegClassID)
1424 .contains(RegShiftedReg.SrcReg) &&
1425 getARMMCRegisterClass(ARM::GPRRegClassID)
1426 .contains(RegShiftedReg.ShiftReg);
1428 bool isRegShiftedImm()
const {
1429 return Kind == k_ShiftedImmediate &&
1430 getARMMCRegisterClass(ARM::GPRRegClassID)
1431 .contains(RegShiftedImm.SrcReg);
1433 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1435 template<
unsigned Min,
unsigned Max>
1436 bool isPowerTwoInRange()
const {
1437 if (!isImm())
return false;
1439 if (!CE)
return false;
1440 int64_t
Value =
CE->getValue();
1444 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1446 bool isModImmNot()
const {
1447 if (!isImm())
return false;
1449 if (!CE)
return false;
1450 int64_t
Value =
CE->getValue();
1454 bool isModImmNeg()
const {
1455 if (!isImm())
return false;
1457 if (!CE)
return false;
1458 int64_t
Value =
CE->getValue();
1463 bool isThumbModImmNeg1_7()
const {
1464 if (!isImm())
return false;
1466 if (!CE)
return false;
1467 int32_t
Value = -(int32_t)
CE->getValue();
1471 bool isThumbModImmNeg8_255()
const {
1472 if (!isImm())
return false;
1474 if (!CE)
return false;
1475 int32_t
Value = -(int32_t)
CE->getValue();
1479 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1480 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1481 bool isPostIdxRegShifted()
const {
1482 return Kind == k_PostIndexRegister &&
1483 getARMMCRegisterClass(ARM::GPRRegClassID)
1484 .contains(PostIdxReg.RegNum);
1486 bool isPostIdxReg()
const {
1489 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1493 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1494 (alignOK || Memory.Alignment ==
Alignment);
1496 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1500 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1505 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1506 (alignOK || Memory.Alignment ==
Alignment);
1508 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1512 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).
contains(Memory.BaseRegNum))
1516 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1517 (alignOK || Memory.Alignment ==
Alignment);
1519 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1523 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).
contains(Memory.BaseRegNum))
1527 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1528 (alignOK || Memory.Alignment ==
Alignment);
1530 bool isMemPCRelImm12()
const {
1531 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1534 if (Memory.BaseRegNum != ARM::PC)
1537 if (!Memory.OffsetImm)
return true;
1539 int64_t Val =
CE->getValue();
1540 return (Val > -4096 && Val < 4096) ||
1541 (Val == std::numeric_limits<int32_t>::min());
1546 bool isAlignedMemory()
const {
1547 return isMemNoOffset(
true);
1550 bool isAlignedMemoryNone()
const {
1551 return isMemNoOffset(
false, 0);
1554 bool isDupAlignedMemoryNone()
const {
1555 return isMemNoOffset(
false, 0);
1558 bool isAlignedMemory16()
const {
1559 if (isMemNoOffset(
false, 2))
1561 return isMemNoOffset(
false, 0);
1564 bool isDupAlignedMemory16()
const {
1565 if (isMemNoOffset(
false, 2))
1567 return isMemNoOffset(
false, 0);
1570 bool isAlignedMemory32()
const {
1571 if (isMemNoOffset(
false, 4))
1573 return isMemNoOffset(
false, 0);
1576 bool isDupAlignedMemory32()
const {
1577 if (isMemNoOffset(
false, 4))
1579 return isMemNoOffset(
false, 0);
1582 bool isAlignedMemory64()
const {
1583 if (isMemNoOffset(
false, 8))
1585 return isMemNoOffset(
false, 0);
1588 bool isDupAlignedMemory64()
const {
1589 if (isMemNoOffset(
false, 8))
1591 return isMemNoOffset(
false, 0);
1594 bool isAlignedMemory64or128()
const {
1595 if (isMemNoOffset(
false, 8))
1597 if (isMemNoOffset(
false, 16))
1599 return isMemNoOffset(
false, 0);
1602 bool isDupAlignedMemory64or128()
const {
1603 if (isMemNoOffset(
false, 8))
1605 if (isMemNoOffset(
false, 16))
1607 return isMemNoOffset(
false, 0);
1610 bool isAlignedMemory64or128or256()
const {
1611 if (isMemNoOffset(
false, 8))
1613 if (isMemNoOffset(
false, 16))
1615 if (isMemNoOffset(
false, 32))
1617 return isMemNoOffset(
false, 0);
1620 bool isAddrMode2()
const {
1621 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1623 if (Memory.OffsetRegNum)
return true;
1625 if (!Memory.OffsetImm)
return true;
1627 int64_t Val =
CE->getValue();
1628 return Val > -4096 && Val < 4096;
1633 bool isAM2OffsetImm()
const {
1634 if (!isImm())
return false;
1637 if (!CE)
return false;
1638 int64_t Val =
CE->getValue();
1639 return (Val == std::numeric_limits<int32_t>::min()) ||
1640 (Val > -4096 && Val < 4096);
1643 bool isAddrMode3()
const {
1649 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1653 if (Memory.OffsetRegNum)
return true;
1655 if (!Memory.OffsetImm)
return true;
1657 int64_t Val =
CE->getValue();
1660 return (Val > -256 && Val < 256) ||
1661 Val == std::numeric_limits<int32_t>::min();
1666 bool isAM3Offset()
const {
1673 if (!CE)
return false;
1674 int64_t Val =
CE->getValue();
1676 return (Val > -256 && Val < 256) ||
1677 Val == std::numeric_limits<int32_t>::min();
1680 bool isAddrMode5()
const {
1686 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1688 if (Memory.OffsetRegNum)
return false;
1690 if (!Memory.OffsetImm)
return true;
1692 int64_t Val =
CE->getValue();
1693 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1694 Val == std::numeric_limits<int32_t>::min();
1699 bool isAddrMode5FP16()
const {
1705 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1707 if (Memory.OffsetRegNum)
return false;
1709 if (!Memory.OffsetImm)
return true;
1711 int64_t Val =
CE->getValue();
1712 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1713 Val == std::numeric_limits<int32_t>::min();
1718 bool isMemTBB()
const {
1719 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1725 bool isMemTBH()
const {
1726 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1727 Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm != 1 ||
1728 Memory.Alignment != 0 )
1733 bool isMemRegOffset()
const {
1734 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1739 bool isT2MemRegOffset()
const {
1740 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1741 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1746 if (Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm > 3)
1751 bool isMemThumbRR()
const {
1754 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1761 bool isMemThumbRIs4()
const {
1762 if (!isGPRMem() || Memory.OffsetRegNum ||
1766 if (!Memory.OffsetImm)
return true;
1768 int64_t Val =
CE->getValue();
1769 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1774 bool isMemThumbRIs2()
const {
1775 if (!isGPRMem() || Memory.OffsetRegNum ||
1779 if (!Memory.OffsetImm)
return true;
1781 int64_t Val =
CE->getValue();
1782 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1787 bool isMemThumbRIs1()
const {
1788 if (!isGPRMem() || Memory.OffsetRegNum ||
1792 if (!Memory.OffsetImm)
return true;
1794 int64_t Val =
CE->getValue();
1795 return Val >= 0 && Val <= 31;
1800 bool isMemThumbSPI()
const {
1801 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1802 Memory.Alignment != 0)
1805 if (!Memory.OffsetImm)
return true;
1807 int64_t Val =
CE->getValue();
1808 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1813 bool isMemImm8s4Offset()
const {
1819 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1822 if (!Memory.OffsetImm)
return true;
1824 int64_t Val =
CE->getValue();
1826 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1827 Val == std::numeric_limits<int32_t>::min();
1832 bool isMemImm7s4Offset()
const {
1838 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1839 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1843 if (!Memory.OffsetImm)
return true;
1845 int64_t Val =
CE->getValue();
1847 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1852 bool isMemImm0_1020s4Offset()
const {
1853 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1856 if (!Memory.OffsetImm)
return true;
1858 int64_t Val =
CE->getValue();
1859 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1864 bool isMemImm8Offset()
const {
1865 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1868 if (Memory.BaseRegNum == ARM::PC)
return false;
1870 if (!Memory.OffsetImm)
return true;
1872 int64_t Val =
CE->getValue();
1873 return (Val == std::numeric_limits<int32_t>::min()) ||
1874 (Val > -256 && Val < 256);
1879 template<
unsigned Bits,
unsigned RegClassID>
1880 bool isMemImm7ShiftedOffset()
const {
1881 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1882 !getARMMCRegisterClass(RegClassID).
contains(Memory.BaseRegNum))
1888 if (!Memory.OffsetImm)
return true;
1890 int64_t Val =
CE->getValue();
1894 if (Val == INT32_MIN)
1897 unsigned Divisor = 1U <<
Bits;
1900 if (Val % Divisor != 0)
1905 return (Val >= -127 && Val <= 127);
1910 template <
int shift>
bool isMemRegRQOffset()
const {
1911 if (!isMVEMem() || Memory.OffsetImm !=
nullptr || Memory.Alignment != 0)
1914 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1917 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1925 (Memory.ShiftType !=
ARM_AM::uxtw || Memory.ShiftImm != shift))
1931 template <
int shift>
bool isMemRegQOffset()
const {
1932 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1935 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1938 if (!Memory.OffsetImm)
1940 static_assert(shift < 56,
1941 "Such that we dont shift by a value higher than 62");
1943 int64_t Val =
CE->getValue();
1946 if ((Val & ((1U << shift) - 1)) != 0)
1952 int64_t
Range = (1U << (7 + shift)) - 1;
1953 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1958 bool isMemPosImm8Offset()
const {
1959 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1962 if (!Memory.OffsetImm)
return true;
1964 int64_t Val =
CE->getValue();
1965 return Val >= 0 && Val < 256;
1970 bool isMemNegImm8Offset()
const {
1971 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1974 if (Memory.BaseRegNum == ARM::PC)
return false;
1976 if (!Memory.OffsetImm)
return false;
1978 int64_t Val =
CE->getValue();
1979 return (Val == std::numeric_limits<int32_t>::min()) ||
1980 (Val > -256 && Val < 0);
1985 bool isMemUImm12Offset()
const {
1986 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1989 if (!Memory.OffsetImm)
return true;
1991 int64_t Val =
CE->getValue();
1992 return (Val >= 0 && Val < 4096);
1997 bool isMemImm12Offset()
const {
2005 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2008 if (!Memory.OffsetImm)
return true;
2010 int64_t Val =
CE->getValue();
2011 return (Val > -4096 && Val < 4096) ||
2012 (Val == std::numeric_limits<int32_t>::min());
2019 bool isConstPoolAsmImm()
const {
2022 return (isConstantPoolImm());
2025 bool isPostIdxImm8()
const {
2026 if (!isImm())
return false;
2028 if (!CE)
return false;
2029 int64_t Val =
CE->getValue();
2030 return (Val > -256 && Val < 256) ||
2031 (Val == std::numeric_limits<int32_t>::min());
2034 bool isPostIdxImm8s4()
const {
2035 if (!isImm())
return false;
2037 if (!CE)
return false;
2038 int64_t Val =
CE->getValue();
2039 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2040 (Val == std::numeric_limits<int32_t>::min());
2043 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2044 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2045 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2048 bool isAnyVectorList()
const {
2049 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2050 Kind == k_VectorListIndexed;
2053 bool isVectorList()
const {
return Kind == k_VectorList; }
2055 bool isSingleSpacedVectorList()
const {
2056 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2059 bool isDoubleSpacedVectorList()
const {
2060 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2063 bool isVecListOneD()
const {
2065 if (isDReg() && !Parser->hasMVE())
2067 if (!isSingleSpacedVectorList())
return false;
2068 return VectorList.Count == 1;
2071 bool isVecListTwoMQ()
const {
2072 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2073 getARMMCRegisterClass(ARM::MQPRRegClassID)
2074 .contains(VectorList.RegNum);
2077 bool isVecListDPair()
const {
2080 if (isQReg() && !Parser->hasMVE())
2082 if (!isSingleSpacedVectorList())
return false;
2083 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2087 bool isVecListThreeD()
const {
2088 if (!isSingleSpacedVectorList())
return false;
2089 return VectorList.Count == 3;
2092 bool isVecListFourD()
const {
2093 if (!isSingleSpacedVectorList())
return false;
2094 return VectorList.Count == 4;
2097 bool isVecListDPairSpaced()
const {
2098 if (Kind != k_VectorList)
return false;
2099 if (isSingleSpacedVectorList())
return false;
2100 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2104 bool isVecListThreeQ()
const {
2105 if (!isDoubleSpacedVectorList())
return false;
2106 return VectorList.Count == 3;
2109 bool isVecListFourQ()
const {
2110 if (!isDoubleSpacedVectorList())
return false;
2111 return VectorList.Count == 4;
2114 bool isVecListFourMQ()
const {
2115 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2116 getARMMCRegisterClass(ARM::MQPRRegClassID)
2117 .contains(VectorList.RegNum);
2120 bool isSingleSpacedVectorAllLanes()
const {
2121 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2124 bool isDoubleSpacedVectorAllLanes()
const {
2125 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2128 bool isVecListOneDAllLanes()
const {
2129 if (!isSingleSpacedVectorAllLanes())
return false;
2130 return VectorList.Count == 1;
2133 bool isVecListDPairAllLanes()
const {
2134 if (!isSingleSpacedVectorAllLanes())
return false;
2135 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2139 bool isVecListDPairSpacedAllLanes()
const {
2140 if (!isDoubleSpacedVectorAllLanes())
return false;
2141 return VectorList.Count == 2;
2144 bool isVecListThreeDAllLanes()
const {
2145 if (!isSingleSpacedVectorAllLanes())
return false;
2146 return VectorList.Count == 3;
2149 bool isVecListThreeQAllLanes()
const {
2150 if (!isDoubleSpacedVectorAllLanes())
return false;
2151 return VectorList.Count == 3;
2154 bool isVecListFourDAllLanes()
const {
2155 if (!isSingleSpacedVectorAllLanes())
return false;
2156 return VectorList.Count == 4;
2159 bool isVecListFourQAllLanes()
const {
2160 if (!isDoubleSpacedVectorAllLanes())
return false;
2161 return VectorList.Count == 4;
2164 bool isSingleSpacedVectorIndexed()
const {
2165 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2168 bool isDoubleSpacedVectorIndexed()
const {
2169 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2172 bool isVecListOneDByteIndexed()
const {
2173 if (!isSingleSpacedVectorIndexed())
return false;
2174 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2177 bool isVecListOneDHWordIndexed()
const {
2178 if (!isSingleSpacedVectorIndexed())
return false;
2179 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2182 bool isVecListOneDWordIndexed()
const {
2183 if (!isSingleSpacedVectorIndexed())
return false;
2184 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2187 bool isVecListTwoDByteIndexed()
const {
2188 if (!isSingleSpacedVectorIndexed())
return false;
2189 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2192 bool isVecListTwoDHWordIndexed()
const {
2193 if (!isSingleSpacedVectorIndexed())
return false;
2194 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2197 bool isVecListTwoQWordIndexed()
const {
2198 if (!isDoubleSpacedVectorIndexed())
return false;
2199 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2202 bool isVecListTwoQHWordIndexed()
const {
2203 if (!isDoubleSpacedVectorIndexed())
return false;
2204 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2207 bool isVecListTwoDWordIndexed()
const {
2208 if (!isSingleSpacedVectorIndexed())
return false;
2209 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2212 bool isVecListThreeDByteIndexed()
const {
2213 if (!isSingleSpacedVectorIndexed())
return false;
2214 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2217 bool isVecListThreeDHWordIndexed()
const {
2218 if (!isSingleSpacedVectorIndexed())
return false;
2219 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2222 bool isVecListThreeQWordIndexed()
const {
2223 if (!isDoubleSpacedVectorIndexed())
return false;
2224 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2227 bool isVecListThreeQHWordIndexed()
const {
2228 if (!isDoubleSpacedVectorIndexed())
return false;
2229 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2232 bool isVecListThreeDWordIndexed()
const {
2233 if (!isSingleSpacedVectorIndexed())
return false;
2234 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2237 bool isVecListFourDByteIndexed()
const {
2238 if (!isSingleSpacedVectorIndexed())
return false;
2239 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2242 bool isVecListFourDHWordIndexed()
const {
2243 if (!isSingleSpacedVectorIndexed())
return false;
2244 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2247 bool isVecListFourQWordIndexed()
const {
2248 if (!isDoubleSpacedVectorIndexed())
return false;
2249 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2252 bool isVecListFourQHWordIndexed()
const {
2253 if (!isDoubleSpacedVectorIndexed())
return false;
2254 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2257 bool isVecListFourDWordIndexed()
const {
2258 if (!isSingleSpacedVectorIndexed())
return false;
2259 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2262 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2264 template <
unsigned NumLanes>
2265 bool isVectorIndexInRange()
const {
2266 if (Kind != k_VectorIndex)
return false;
2267 return VectorIndex.Val < NumLanes;
2270 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2271 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2272 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2273 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2275 template<
int PermittedValue,
int OtherPermittedValue>
2276 bool isMVEPairVectorIndex()
const {
2277 if (Kind != k_VectorIndex)
return false;
2278 return VectorIndex.Val == PermittedValue ||
2279 VectorIndex.Val == OtherPermittedValue;
2282 bool isNEONi8splat()
const {
2283 if (!isImm())
return false;
2286 if (!CE)
return false;
2287 int64_t
Value =
CE->getValue();
2294 if (isNEONByteReplicate(2))
2300 if (!CE)
return false;
2301 unsigned Value =
CE->getValue();
2305 bool isNEONi16splatNot()
const {
2310 if (!CE)
return false;
2311 unsigned Value =
CE->getValue();
2316 if (isNEONByteReplicate(4))
2322 if (!CE)
return false;
2323 unsigned Value =
CE->getValue();
2327 bool isNEONi32splatNot()
const {
2332 if (!CE)
return false;
2333 unsigned Value =
CE->getValue();
2337 static bool isValidNEONi32vmovImm(int64_t
Value) {
2340 return ((
Value & 0xffffffffffffff00) == 0) ||
2341 ((
Value & 0xffffffffffff00ff) == 0) ||
2342 ((
Value & 0xffffffffff00ffff) == 0) ||
2343 ((
Value & 0xffffffff00ffffff) == 0) ||
2344 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2345 ((
Value & 0xffffffffff00ffff) == 0xffff);
2348 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2349 assert((Width == 8 || Width == 16 || Width == 32) &&
2350 "Invalid element width");
2351 assert(NumElems * Width <= 64 &&
"Invalid result width");
2359 int64_t
Value =
CE->getValue();
2367 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2369 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2372 for (
unsigned i = 1; i < NumElems; ++i) {
2374 if ((
Value & Mask) != Elem)
2380 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2381 return isNEONReplicate(8, NumBytes,
false);
2384 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2385 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2386 "Invalid source width");
2387 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2388 "Invalid destination width");
2389 assert(FromW < ToW &&
"ToW is not less than FromW");
2392 template<
unsigned FromW,
unsigned ToW>
2393 bool isNEONmovReplicate()
const {
2394 checkNeonReplicateArgs(FromW, ToW);
2395 if (ToW == 64 && isNEONi64splat())
2397 return isNEONReplicate(FromW, ToW / FromW,
false);
2400 template<
unsigned FromW,
unsigned ToW>
2401 bool isNEONinvReplicate()
const {
2402 checkNeonReplicateArgs(FromW, ToW);
2403 return isNEONReplicate(FromW, ToW / FromW,
true);
2406 bool isNEONi32vmov()
const {
2407 if (isNEONByteReplicate(4))
2415 return isValidNEONi32vmovImm(
CE->getValue());
2418 bool isNEONi32vmovNeg()
const {
2419 if (!isImm())
return false;
2422 if (!CE)
return false;
2423 return isValidNEONi32vmovImm(~
CE->getValue());
2426 bool isNEONi64splat()
const {
2427 if (!isImm())
return false;
2430 if (!CE)
return false;
2433 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2434 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2438 template<
int64_t Angle,
int64_t Remainder>
2439 bool isComplexRotation()
const {
2440 if (!isImm())
return false;
2443 if (!CE)
return false;
2446 return (
Value % Angle == Remainder &&
Value <= 270);
2449 bool isMVELongShift()
const {
2450 if (!isImm())
return false;
2453 if (!CE)
return false;
2458 bool isMveSaturateOp()
const {
2459 if (!isImm())
return false;
2461 if (!CE)
return false;
2466 bool isITCondCodeNoAL()
const {
2467 if (!isITCondCode())
return false;
2472 bool isITCondCodeRestrictedI()
const {
2473 if (!isITCondCode())
2479 bool isITCondCodeRestrictedS()
const {
2480 if (!isITCondCode())
2487 bool isITCondCodeRestrictedU()
const {
2488 if (!isITCondCode())
2494 bool isITCondCodeRestrictedFP()
const {
2495 if (!isITCondCode())
2502 void setVecListDPair(
unsigned int DPair) {
2503 Kind = k_VectorList;
2504 VectorList.RegNum = DPair;
2505 VectorList.Count = 2;
2506 VectorList.isDoubleSpaced =
false;
2509 void setVecListOneD(
unsigned int DReg) {
2510 Kind = k_VectorList;
2511 VectorList.RegNum =
DReg;
2512 VectorList.Count = 1;
2513 VectorList.isDoubleSpaced =
false;
2516 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
2526 void addARMBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2527 assert(
N == 1 &&
"Invalid number of operands!");
2531 void addThumbBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2532 assert(
N == 1 &&
"Invalid number of operands!");
2536 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2537 assert(
N == 2 &&
"Invalid number of operands!");
2543 void addVPTPredNOperands(MCInst &Inst,
unsigned N)
const {
2544 assert(
N == 3 &&
"Invalid number of operands!");
2546 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2551 void addVPTPredROperands(MCInst &Inst,
unsigned N)
const {
2552 assert(
N == 4 &&
"Invalid number of operands!");
2553 addVPTPredNOperands(Inst,
N-1);
2556 RegNum = ARM::NoRegister;
2559 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2560 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2562 "Inactive register in vpred_r is not tied to an output!");
2568 void addCoprocNumOperands(MCInst &Inst,
unsigned N)
const {
2569 assert(
N == 1 &&
"Invalid number of operands!");
2573 void addCoprocRegOperands(MCInst &Inst,
unsigned N)
const {
2574 assert(
N == 1 &&
"Invalid number of operands!");
2578 void addCoprocOptionOperands(MCInst &Inst,
unsigned N)
const {
2579 assert(
N == 1 &&
"Invalid number of operands!");
2583 void addITMaskOperands(MCInst &Inst,
unsigned N)
const {
2584 assert(
N == 1 &&
"Invalid number of operands!");
2588 void addITCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2589 assert(
N == 1 &&
"Invalid number of operands!");
2593 void addITCondCodeInvOperands(MCInst &Inst,
unsigned N)
const {
2594 assert(
N == 1 &&
"Invalid number of operands!");
2598 void addCCOutOperands(MCInst &Inst,
unsigned N)
const {
2599 assert(
N == 1 &&
"Invalid number of operands!");
2603 void addRegOperands(MCInst &Inst,
unsigned N)
const {
2604 assert(
N == 1 &&
"Invalid number of operands!");
2608 void addRegShiftedRegOperands(MCInst &Inst,
unsigned N)
const {
2609 assert(
N == 3 &&
"Invalid number of operands!");
2610 assert(isRegShiftedReg() &&
2611 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2618 void addRegShiftedImmOperands(MCInst &Inst,
unsigned N)
const {
2619 assert(
N == 2 &&
"Invalid number of operands!");
2620 assert(isRegShiftedImm() &&
2621 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2624 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2629 void addShifterImmOperands(MCInst &Inst,
unsigned N)
const {
2630 assert(
N == 1 &&
"Invalid number of operands!");
2635 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
2636 assert(
N == 1 &&
"Invalid number of operands!");
2637 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2638 for (MCRegister
Reg : RegList)
2642 void addRegListWithAPSROperands(MCInst &Inst,
unsigned N)
const {
2643 assert(
N == 1 &&
"Invalid number of operands!");
2644 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2645 for (MCRegister
Reg : RegList)
2649 void addDPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2650 addRegListOperands(Inst,
N);
2653 void addSPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2654 addRegListOperands(Inst,
N);
2657 void addFPSRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2658 addRegListOperands(Inst,
N);
2661 void addFPDRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2662 addRegListOperands(Inst,
N);
2665 void addRotImmOperands(MCInst &Inst,
unsigned N)
const {
2666 assert(
N == 1 &&
"Invalid number of operands!");
2671 void addModImmOperands(MCInst &Inst,
unsigned N)
const {
2672 assert(
N == 1 &&
"Invalid number of operands!");
2676 return addImmOperands(Inst,
N);
2681 void addModImmNotOperands(MCInst &Inst,
unsigned N)
const {
2682 assert(
N == 1 &&
"Invalid number of operands!");
2688 void addModImmNegOperands(MCInst &Inst,
unsigned N)
const {
2689 assert(
N == 1 &&
"Invalid number of operands!");
2695 void addThumbModImmNeg8_255Operands(MCInst &Inst,
unsigned N)
const {
2696 assert(
N == 1 &&
"Invalid number of operands!");
2698 uint32_t Val = -
CE->getValue();
2702 void addThumbModImmNeg1_7Operands(MCInst &Inst,
unsigned N)
const {
2703 assert(
N == 1 &&
"Invalid number of operands!");
2705 uint32_t Val = -
CE->getValue();
2709 void addBitfieldOperands(MCInst &Inst,
unsigned N)
const {
2710 assert(
N == 1 &&
"Invalid number of operands!");
2715 uint32_t
Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2716 (32 - (lsb + width)));
2720 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2721 assert(
N == 1 &&
"Invalid number of operands!");
2725 void addFBits16Operands(MCInst &Inst,
unsigned N)
const {
2726 assert(
N == 1 &&
"Invalid number of operands!");
2731 void addFBits32Operands(MCInst &Inst,
unsigned N)
const {
2732 assert(
N == 1 &&
"Invalid number of operands!");
2737 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2738 assert(
N == 1 &&
"Invalid number of operands!");
2744 void addImm8s4Operands(MCInst &Inst,
unsigned N)
const {
2745 assert(
N == 1 &&
"Invalid number of operands!");
2752 void addImm7s4Operands(MCInst &Inst,
unsigned N)
const {
2753 assert(
N == 1 &&
"Invalid number of operands!");
2760 void addImm7Shift0Operands(MCInst &Inst,
unsigned N)
const {
2761 assert(
N == 1 &&
"Invalid number of operands!");
2766 void addImm7Shift1Operands(MCInst &Inst,
unsigned N)
const {
2767 assert(
N == 1 &&
"Invalid number of operands!");
2772 void addImm7Shift2Operands(MCInst &Inst,
unsigned N)
const {
2773 assert(
N == 1 &&
"Invalid number of operands!");
2778 void addImm7Operands(MCInst &Inst,
unsigned N)
const {
2779 assert(
N == 1 &&
"Invalid number of operands!");
2784 void addImm0_1020s4Operands(MCInst &Inst,
unsigned N)
const {
2785 assert(
N == 1 &&
"Invalid number of operands!");
2792 void addImm0_508s4NegOperands(MCInst &Inst,
unsigned N)
const {
2793 assert(
N == 1 &&
"Invalid number of operands!");
2800 void addImm0_508s4Operands(MCInst &Inst,
unsigned N)
const {
2801 assert(
N == 1 &&
"Invalid number of operands!");
2808 void addImm1_16Operands(MCInst &Inst,
unsigned N)
const {
2809 assert(
N == 1 &&
"Invalid number of operands!");
2816 void addImm1_32Operands(MCInst &Inst,
unsigned N)
const {
2817 assert(
N == 1 &&
"Invalid number of operands!");
2824 void addImmThumbSROperands(MCInst &Inst,
unsigned N)
const {
2825 assert(
N == 1 &&
"Invalid number of operands!");
2829 unsigned Imm =
CE->getValue();
2833 void addPKHASRImmOperands(MCInst &Inst,
unsigned N)
const {
2834 assert(
N == 1 &&
"Invalid number of operands!");
2838 int Val =
CE->getValue();
2842 void addT2SOImmNotOperands(MCInst &Inst,
unsigned N)
const {
2843 assert(
N == 1 &&
"Invalid number of operands!");
2850 void addT2SOImmNegOperands(MCInst &Inst,
unsigned N)
const {
2851 assert(
N == 1 &&
"Invalid number of operands!");
2858 void addImm0_4095NegOperands(MCInst &Inst,
unsigned N)
const {
2859 assert(
N == 1 &&
"Invalid number of operands!");
2866 void addUnsignedOffset_b8s2Operands(MCInst &Inst,
unsigned N)
const {
2875 void addThumbMemPCOperands(MCInst &Inst,
unsigned N)
const {
2876 assert(
N == 1 &&
"Invalid number of operands!");
2888 assert(isGPRMem() &&
"Unknown value type!");
2896 void addMemBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2897 assert(
N == 1 &&
"Invalid number of operands!");
2901 void addInstSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2902 assert(
N == 1 &&
"Invalid number of operands!");
2906 void addTraceSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2907 assert(
N == 1 &&
"Invalid number of operands!");
2911 void addMemNoOffsetOperands(MCInst &Inst,
unsigned N)
const {
2912 assert(
N == 1 &&
"Invalid number of operands!");
2916 void addMemNoOffsetT2Operands(MCInst &Inst,
unsigned N)
const {
2917 assert(
N == 1 &&
"Invalid number of operands!");
2921 void addMemNoOffsetT2NoSpOperands(MCInst &Inst,
unsigned N)
const {
2922 assert(
N == 1 &&
"Invalid number of operands!");
2926 void addMemNoOffsetTOperands(MCInst &Inst,
unsigned N)
const {
2927 assert(
N == 1 &&
"Invalid number of operands!");
2931 void addMemPCRelImm12Operands(MCInst &Inst,
unsigned N)
const {
2932 assert(
N == 1 &&
"Invalid number of operands!");
2939 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2940 assert(
N == 1 &&
"Invalid number of operands!");
2941 assert(isImm() &&
"Not an immediate!");
2951 int Val =
CE->getValue();
2955 void addAlignedMemoryOperands(MCInst &Inst,
unsigned N)
const {
2956 assert(
N == 2 &&
"Invalid number of operands!");
2961 void addDupAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2962 addAlignedMemoryOperands(Inst,
N);
2965 void addAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2966 addAlignedMemoryOperands(Inst,
N);
2969 void addAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2970 addAlignedMemoryOperands(Inst,
N);
2973 void addDupAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2974 addAlignedMemoryOperands(Inst,
N);
2977 void addAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2978 addAlignedMemoryOperands(Inst,
N);
2981 void addDupAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2982 addAlignedMemoryOperands(Inst,
N);
2985 void addAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2986 addAlignedMemoryOperands(Inst,
N);
2989 void addDupAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2990 addAlignedMemoryOperands(Inst,
N);
2993 void addAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2994 addAlignedMemoryOperands(Inst,
N);
2997 void addDupAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2998 addAlignedMemoryOperands(Inst,
N);
3001 void addAlignedMemory64or128or256Operands(MCInst &Inst,
unsigned N)
const {
3002 addAlignedMemoryOperands(Inst,
N);
3005 void addAddrMode2Operands(MCInst &Inst,
unsigned N)
const {
3006 assert(
N == 3 &&
"Invalid number of operands!");
3009 if (!Memory.OffsetRegNum) {
3010 if (!Memory.OffsetImm)
3013 int32_t Val =
CE->getValue();
3016 if (Val == std::numeric_limits<int32_t>::min())
3029 Memory.ShiftImm, Memory.ShiftType);
3034 void addAM2OffsetImmOperands(MCInst &Inst,
unsigned N)
const {
3035 assert(
N == 2 &&
"Invalid number of operands!");
3037 assert(CE &&
"non-constant AM2OffsetImm operand!");
3038 int32_t Val =
CE->getValue();
3041 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3042 if (Val < 0) Val = -Val;
3048 void addAddrMode3Operands(MCInst &Inst,
unsigned N)
const {
3049 assert(
N == 3 &&
"Invalid number of operands!");
3062 if (!Memory.OffsetRegNum) {
3063 if (!Memory.OffsetImm)
3066 int32_t Val =
CE->getValue();
3069 if (Val == std::numeric_limits<int32_t>::min())
3086 void addAM3OffsetOperands(MCInst &Inst,
unsigned N)
const {
3087 assert(
N == 2 &&
"Invalid number of operands!");
3088 if (Kind == k_PostIndexRegister) {
3097 const MCConstantExpr *
CE =
static_cast<const MCConstantExpr*
>(
getImm());
3098 int32_t Val =
CE->getValue();
3101 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3102 if (Val < 0) Val = -Val;
3108 void addAddrMode5Operands(MCInst &Inst,
unsigned N)
const {
3109 assert(
N == 2 &&
"Invalid number of operands!");
3120 if (!Memory.OffsetImm)
3124 int32_t Val =
CE->getValue() / 4;
3127 if (Val == std::numeric_limits<int32_t>::min())
3137 void addAddrMode5FP16Operands(MCInst &Inst,
unsigned N)
const {
3138 assert(
N == 2 &&
"Invalid number of operands!");
3150 if (!Memory.OffsetImm)
3153 int32_t Val =
CE->getValue() / 2;
3156 if (Val == std::numeric_limits<int32_t>::min())
3166 void addMemImm8s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3167 assert(
N == 2 &&
"Invalid number of operands!");
3178 addExpr(Inst, Memory.OffsetImm);
3181 void addMemImm7s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3182 assert(
N == 2 &&
"Invalid number of operands!");
3193 addExpr(Inst, Memory.OffsetImm);
3196 void addMemImm0_1020s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3197 assert(
N == 2 &&
"Invalid number of operands!");
3199 if (!Memory.OffsetImm)
3208 void addMemImmOffsetOperands(MCInst &Inst,
unsigned N)
const {
3209 assert(
N == 2 &&
"Invalid number of operands!");
3211 addExpr(Inst, Memory.OffsetImm);
3214 void addMemRegRQOffsetOperands(MCInst &Inst,
unsigned N)
const {
3215 assert(
N == 2 &&
"Invalid number of operands!");
3220 void addMemUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3221 assert(
N == 2 &&
"Invalid number of operands!");
3231 addExpr(Inst, Memory.OffsetImm);
3234 void addMemImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3235 assert(
N == 2 &&
"Invalid number of operands!");
3245 addExpr(Inst, Memory.OffsetImm);
3248 void addConstPoolAsmImmOperands(MCInst &Inst,
unsigned N)
const {
3249 assert(
N == 1 &&
"Invalid number of operands!");
3252 addExpr(Inst, getConstantPoolImm());
3255 void addMemTBBOperands(MCInst &Inst,
unsigned N)
const {
3256 assert(
N == 2 &&
"Invalid number of operands!");
3261 void addMemTBHOperands(MCInst &Inst,
unsigned N)
const {
3262 assert(
N == 2 &&
"Invalid number of operands!");
3267 void addMemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3268 assert(
N == 3 &&
"Invalid number of operands!");
3271 Memory.ShiftImm, Memory.ShiftType);
3277 void addT2MemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3278 assert(
N == 3 &&
"Invalid number of operands!");
3284 void addMemThumbRROperands(MCInst &Inst,
unsigned N)
const {
3285 assert(
N == 2 &&
"Invalid number of operands!");
3290 void addMemThumbRIs4Operands(MCInst &Inst,
unsigned N)
const {
3291 assert(
N == 2 &&
"Invalid number of operands!");
3293 if (!Memory.OffsetImm)
3302 void addMemThumbRIs2Operands(MCInst &Inst,
unsigned N)
const {
3303 assert(
N == 2 &&
"Invalid number of operands!");
3305 if (!Memory.OffsetImm)
3313 void addMemThumbRIs1Operands(MCInst &Inst,
unsigned N)
const {
3314 assert(
N == 2 &&
"Invalid number of operands!");
3316 addExpr(Inst, Memory.OffsetImm);
3319 void addMemThumbSPIOperands(MCInst &Inst,
unsigned N)
const {
3320 assert(
N == 2 &&
"Invalid number of operands!");
3322 if (!Memory.OffsetImm)
3331 void addPostIdxImm8Operands(MCInst &Inst,
unsigned N)
const {
3332 assert(
N == 1 &&
"Invalid number of operands!");
3334 assert(CE &&
"non-constant post-idx-imm8 operand!");
3335 int Imm =
CE->getValue();
3336 bool isAdd =
Imm >= 0;
3337 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3342 void addPostIdxImm8s4Operands(MCInst &Inst,
unsigned N)
const {
3343 assert(
N == 1 &&
"Invalid number of operands!");
3345 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3346 int Imm =
CE->getValue();
3347 bool isAdd =
Imm >= 0;
3348 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3354 void addPostIdxRegOperands(MCInst &Inst,
unsigned N)
const {
3355 assert(
N == 2 &&
"Invalid number of operands!");
3360 void addPostIdxRegShiftedOperands(MCInst &Inst,
unsigned N)
const {
3361 assert(
N == 2 &&
"Invalid number of operands!");
3367 PostIdxReg.ShiftTy);
3371 void addPowerTwoOperands(MCInst &Inst,
unsigned N)
const {
3372 assert(
N == 1 &&
"Invalid number of operands!");
3377 void addMSRMaskOperands(MCInst &Inst,
unsigned N)
const {
3378 assert(
N == 1 &&
"Invalid number of operands!");
3382 void addBankedRegOperands(MCInst &Inst,
unsigned N)
const {
3383 assert(
N == 1 &&
"Invalid number of operands!");
3387 void addProcIFlagsOperands(MCInst &Inst,
unsigned N)
const {
3388 assert(
N == 1 &&
"Invalid number of operands!");
3392 void addVecListOperands(MCInst &Inst,
unsigned N)
const {
3393 assert(
N == 1 &&
"Invalid number of operands!");
3395 if (isAnyVectorList())
3397 else if (isDReg() && !Parser->hasMVE()) {
3399 }
else if (isQReg() && !Parser->hasMVE()) {
3400 MCRegister DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3401 DPair = Parser->getMRI()->getMatchingSuperReg(
3402 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3407 "attempted to add a vector list register with wrong type!");
3411 void addMVEVecListOperands(MCInst &Inst,
unsigned N)
const {
3412 assert(
N == 1 &&
"Invalid number of operands!");
3428 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3429 const MCRegisterClass *RC_out =
3430 (VectorList.Count == 2)
3431 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3432 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3435 for (
I = 0;
I <
E;
I++)
3438 assert(
I <
E &&
"Invalid vector list start register!");
3443 void addVecListIndexedOperands(MCInst &Inst,
unsigned N)
const {
3444 assert(
N == 2 &&
"Invalid number of operands!");
3449 void addVectorIndex8Operands(MCInst &Inst,
unsigned N)
const {
3450 assert(
N == 1 &&
"Invalid number of operands!");
3454 void addVectorIndex16Operands(MCInst &Inst,
unsigned N)
const {
3455 assert(
N == 1 &&
"Invalid number of operands!");
3459 void addVectorIndex32Operands(MCInst &Inst,
unsigned N)
const {
3460 assert(
N == 1 &&
"Invalid number of operands!");
3464 void addVectorIndex64Operands(MCInst &Inst,
unsigned N)
const {
3465 assert(
N == 1 &&
"Invalid number of operands!");
3469 void addMVEVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3470 assert(
N == 1 &&
"Invalid number of operands!");
3474 void addMVEPairVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3475 assert(
N == 1 &&
"Invalid number of operands!");
3479 void addNEONi8splatOperands(MCInst &Inst,
unsigned N)
const {
3480 assert(
N == 1 &&
"Invalid number of operands!");
3487 void addNEONi16splatOperands(MCInst &Inst,
unsigned N)
const {
3488 assert(
N == 1 &&
"Invalid number of operands!");
3491 unsigned Value =
CE->getValue();
3496 void addNEONi16splatNotOperands(MCInst &Inst,
unsigned N)
const {
3497 assert(
N == 1 &&
"Invalid number of operands!");
3500 unsigned Value =
CE->getValue();
3505 void addNEONi32splatOperands(MCInst &Inst,
unsigned N)
const {
3506 assert(
N == 1 &&
"Invalid number of operands!");
3509 unsigned Value =
CE->getValue();
3514 void addNEONi32splatNotOperands(MCInst &Inst,
unsigned N)
const {
3515 assert(
N == 1 &&
"Invalid number of operands!");
3518 unsigned Value =
CE->getValue();
3523 void addNEONi8ReplicateOperands(MCInst &Inst,
bool Inv)
const {
3528 "All instructions that wants to replicate non-zero byte "
3529 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3530 unsigned Value =
CE->getValue();
3533 unsigned B =
Value & 0xff;
3538 void addNEONinvi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3539 assert(
N == 1 &&
"Invalid number of operands!");
3540 addNEONi8ReplicateOperands(Inst,
true);
3543 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3546 else if (
Value > 0xffff &&
Value <= 0xffffff)
3548 else if (
Value > 0xffffff)
3553 void addNEONi32vmovOperands(MCInst &Inst,
unsigned N)
const {
3554 assert(
N == 1 &&
"Invalid number of operands!");
3557 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3561 void addNEONvmovi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3562 assert(
N == 1 &&
"Invalid number of operands!");
3563 addNEONi8ReplicateOperands(Inst,
false);
3566 void addNEONvmovi16ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3567 assert(
N == 1 &&
"Invalid number of operands!");
3573 "All instructions that want to replicate non-zero half-word "
3574 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3576 unsigned Elem =
Value & 0xffff;
3578 Elem = (Elem >> 8) | 0x200;
3582 void addNEONi32vmovNegOperands(MCInst &Inst,
unsigned N)
const {
3583 assert(
N == 1 &&
"Invalid number of operands!");
3586 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3590 void addNEONvmovi32ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3591 assert(
N == 1 &&
"Invalid number of operands!");
3597 "All instructions that want to replicate non-zero word "
3598 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3600 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3604 void addNEONi64splatOperands(MCInst &Inst,
unsigned N)
const {
3605 assert(
N == 1 &&
"Invalid number of operands!");
3610 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3616 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
3617 assert(
N == 1 &&
"Invalid number of operands!");
3622 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
3623 assert(
N == 1 &&
"Invalid number of operands!");
3628 void addMveSaturateOperands(MCInst &Inst,
unsigned N)
const {
3629 assert(
N == 1 &&
"Invalid number of operands!");
3631 unsigned Imm =
CE->getValue();
3632 assert((
Imm == 48 ||
Imm == 64) &&
"Invalid saturate operand");
3636 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
3638 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask, SMLoc S,
3639 ARMAsmParser &Parser) {
3640 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3647 static std::unique_ptr<ARMOperand>
3649 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3656 static std::unique_ptr<ARMOperand> CreateVPTPred(
ARMVCC::VPTCodes CC, SMLoc S,
3657 ARMAsmParser &Parser) {
3658 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3665 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal, SMLoc S,
3666 ARMAsmParser &Parser) {
3667 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3668 Op->Cop.Val = CopVal;
3674 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal, SMLoc S,
3675 ARMAsmParser &Parser) {
3676 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3677 Op->Cop.Val = CopVal;
3683 static std::unique_ptr<ARMOperand>
3684 CreateCoprocOption(
unsigned Val, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3685 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3692 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister
Reg, SMLoc S,
3693 ARMAsmParser &Parser) {
3694 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3695 Op->Reg.RegNum =
Reg;
3701 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3702 ARMAsmParser &Parser) {
3703 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3704 Op->Tok.Data = Str.data();
3705 Op->Tok.Length = Str.size();
3711 static std::unique_ptr<ARMOperand> CreateReg(MCRegister
Reg, SMLoc S, SMLoc
E,
3712 ARMAsmParser &Parser) {
3713 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3714 Op->Reg.RegNum =
Reg;
3720 static std::unique_ptr<ARMOperand>
3722 MCRegister ShiftReg,
unsigned ShiftImm, SMLoc S,
3723 SMLoc
E, ARMAsmParser &Parser) {
3724 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3725 Op->RegShiftedReg.ShiftTy = ShTy;
3726 Op->RegShiftedReg.SrcReg = SrcReg;
3727 Op->RegShiftedReg.ShiftReg = ShiftReg;
3728 Op->RegShiftedReg.ShiftImm = ShiftImm;
3734 static std::unique_ptr<ARMOperand>
3736 unsigned ShiftImm, SMLoc S, SMLoc
E,
3737 ARMAsmParser &Parser) {
3738 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3739 Op->RegShiftedImm.ShiftTy = ShTy;
3740 Op->RegShiftedImm.SrcReg = SrcReg;
3741 Op->RegShiftedImm.ShiftImm = ShiftImm;
3747 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3749 ARMAsmParser &Parser) {
3750 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3751 Op->ShifterImm.isASR = isASR;
3752 Op->ShifterImm.Imm =
Imm;
3758 static std::unique_ptr<ARMOperand>
3759 CreateRotImm(
unsigned Imm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3760 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3761 Op->RotImm.Imm =
Imm;
3767 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3769 ARMAsmParser &Parser) {
3770 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3772 Op->ModImm.Rot = Rot;
3778 static std::unique_ptr<ARMOperand>
3779 CreateConstantPoolImm(
const MCExpr *Val, SMLoc S, SMLoc
E,
3780 ARMAsmParser &Parser) {
3781 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3788 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3789 unsigned Width, SMLoc S,
3791 ARMAsmParser &Parser) {
3792 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3793 Op->Bitfield.LSB = LSB;
3794 Op->Bitfield.Width = Width;
3800 static std::unique_ptr<ARMOperand>
3801 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3802 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3803 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3804 KindTy Kind = k_RegisterList;
3806 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3808 if (Regs.back().second == ARM::VPR)
3809 Kind = k_FPDRegisterListWithVPR;
3811 Kind = k_DPRRegisterList;
3812 }
else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3814 if (Regs.back().second == ARM::VPR)
3815 Kind = k_FPSRegisterListWithVPR;
3817 Kind = k_SPRRegisterList;
3818 }
else if (Regs.front().second == ARM::VPR) {
3819 assert(Regs.size() == 1 &&
3820 "Register list starting with VPR expected to only contain VPR");
3821 Kind = k_FPSRegisterListWithVPR;
3824 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3825 Kind = k_RegisterListWithAPSR;
3829 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3830 for (
const auto &
P : Regs)
3831 Op->Registers.push_back(
P.second);
3833 Op->StartLoc = StartLoc;
3834 Op->EndLoc = EndLoc;
3838 static std::unique_ptr<ARMOperand>
3839 CreateVectorList(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced, SMLoc S,
3840 SMLoc
E, ARMAsmParser &Parser) {
3841 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3842 Op->VectorList.RegNum =
Reg;
3844 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3850 static std::unique_ptr<ARMOperand>
3851 CreateVectorListAllLanes(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced,
3852 SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3853 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3854 Op->VectorList.RegNum =
Reg;
3856 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3862 static std::unique_ptr<ARMOperand>
3863 CreateVectorListIndexed(MCRegister
Reg,
unsigned Count,
unsigned Index,
3864 bool isDoubleSpaced, SMLoc S, SMLoc
E,
3865 ARMAsmParser &Parser) {
3866 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3867 Op->VectorList.RegNum =
Reg;
3869 Op->VectorList.LaneIndex =
Index;
3870 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3876 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx, SMLoc S,
3877 SMLoc
E, MCContext &Ctx,
3878 ARMAsmParser &Parser) {
3879 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3880 Op->VectorIndex.Val = Idx;
3886 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val, SMLoc S,
3887 SMLoc
E, ARMAsmParser &Parser) {
3888 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3895 static std::unique_ptr<ARMOperand>
3896 CreateMem(MCRegister BaseReg,
const MCExpr *OffsetImm, MCRegister OffsetReg,
3898 bool isNegative, SMLoc S, SMLoc
E, ARMAsmParser &Parser,
3899 SMLoc AlignmentLoc = SMLoc()) {
3900 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3902 Op->Memory.OffsetImm = OffsetImm;
3903 Op->Memory.OffsetRegNum = OffsetReg;
3904 Op->Memory.ShiftType = ShiftType;
3905 Op->Memory.ShiftImm = ShiftImm;
3907 Op->Memory.isNegative = isNegative;
3910 Op->AlignmentLoc = AlignmentLoc;
3914 static std::unique_ptr<ARMOperand>
3916 unsigned ShiftImm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3917 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3918 Op->PostIdxReg.RegNum =
Reg;
3919 Op->PostIdxReg.isAdd = isAdd;
3920 Op->PostIdxReg.ShiftTy = ShiftTy;
3921 Op->PostIdxReg.ShiftImm = ShiftImm;
3927 static std::unique_ptr<ARMOperand>
3928 CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3929 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3930 Op->MBOpt.Val = Opt;
3936 static std::unique_ptr<ARMOperand>
3938 ARMAsmParser &Parser) {
3939 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3940 Op->ISBOpt.Val = Opt;
3946 static std::unique_ptr<ARMOperand>
3948 ARMAsmParser &Parser) {
3949 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3950 Op->TSBOpt.Val = Opt;
3956 static std::unique_ptr<ARMOperand>
3958 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3965 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask, SMLoc S,
3966 ARMAsmParser &Parser) {
3967 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3968 Op->MMask.Val = MMask;
3974 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg, SMLoc S,
3975 ARMAsmParser &Parser) {
3976 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3977 Op->BankedReg.Val =
Reg;
3986void ARMOperand::print(raw_ostream &OS,
const MCAsmInfo &MAI)
const {
4004 case k_ITCondMask: {
4005 static const char *
const MaskStr[] = {
4006 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4007 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4008 "(t)",
"(tett)",
"(tet)",
"(tete)",
4009 "(te)",
"(teet)",
"(tee)",
"(teee)",
4011 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4012 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4016 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4019 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4021 case k_CoprocOption:
4022 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4025 OS <<
"<mask: " << getMSRMask() <<
">";
4028 OS <<
"<banked reg: " << getBankedReg() <<
">";
4033 case k_MemBarrierOpt:
4034 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4036 case k_InstSyncBarrierOpt:
4037 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4039 case k_TraceSyncBarrierOpt:
4040 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4044 if (Memory.BaseRegNum)
4045 OS <<
" base:" <<
RegName(Memory.BaseRegNum);
4046 if (Memory.OffsetImm) {
4047 OS <<
" offset-imm:";
4050 if (Memory.OffsetRegNum)
4051 OS <<
" offset-reg:" << (Memory.isNegative ?
"-" :
"")
4052 <<
RegName(Memory.OffsetRegNum);
4055 OS <<
" shift-imm:" << Memory.ShiftImm;
4057 if (Memory.Alignment)
4058 OS <<
" alignment:" << Memory.Alignment;
4061 case k_PostIndexRegister:
4062 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4063 <<
RegName(PostIdxReg.RegNum);
4066 << PostIdxReg.ShiftImm;
4069 case k_ProcIFlags: {
4070 OS <<
"<ARM_PROC::";
4071 unsigned IFlags = getProcIFlags();
4072 for (
int i=2; i >= 0; --i)
4073 if (IFlags & (1 << i))
4081 case k_ShifterImmediate:
4082 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4083 <<
" #" << ShifterImm.Imm <<
">";
4085 case k_ShiftedRegister:
4086 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4088 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4090 case k_ShiftedImmediate:
4091 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4093 << RegShiftedImm.ShiftImm <<
">";
4095 case k_RotateImmediate:
4096 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4098 case k_ModifiedImmediate:
4099 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4100 << ModImm.Rot <<
")>";
4102 case k_ConstantPoolImmediate:
4103 OS <<
"<constant_pool_imm #";
4104 MAI.
printExpr(OS, *getConstantPoolImm());
4106 case k_BitfieldDescriptor:
4107 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4108 <<
", width: " <<
Bitfield.Width <<
">";
4110 case k_RegisterList:
4111 case k_RegisterListWithAPSR:
4112 case k_DPRRegisterList:
4113 case k_SPRRegisterList:
4114 case k_FPSRegisterListWithVPR:
4115 case k_FPDRegisterListWithVPR: {
4116 OS <<
"<register_list ";
4118 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4119 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4121 if (++
I <
E) OS <<
", ";
4128 OS <<
"<vector_list " << VectorList.Count <<
" * "
4129 <<
RegName(VectorList.RegNum) <<
">";
4131 case k_VectorListAllLanes:
4132 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4133 <<
RegName(VectorList.RegNum) <<
">";
4135 case k_VectorListIndexed:
4136 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4137 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4143 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4157 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4158 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4159 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4164 unsigned MnemonicOpsEndInd = 1;
4170 static_cast<ARMOperand &
>(*
Operands[1]).getImm()->getKind() ==
4173 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4176 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4178 ++MnemonicOpsEndInd;
4182 bool RHSCondCode =
false;
4183 while (MnemonicOpsEndInd <
Operands.size()) {
4184 auto Op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
4186 if (
Op.isITMask()) {
4188 MnemonicOpsEndInd++;
4189 }
else if (
Op.isToken() &&
4193 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4194 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4200 MnemonicOpsEndInd++;
4203 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4204 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4205 MnemonicOpsEndInd++;
4209 return MnemonicOpsEndInd;
4212bool ARMAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4214 const AsmToken &Tok = getParser().getTok();
4217 Reg = tryParseRegister();
4222ParseStatus ARMAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4224 if (parseRegister(
Reg, StartLoc, EndLoc))
4232MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4233 MCAsmParser &Parser = getParser();
4234 const AsmToken &Tok = Parser.
getTok();
4236 return MCRegister();
4241 Reg = StringSwitch<MCRegister>(lowerCase)
4242 .Case(
"r13", ARM::SP)
4243 .Case(
"r14", ARM::LR)
4244 .Case(
"r15", ARM::PC)
4245 .Case(
"ip", ARM::R12)
4247 .Case(
"a1", ARM::R0)
4248 .Case(
"a2", ARM::R1)
4249 .Case(
"a3", ARM::R2)
4250 .Case(
"a4", ARM::R3)
4251 .Case(
"v1", ARM::R4)
4252 .Case(
"v2", ARM::R5)
4253 .Case(
"v3", ARM::R6)
4254 .Case(
"v4", ARM::R7)
4255 .Case(
"v5", ARM::R8)
4256 .Case(
"v6", ARM::R9)
4257 .Case(
"v7", ARM::R10)
4258 .Case(
"v8", ARM::R11)
4259 .Case(
"sb", ARM::R9)
4260 .Case(
"sl", ARM::R10)
4261 .Case(
"fp", ARM::R11)
4262 .Default(MCRegister());
4268 auto Entry = RegisterReqs.
find(lowerCase);
4270 if (Entry == RegisterReqs.
end())
4271 return MCRegister();
4273 return Entry->getValue();
4277 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4278 return MCRegister();
4285std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4286 MCAsmParser &Parser = getParser();
4287 const AsmToken &Tok = Parser.
getTok();
4289 return std::nullopt;
4292 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4299 .Default(std::nullopt);
4308 MCAsmParser &Parser = getParser();
4311 auto ShiftTyOpt = tryParseShiftToken();
4312 if (ShiftTyOpt == std::nullopt)
4314 auto ShiftTy = ShiftTyOpt.value();
4321 std::unique_ptr<ARMOperand> PrevOp(
4322 (ARMOperand *)
Operands.pop_back_val().release());
4323 if (!PrevOp->isReg())
4324 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4325 MCRegister SrcReg = PrevOp->getReg();
4329 MCRegister ShiftReg;
4341 const MCExpr *ShiftExpr =
nullptr;
4342 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4343 Error(ImmLoc,
"invalid immediate shift value");
4349 Error(ImmLoc,
"invalid immediate shift value");
4355 Imm =
CE->getValue();
4359 Error(ImmLoc,
"immediate shift value out of range");
4369 ShiftReg = tryParseRegister();
4371 Error(L,
"expected immediate or register in shift operand");
4376 "expected immediate or register in shift operand");
4382 Operands.push_back(ARMOperand::CreateShiftedRegister(
4383 ShiftTy, SrcReg, ShiftReg,
Imm, S, EndLoc, *
this));
4385 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg,
Imm,
4398 MCAsmParser &Parser = getParser();
4401 MCRegister
Reg = tryParseRegister();
4405 Operands.push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4407 const AsmToken &ExclaimTok = Parser.
getTok();
4410 ExclaimTok.
getLoc(), *
this));
4422 const MCExpr *ImmVal;
4423 if (getParser().parseExpression(ImmVal))
4427 return TokError(
"immediate value expected for vector index");
4454 if (Name.size() < 2 || Name[0] != CoprocOp)
4456 Name = (Name[1] ==
'r') ? Name.drop_front(2) : Name.drop_front();
4458 switch (Name.size()) {
4481 case '0':
return 10;
4482 case '1':
return 11;
4483 case '2':
return 12;
4484 case '3':
return 13;
4485 case '4':
return 14;
4486 case '5':
return 15;
4493 MCAsmParser &Parser = getParser();
4495 const AsmToken &Tok = Parser.
getTok();
4513 MCAsmParser &Parser = getParser();
4515 const AsmToken &Tok = Parser.
getTok();
4526 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4534 MCAsmParser &Parser = getParser();
4536 const AsmToken &Tok = Parser.
getTok();
4545 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4552 MCAsmParser &Parser = getParser();
4562 if (getParser().parseExpression(Expr))
4563 return Error(Loc,
"illegal expression");
4565 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4567 "coprocessor option must be an immediate in range [0, 255]");
4568 int Val =
CE->getValue();
4576 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4587 if (!getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4591 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4592 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4593 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4594 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4595 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4596 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4597 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4598 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4607 Regs.emplace_back(Enc,
Reg);
4608 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4609 if (J->first == Enc) {
4610 Regs.erase(J.base());
4622 bool AllowRAAC,
bool IsLazyLoadStore,
4624 MCAsmParser &Parser = getParser();
4626 return TokError(
"Token is not a Left Curly Brace");
4633 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4634 MCRegister
Reg = tryParseRegister(AllowOutOfBoundReg);
4636 return Error(RegLoc,
"register expected");
4637 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4638 return Error(RegLoc,
"pseudo-register not allowed");
4649 bool VSCCLRMAdjustEncoding =
false;
4652 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4653 Reg = getDRegFromQReg(
Reg);
4658 const MCRegisterClass *RC;
4659 if (
Reg == ARM::RA_AUTH_CODE ||
4660 getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4661 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4662 else if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg))
4663 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4664 else if (getARMMCRegisterClass(ARM::SPRRegClassID).
contains(
Reg))
4665 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4666 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg))
4667 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4668 else if (
Reg == ARM::VPR)
4669 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4671 return Error(RegLoc,
"invalid register in register list");
4683 if (
Reg == ARM::RA_AUTH_CODE)
4684 return Error(RegLoc,
"pseudo-register not allowed");
4687 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4689 return Error(AfterMinusLoc,
"register expected");
4690 if (EndReg == ARM::RA_AUTH_CODE)
4691 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4693 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4694 EndReg = getDRegFromQReg(EndReg) + 1;
4701 return Error(AfterMinusLoc,
"invalid register in register list");
4704 return Error(AfterMinusLoc,
"bad range in register list");
4707 while (
Reg != EndReg) {
4710 if (VSCCLRMAdjustEncoding)
4713 Warning(AfterMinusLoc, StringRef(
"duplicated register (") +
4715 ") in register list");
4722 MCRegister OldReg =
Reg;
4724 const AsmToken RegTok = Parser.
getTok();
4725 Reg = tryParseRegister(AllowOutOfBoundReg);
4727 return Error(RegLoc,
"register expected");
4728 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4729 return Error(RegLoc,
"pseudo-register not allowed");
4731 bool isQReg =
false;
4732 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4733 Reg = getDRegFromQReg(
Reg);
4737 RC->
getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4738 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg)) {
4741 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4743 if (
Reg == ARM::VPR &&
4744 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4746 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4747 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4751 ") in register list");
4757 if (IsVSCCLRM && OldReg == ARM::S31 &&
Reg ==
ARM::D16) {
4758 VSCCLRMAdjustEncoding =
true;
4759 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4762 if ((
Reg == ARM::RA_AUTH_CODE &&
4763 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4765 return Error(RegLoc,
"invalid register in register list");
4771 if (VSCCLRMAdjustEncoding)
4773 if (EnforceOrder && EReg < EOldReg) {
4774 if (getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4775 Warning(RegLoc,
"register list not in ascending order");
4776 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4778 return Error(RegLoc,
"register list not in ascending order");
4781 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4782 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4783 EReg != EOldReg + 1)
4784 return Error(RegLoc,
"non-contiguous register range");
4788 ") in register list");
4808 ARMOperand::CreateToken(
"^", Parser.
getTok().
getLoc(), *
this));
4816ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4817 unsigned &Index, SMLoc &EndLoc) {
4818 MCAsmParser &Parser = getParser();
4824 LaneKind = AllLanes;
4835 const MCExpr *LaneIndex;
4837 if (getParser().parseExpression(LaneIndex))
4838 return Error(Loc,
"illegal expression");
4841 return Error(Loc,
"lane index must be empty or an integer");
4846 int64_t Val =
CE->getValue();
4849 if (Val < 0 || Val > 7)
4852 LaneKind = IndexedLane;
4861 MCAsmParser &Parser = getParser();
4862 VectorLaneTy LaneKind;
4872 MCRegister
Reg = tryParseRegister();
4875 if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg)) {
4876 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4881 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4885 ARMOperand::CreateVectorListAllLanes(
Reg, 1,
false, S,
E, *
this));
4888 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4889 Reg, 1, LaneIndex,
false, S,
E, *
this));
4894 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4895 Reg = getDRegFromQReg(
Reg);
4896 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4901 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4905 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4907 ARMOperand::CreateVectorListAllLanes(
Reg, 2,
false, S,
E, *
this));
4910 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4911 Reg, 2, LaneIndex,
false, S,
E, *
this));
4916 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4926 MCRegister
Reg = tryParseRegister();
4928 return Error(RegLoc,
"register expected");
4931 MCRegister FirstReg =
Reg;
4933 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
4935 "vector register in range Q0-Q7 expected");
4938 else if (!hasMVE() &&
4939 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4940 FirstReg =
Reg = getDRegFromQReg(
Reg);
4948 if (!parseVectorLane(LaneKind, LaneIndex,
E).isSuccess())
4956 else if (Spacing == 2)
4958 "sequential registers in double spaced list");
4961 MCRegister EndReg = tryParseRegister();
4963 return Error(AfterMinusLoc,
"register expected");
4966 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4967 EndReg = getDRegFromQReg(EndReg) + 1;
4974 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(EndReg)) ||
4976 !getARMMCRegisterClass(ARM::DPRRegClassID).
contains(EndReg)))
4977 return Error(AfterMinusLoc,
"invalid register in register list");
4980 return Error(AfterMinusLoc,
"bad range in register list");
4982 VectorLaneTy NextLaneKind;
4983 unsigned NextLaneIndex;
4984 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
4986 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4987 return Error(AfterMinusLoc,
"mismatched lane index in register list");
4996 MCRegister OldReg =
Reg;
4997 Reg = tryParseRegister();
4999 return Error(RegLoc,
"register expected");
5002 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
5003 return Error(RegLoc,
"vector register in range Q0-Q7 expected");
5012 else if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
5015 else if (Spacing == 2)
5018 "invalid register in double-spaced list (must be 'D' register')");
5019 Reg = getDRegFromQReg(
Reg);
5020 if (
Reg != OldReg + 1)
5021 return Error(RegLoc,
"non-contiguous register range");
5025 VectorLaneTy NextLaneKind;
5026 unsigned NextLaneIndex;
5028 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5030 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5031 return Error(LaneLoc,
"mismatched lane index in register list");
5038 Spacing = 1 + (
Reg == OldReg + 2);
5041 if (
Reg != OldReg + Spacing)
5042 return Error(RegLoc,
"non-contiguous register range");
5045 VectorLaneTy NextLaneKind;
5046 unsigned NextLaneIndex;
5048 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5050 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5051 return Error(EndLoc,
"mismatched lane index in register list");
5064 if (
Count == 2 && !hasMVE()) {
5065 const MCRegisterClass *RC =
5066 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5067 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5070 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5071 ARMOperand::CreateVectorListAllLanes);
5072 Operands.push_back(Create(FirstReg,
Count, (Spacing == 2), S,
E, *
this));
5076 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5077 FirstReg,
Count, LaneIndex, (Spacing == 2), S,
E, *
this));
5085 MCAsmParser &Parser = getParser();
5087 const AsmToken &Tok = Parser.
getTok();
5093 Opt = StringSwitch<unsigned>(OptStr.
lower())
5128 const MCExpr *MemBarrierID;
5129 if (getParser().parseExpression(MemBarrierID))
5130 return Error(Loc,
"illegal expression");
5134 return Error(Loc,
"constant expression expected");
5136 int Val =
CE->getValue();
5138 return Error(Loc,
"immediate value out of range");
5143 "expected an immediate or barrier type");
5152 MCAsmParser &Parser = getParser();
5154 const AsmToken &Tok = Parser.
getTok();
5165 ARMOperand::CreateTraceSyncBarrierOpt(
ARM_TSB::CSYNC, S, *
this));
5172 MCAsmParser &Parser = getParser();
5174 const AsmToken &Tok = Parser.
getTok();
5193 const MCExpr *ISBarrierID;
5194 if (getParser().parseExpression(ISBarrierID))
5195 return Error(Loc,
"illegal expression");
5199 return Error(Loc,
"constant expression expected");
5201 int Val =
CE->getValue();
5203 return Error(Loc,
"immediate value out of range");
5208 "expected an immediate or barrier type");
5210 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5217 MCAsmParser &Parser = getParser();
5219 const AsmToken &Tok = Parser.
getTok();
5227 if (IFlagsStr !=
"none") {
5228 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
5229 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.
substr(i, 1).
lower())
5237 if (Flag == ~0U || (IFlags & Flag))
5253 if (
static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask() ||
5254 static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg())
5256 MCAsmParser &Parser = getParser();
5258 const AsmToken &Tok = Parser.
getTok();
5262 if (Val > 255 || Val < 0) {
5265 unsigned SYSmvalue = Val & 0xFF;
5267 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5276 auto TheReg = ARMSysReg::lookupMClassSysRegByName(
Mask.lower());
5277 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5280 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5283 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5289 StringRef
Flags =
"";
5290 std::string SpecReg =
Mask.slice(Start,
Next).lower();
5297 unsigned FlagsVal = 0;
5299 if (SpecReg ==
"apsr") {
5300 FlagsVal = StringSwitch<unsigned>(Flags)
5303 .Case(
"nzcvqg", 0xc)
5306 if (FlagsVal == ~0U) {
5312 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
5314 if (Flags ==
"all" || Flags ==
"")
5316 for (
int i = 0, e =
Flags.size(); i != e; ++i) {
5317 unsigned Flag = StringSwitch<unsigned>(
Flags.substr(i, 1))
5326 if (Flag == ~0U || (FlagsVal & Flag))
5342 if (SpecReg ==
"spsr")
5346 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *
this));
5354 if (
static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg() ||
5355 static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask())
5357 MCAsmParser &Parser = getParser();
5359 const AsmToken &Tok = Parser.
getTok();
5364 auto TheReg = ARMBankedReg::lookupBankedRegByName(
RegName.lower());
5367 unsigned Encoding = TheReg->Encoding;
5370 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *
this));
5379 MCAsmParser &Parser = getParser();
5380 auto ShiftCodeOpt = tryParseShiftToken();
5382 if (!ShiftCodeOpt.has_value())
5384 auto ShiftCode = ShiftCodeOpt.value();
5388 if (ShiftCode !=
Op)
5400 const MCExpr *ShiftAmount;
5403 if (getParser().parseExpression(ShiftAmount, EndLoc))
5404 return Error(Loc,
"illegal expression");
5407 return Error(Loc,
"constant expression expected");
5408 int Val =
CE->getValue();
5409 if (Val < Low || Val >
High)
5410 return Error(Loc,
"immediate value out of range");
5412 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *
this));
5418 MCAsmParser &Parser = getParser();
5419 const AsmToken &Tok = Parser.
getTok();
5422 return Error(S,
"'be' or 'le' operand expected");
5430 return Error(S,
"'be' or 'le' operand expected");
5431 Operands.push_back(ARMOperand::CreateImm(
5442 MCAsmParser &Parser = getParser();
5443 const AsmToken &Tok = Parser.
getTok();
5449 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
5451 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5464 const MCExpr *ShiftAmount;
5466 if (getParser().parseExpression(ShiftAmount, EndLoc))
5467 return Error(ExLoc,
"malformed shift expression");
5470 return Error(ExLoc,
"shift amount must be an immediate");
5472 int64_t Val =
CE->getValue();
5475 if (Val < 1 || Val > 32)
5476 return Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
5479 return Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
5480 if (Val == 32) Val = 0;
5483 if (Val < 0 || Val > 31)
5484 return Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
5488 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *
this));
5497 MCAsmParser &Parser = getParser();
5498 const AsmToken &Tok = Parser.
getTok();
5503 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
5514 const MCExpr *ShiftAmount;
5516 if (getParser().parseExpression(ShiftAmount, EndLoc))
5517 return Error(ExLoc,
"malformed rotate expression");
5520 return Error(ExLoc,
"rotate amount must be an immediate");
5522 int64_t Val =
CE->getValue();
5526 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5527 return Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
5529 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *
this));
5535 MCAsmParser &Parser = getParser();
5536 AsmLexer &Lexer = getLexer();
5567 const MCExpr *Imm1Exp;
5568 if (getParser().parseExpression(Imm1Exp, Ex1))
5569 return Error(Sx1,
"malformed expression");
5575 Imm1 =
CE->getValue();
5579 Operands.push_back(ARMOperand::CreateModImm(
5580 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *
this));
5591 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5597 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5604 "expected modified immediate operand: #[0, 255], #even[0-30]");
5607 return Error(Sx1,
"immediate operand must a number in the range [0, 255]");
5621 const MCExpr *Imm2Exp;
5622 if (getParser().parseExpression(Imm2Exp, Ex2))
5623 return Error(Sx2,
"malformed expression");
5628 Imm2 =
CE->getValue();
5629 if (!(Imm2 & ~0x1E)) {
5631 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *
this));
5635 "immediate operand must an even number in the range [0, 30]");
5637 return Error(Sx2,
"constant expression expected");
5642 MCAsmParser &Parser = getParser();
5650 const MCExpr *LSBExpr;
5652 if (getParser().parseExpression(LSBExpr))
5653 return Error(
E,
"malformed immediate expression");
5656 return Error(
E,
"'lsb' operand must be an immediate");
5658 int64_t LSB =
CE->getValue();
5660 if (LSB < 0 || LSB > 31)
5661 return Error(
E,
"'lsb' operand must be in the range [0,31]");
5673 const MCExpr *WidthExpr;
5675 if (getParser().parseExpression(WidthExpr, EndLoc))
5676 return Error(
E,
"malformed immediate expression");
5679 return Error(
E,
"'width' operand must be an immediate");
5681 int64_t Width =
CE->getValue();
5683 if (Width < 1 || Width > 32 - LSB)
5684 return Error(
E,
"'width' operand must be in the range [1,32-lsb]");
5686 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *
this));
5700 MCAsmParser &Parser = getParser();
5701 AsmToken Tok = Parser.
getTok();
5703 bool haveEaten =
false;
5715 MCRegister
Reg = tryParseRegister();
5723 unsigned ShiftImm = 0;
5726 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5734 ARMOperand::CreatePostIdxReg(
Reg, isAdd, ShiftTy, ShiftImm, S,
E, *
this));
5751 MCAsmParser &Parser = getParser();
5752 AsmToken Tok = Parser.
getTok();
5764 if (getParser().parseExpression(
Offset,
E))
5768 return Error(S,
"constant expression expected");
5771 int32_t Val =
CE->getValue();
5772 if (isNegative && Val == 0)
5773 Val = std::numeric_limits<int32_t>::min();
5775 Operands.push_back(ARMOperand::CreateImm(
5781 bool haveEaten =
false;
5793 MCRegister
Reg = tryParseRegister();
5800 Operands.push_back(ARMOperand::CreatePostIdxReg(
5808 unsigned MnemonicOpsEndInd) {
5809 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5810 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5811 if (
Op.isCondCode())
5818 unsigned MnemonicOpsEndInd) {
5819 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5820 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5830void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5837 unsigned RegRd = MnemonicOpsEndInd;
5838 unsigned RegRn = MnemonicOpsEndInd + 1;
5839 unsigned RegRm = MnemonicOpsEndInd;
5841 if (
Operands.size() == MnemonicOpsEndInd + 3) {
5846 RegRn = MnemonicOpsEndInd + 2;
5847 RegRm = MnemonicOpsEndInd + 1;
5849 RegRn = MnemonicOpsEndInd + 1;
5850 RegRm = MnemonicOpsEndInd + 2;
5855 ((ARMOperand &)*
Operands[RegRd]).addRegOperands(Inst, 1);
5857 if (CondOutI != 0) {
5858 ((ARMOperand &)*
Operands[CondOutI]).addCCOutOperands(Inst, 1);
5861 *ARMOperand::CreateCCOut(0,
Operands[0]->getEndLoc(), *
this);
5862 Op.addCCOutOperands(Inst, 1);
5865 ((ARMOperand &)*
Operands[RegRn]).addRegOperands(Inst, 1);
5867 ((ARMOperand &)*
Operands[RegRm]).addRegOperands(Inst, 1);
5871 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5873 ARMOperand
Op = *ARMOperand::CreateCondCode(
5875 Op.addCondCodeOperands(Inst, 2);
5879void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5885 :
static_cast<ARMOperand &
>(*
Operands[CondI]).getCondCode());
5893 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5894 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5913 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5914 if (!
op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5920 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5921 if (!
op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5926 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5928 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5930 ARMOperand
Op = *ARMOperand::CreateCondCode(
5932 Op.addCondCodeOperands(Inst, 2);
5936void ARMAsmParser::cvtMVEVMOVQtoDReg(
5945 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1);
5946 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 1])
5947 .addRegOperands(Inst, 1);
5948 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 2])
5949 .addRegOperands(Inst, 1);
5950 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 3])
5951 .addMVEPairVectorIndexOperands(Inst, 1);
5953 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 5])
5954 .addMVEPairVectorIndexOperands(Inst, 1);
5957 .addCondCodeOperands(Inst, 2);
5961 Op.addCondCodeOperands(Inst, 2);
5968 MCAsmParser &Parser = getParser();
5971 return TokError(
"Token is not a Left Bracket");
5975 const AsmToken &BaseRegTok = Parser.
getTok();
5976 MCRegister
BaseReg = tryParseRegister();
5978 return Error(BaseRegTok.
getLoc(),
"register expected");
5981 const AsmToken &Tok = Parser.
getTok();
5984 return Error(Tok.
getLoc(),
"malformed memory operand");
5990 Operands.push_back(ARMOperand::CreateMem(
5997 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6005 "Lost colon or comma in memory operand?!");
6014 SMLoc AlignmentLoc = Tok.
getLoc();
6017 if (getParser().parseExpression(Expr))
6025 return Error (
E,
"constant expression expected");
6028 switch (
CE->getValue()) {
6031 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6032 case 16:
Align = 2;
break;
6033 case 32:
Align = 4;
break;
6034 case 64:
Align = 8;
break;
6035 case 128:
Align = 16;
break;
6036 case 256:
Align = 32;
break;
6047 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, 0,
6049 S,
E, *
this, AlignmentLoc));
6055 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6075 const MCExpr *
Offset, *AdjustedOffset;
6076 if (getParser().parseExpression(
Offset))
6082 int32_t Val =
CE->getValue();
6083 if (isNegative && Val == 0)
6088 AdjustedOffset =
CE;
6091 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6105 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6113 bool isNegative =
false;
6123 MCRegister OffsetReg = tryParseRegister();
6125 return Error(
E,
"register expected");
6129 unsigned ShiftImm = 0;
6132 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6142 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, OffsetReg,
6143 ShiftType, ShiftImm, 0, isNegative,
6150 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6163 MCAsmParser &Parser = getParser();
6165 const AsmToken &Tok = Parser.
getTok();
6167 return Error(Loc,
"illegal shift operator");
6169 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
6170 ShiftName ==
"asl" || ShiftName ==
"ASL")
6172 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
6174 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
6176 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
6178 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
6180 else if (ShiftName ==
"uxtw" || ShiftName ==
"UXTW")
6183 return Error(Loc,
"illegal shift operator");
6191 const AsmToken &HashTok = Parser.
getTok();
6198 if (getParser().parseExpression(Expr))
6205 return Error(Loc,
"shift amount must be an immediate");
6206 int64_t
Imm =
CE->getValue();
6210 return Error(Loc,
"immediate shift value out of range");
6227 MCAsmParser &Parser = getParser();
6254 bool isVmovf =
false;
6256 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
6257 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*
Operands[
I]);
6258 if (TyOp.isToken() &&
6259 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
6260 TyOp.getToken() ==
".f16")) {
6266 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*
Operands[0]);
6267 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
6268 Mnemonic.getToken() ==
"fconsts");
6269 if (!(isVmovf || isFconst))
6275 bool isNegative =
false;
6280 const AsmToken &Tok = Parser.
getTok();
6281 SMLoc Loc = Tok.
getLoc();
6298 if (Val > 255 || Val < 0)
6299 return Error(Loc,
"encoded floating point value out of range");
6301 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
6309 return Error(Loc,
"invalid floating point immediate");
6315 MCAsmParser &Parser = getParser();
6320 ParseStatus ResTy = MatchOperandParserImpl(
Operands, Mnemonic);
6329 switch (getLexer().getKind()) {
6337 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
6339 if (!tryParseRegisterWithWriteBack(
Operands))
6341 int Res = tryParseShiftRegister(
Operands);
6347 if (Mnemonic ==
"vmrs" &&
6351 Operands.push_back(ARMOperand::CreateToken(
"APSR_nzcv", S, *
this));
6366 const MCExpr *IdVal;
6368 if (getParser().parseExpression(IdVal))
6371 Operands.push_back(ARMOperand::CreateImm(IdVal, S,
E, *
this));
6377 bool IsLazyLoadStore = Mnemonic ==
"vlldm" || Mnemonic ==
"vlstm";
6378 bool IsVSCCLRM = Mnemonic ==
"vscclrm";
6380 IsLazyLoadStore, IsVSCCLRM);
6393 auto AdjacentToken = getLexer().peekTok(
false);
6397 if (!ExpectIdentifier) {
6405 const MCExpr *ImmVal;
6406 if (getParser().parseExpression(ImmVal))
6410 int32_t Val =
CE->getValue();
6411 if (IsNegative && Val == 0)
6416 Operands.push_back(ARMOperand::CreateImm(ImmVal, S,
E, *
this));
6422 Operands.push_back(ARMOperand::CreateToken(
6438 if (parsePrefix(Spec))
6441 const MCExpr *SubExprVal;
6442 if (getParser().parseExpression(SubExprVal))
6445 const auto *ExprVal =
6448 Operands.push_back(ARMOperand::CreateImm(ExprVal, S,
E, *
this));
6453 if (Mnemonic !=
"ldr")
6454 return Error(S,
"unexpected token in operand");
6456 const MCExpr *SubExprVal;
6457 if (getParser().parseExpression(SubExprVal))
6464 ARMOperand::CreateConstantPoolImm(SubExprVal, S,
E, *
this));
6470bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6471 const MCExpr *Expr =
nullptr;
6472 SMLoc
L = getParser().getTok().getLoc();
6473 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
6476 if (check(!
Value, L,
"expected constant expression"))
6478 Out =
Value->getValue();
6486 MCAsmParser &Parser = getParser();
6507 static const struct PrefixEntry {
6508 const char *Spelling;
6510 uint8_t SupportedFormats;
6511 } PrefixEntries[] = {
6523 llvm::find_if(PrefixEntries, [&IDVal](
const PrefixEntry &PE) {
6524 return PE.Spelling == IDVal;
6526 if (Prefix == std::end(PrefixEntries)) {
6531 uint8_t CurrentFormat;
6534 CurrentFormat = MACHO;
6537 CurrentFormat =
ELF;
6540 CurrentFormat =
COFF;
6543 CurrentFormat = WASM;
6553 if (~
Prefix->SupportedFormats & CurrentFormat) {
6555 "cannot represent relocation in the current file format");
6579StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6583 unsigned &ProcessorIMod,
6584 StringRef &ITMask) {
6587 CarrySetting =
false;
6593 if ((Mnemonic ==
"movs" &&
isThumb()) || Mnemonic ==
"teq" ||
6594 Mnemonic ==
"vceq" || Mnemonic ==
"svc" || Mnemonic ==
"mls" ||
6595 Mnemonic ==
"smmls" || Mnemonic ==
"vcls" || Mnemonic ==
"vmls" ||
6596 Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" || Mnemonic ==
"vcge" ||
6597 Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" || Mnemonic ==
"vaclt" ||
6598 Mnemonic ==
"vacle" || Mnemonic ==
"hlt" || Mnemonic ==
"vcgt" ||
6599 Mnemonic ==
"vcle" || Mnemonic ==
"smlal" || Mnemonic ==
"umaal" ||
6600 Mnemonic ==
"umlal" || Mnemonic ==
"vabal" || Mnemonic ==
"vmlal" ||
6601 Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" || Mnemonic ==
"fmuls" ||
6602 Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" ||
6603 Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" ||
6604 Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" ||
6605 Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
6606 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vins" ||
6607 Mnemonic ==
"vmovx" || Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
6608 Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" || Mnemonic ==
"vudot" ||
6609 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6610 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"wls" ||
6611 Mnemonic ==
"le" || Mnemonic ==
"dls" || Mnemonic ==
"csel" ||
6612 Mnemonic ==
"csinc" || Mnemonic ==
"csinv" || Mnemonic ==
"csneg" ||
6613 Mnemonic ==
"cinc" || Mnemonic ==
"cinv" || Mnemonic ==
"cneg" ||
6614 Mnemonic ==
"cset" || Mnemonic ==
"csetm" || Mnemonic ==
"aut" ||
6615 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"bti")
6620 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
6621 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
6622 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
6623 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs" &&
6625 (Mnemonic ==
"vmine" || Mnemonic ==
"vshle" || Mnemonic ==
"vshlt" ||
6626 Mnemonic ==
"vshllt" || Mnemonic ==
"vrshle" || Mnemonic ==
"vrshlt" ||
6627 Mnemonic ==
"vmvne" || Mnemonic ==
"vorne" || Mnemonic ==
"vnege" ||
6628 Mnemonic ==
"vnegt" || Mnemonic ==
"vmule" || Mnemonic ==
"vmult" ||
6629 Mnemonic ==
"vrintne" || Mnemonic ==
"vcmult" ||
6630 Mnemonic ==
"vcmule" || Mnemonic ==
"vpsele" || Mnemonic ==
"vpselt" ||
6634 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
6642 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" || Mnemonic ==
"mrs" ||
6643 Mnemonic ==
"smmls" || Mnemonic ==
"vabs" || Mnemonic ==
"vcls" ||
6644 Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" || Mnemonic ==
"vnmls" ||
6645 Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" || Mnemonic ==
"vrsqrts" ||
6646 Mnemonic ==
"srs" || Mnemonic ==
"flds" || Mnemonic ==
"fmrs" ||
6647 Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" || Mnemonic ==
"fsts" ||
6648 Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" || Mnemonic ==
"fmuls" ||
6649 Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" || Mnemonic ==
"vfms" ||
6650 Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" || Mnemonic ==
"bxns" ||
6651 Mnemonic ==
"blxns" || Mnemonic ==
"vfmas" || Mnemonic ==
"vmlas" ||
6652 (Mnemonic ==
"movs" &&
isThumb()))) {
6653 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
6654 CarrySetting =
true;
6662 StringSwitch<unsigned>(Mnemonic.
substr(Mnemonic.
size()-2, 2))
6667 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
6668 ProcessorIMod =
IMod;
6672 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic !=
"vmovlt" &&
6673 Mnemonic !=
"vshllt" && Mnemonic !=
"vrshrnt" && Mnemonic !=
"vshrnt" &&
6674 Mnemonic !=
"vqrshrunt" && Mnemonic !=
"vqshrunt" &&
6675 Mnemonic !=
"vqrshrnt" && Mnemonic !=
"vqshrnt" && Mnemonic !=
"vmullt" &&
6676 Mnemonic !=
"vqmovnt" && Mnemonic !=
"vqmovunt" && Mnemonic !=
"vmovnt" &&
6677 Mnemonic !=
"vqdmullt" && Mnemonic !=
"vpnot" && Mnemonic !=
"vcvtt" &&
6678 Mnemonic !=
"vcvt") {
6682 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-1);
6690 ITMask = Mnemonic.
substr(2);
6691 Mnemonic = Mnemonic.
slice(0, 2);
6695 ITMask = Mnemonic.
substr(4);
6696 Mnemonic = Mnemonic.
slice(0, 4);
6698 ITMask = Mnemonic.
substr(3);
6699 Mnemonic = Mnemonic.
slice(0, 3);
6709void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6710 StringRef ExtraToken,
6712 bool &CanAcceptCarrySet,
6713 bool &CanAcceptPredicationCode,
6714 bool &CanAcceptVPTPredicationCode) {
6715 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6718 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6719 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
6720 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
6721 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
6722 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
6723 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
6724 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
6726 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
6727 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
6729 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
6730 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
6731 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
6733 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vmaxnm" ||
6734 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
6735 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
6736 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
6737 Mnemonic.
starts_with(
"aes") || Mnemonic ==
"hvc" ||
6738 Mnemonic ==
"setpan" || Mnemonic.
starts_with(
"sha1") ||
6741 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" || Mnemonic ==
"vudot" ||
6742 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6743 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"vfmat" ||
6744 Mnemonic ==
"vfmab" || Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" ||
6745 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" || Mnemonic ==
"pssbb" ||
6746 Mnemonic ==
"vsmmla" || Mnemonic ==
"vummla" || Mnemonic ==
"vusmmla" ||
6747 Mnemonic ==
"vusdot" || Mnemonic ==
"vsudot" || Mnemonic ==
"bfcsel" ||
6748 Mnemonic ==
"wls" || Mnemonic ==
"dls" || Mnemonic ==
"le" ||
6749 Mnemonic ==
"csel" || Mnemonic ==
"csinc" || Mnemonic ==
"csinv" ||
6750 Mnemonic ==
"csneg" || Mnemonic ==
"cinc" || Mnemonic ==
"cinv" ||
6751 Mnemonic ==
"cneg" || Mnemonic ==
"cset" || Mnemonic ==
"csetm" ||
6752 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6753 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6755 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"aut" ||
6756 Mnemonic ==
"bti" ||
6763 CanAcceptPredicationCode =
false;
6766 CanAcceptPredicationCode =
6767 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
6768 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
6769 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
6770 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
6771 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
6772 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" && Mnemonic !=
"tsb" &&
6774 }
else if (isThumbOne()) {
6776 CanAcceptPredicationCode = Mnemonic !=
"movs";
6778 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
6780 CanAcceptPredicationCode =
true;
6784 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I) {
6785 auto &
Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
6786 if (
Op.isToken() &&
Op.getToken() ==
".w")
6796void ARMAsmParser::tryConvertingToTwoOperandForm(
6802 if (
Operands.size() != MnemonicOpsEndInd + 3)
6805 const auto &Op3 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
6806 auto &Op4 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
6807 if (!Op3.isReg() || !Op4.isReg())
6810 auto Op3Reg = Op3.getReg();
6811 auto Op4Reg = Op4.getReg();
6817 auto &Op5 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 2]);
6819 if (Mnemonic !=
"add")
6821 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6822 (Op5.isReg() && Op5.getReg() == ARM::PC);
6823 if (!TryTransform) {
6824 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6825 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6826 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6827 Op5.isImm() && !Op5.isImm0_508s4());
6831 }
else if (!isThumbOne())
6834 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
6835 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6836 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
6837 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
6843 bool Transform = Op3Reg == Op4Reg;
6848 const ARMOperand *LastOp = &Op5;
6850 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6851 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
6852 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
6853 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
6864 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
6870 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
6886 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
6896bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6898 if (!hasMVE() ||
Operands.size() <= MnemonicOpsEndInd)
6912 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6913 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6915 getARMMCRegisterClass(ARM::DPRRegClassID)
6916 .
contains((*Operand).getReg())))) {
6926 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6927 static_cast<ARMOperand &
>(*Operand).isQReg())
6943 unsigned VariantID);
6954void ARMAsmParser::fixupGNULDRDAlias(
StringRef Mnemonic,
6956 unsigned MnemonicOpsEndInd) {
6957 if (Mnemonic !=
"ldrd" && Mnemonic !=
"strd" && Mnemonic !=
"ldrexd" &&
6958 Mnemonic !=
"strexd" && Mnemonic !=
"ldaexd" && Mnemonic !=
"stlexd")
6961 unsigned IdX = Mnemonic ==
"strexd" || Mnemonic ==
"stlexd"
6962 ? MnemonicOpsEndInd + 1
6963 : MnemonicOpsEndInd;
6968 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*
Operands[IdX]);
6969 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*
Operands[IdX + 1]);
6973 if (!Op3.isGPRMem())
6981 if (!
isThumb() && (RtEncoding & 1)) {
6986 if (Op2.getReg() == ARM::PC)
6988 MCRegister PairedReg = GPR.
getRegister(RtEncoding + 1);
6989 if (!PairedReg || PairedReg == ARM::PC ||
6990 (PairedReg == ARM::SP && !hasV8Ops()))
6994 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6995 Op2.getEndLoc(), *
this));
7003bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7005 unsigned MnemonicOpsEndInd) {
7006 assert(MS.isCDEDualRegInstr(Mnemonic));
7008 if (
Operands.size() < 3 + MnemonicOpsEndInd)
7012 "operand must be an even-numbered register in the range [r0, r10]");
7014 const MCParsedAsmOperand &Op2 = *
Operands[MnemonicOpsEndInd + 1];
7045 RPair = ARM::R10_R11;
7049 const MCParsedAsmOperand &Op3 = *
Operands[MnemonicOpsEndInd + 2];
7060 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7061 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCondCode()) {
7063 --MnemonicOpsEndInd;
7069 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7070 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCCOut()) {
7072 --MnemonicOpsEndInd;
7078 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7079 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred()) {
7081 --MnemonicOpsEndInd;
7087bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7089 MCAsmParser &Parser = getParser();
7096 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7097 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7103 parseDirectiveReq(Name, NameLoc);
7111 StringRef Mnemonic =
Name.slice(Start,
Next);
7117 unsigned ProcessorIMod;
7120 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7121 CarrySetting, ProcessorIMod, ITMask);
7124 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
7125 return Error(NameLoc,
"conditional execution not supported in Thumb1");
7128 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7141 if (Mnemonic ==
"it" || Mnemonic.
starts_with(
"vpt") ||
7144 Mnemonic ==
"vpt" ? SMLoc::getFromPointer(NameLoc.
getPointer() + 3) :
7145 SMLoc::getFromPointer(NameLoc.
getPointer() + 4);
7146 if (ITMask.
size() > 3) {
7147 if (Mnemonic ==
"it")
7148 return Error(Loc,
"too many conditions on IT instruction");
7149 return Error(Loc,
"too many conditions on VPT instruction");
7153 if (Pos !=
't' && Pos !=
'e') {
7154 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
7160 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *
this));
7173 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7174 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7175 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7179 if (!CanAcceptCarrySet && CarrySetting) {
7180 return Error(NameLoc,
"instruction '" + Mnemonic +
7181 "' can not set flags, but 's' suffix specified");
7185 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
7186 return Error(NameLoc,
"instruction '" + Mnemonic +
7187 "' is not predicable, but condition code specified");
7192 if (!CanAcceptVPTPredicationCode && VPTPredicationCode !=
ARMVCC::None) {
7193 return Error(NameLoc,
"instruction '" + Mnemonic +
7194 "' is not VPT predicable, but VPT code T/E is specified");
7198 if (CanAcceptCarrySet && CarrySetting) {
7200 Operands.push_back(ARMOperand::CreateCCOut(
7201 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *
this));
7208 Operands.push_back(ARMOperand::CreateCondCode(
7216 !(Mnemonic.
starts_with(
"vcvt") && Mnemonic !=
"vcvta" &&
7217 Mnemonic !=
"vcvtn" && Mnemonic !=
"vcvtp" && Mnemonic !=
"vcvtm")) {
7220 Operands.push_back(ARMOperand::CreateVPTPred(
7225 if (ProcessorIMod) {
7226 Operands.push_back(ARMOperand::CreateImm(
7229 }
else if (Mnemonic ==
"cps" && isMClass()) {
7230 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
7237 ExtraToken =
Name.slice(Start,
Next);
7246 if (ExtraToken ==
".n" && !
isThumb()) {
7248 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
7255 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
7257 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *
this));
7264 unsigned MnemonicOpsEndInd =
Operands.size();
7269 if (parseOperand(
Operands, Mnemonic)) {
7275 if (parseOperand(
Operands, Mnemonic)) {
7284 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7287 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7295 if (MS.isCDEDualRegInstr(Mnemonic)) {
7297 CDEConvertDualRegOperand(Mnemonic,
Operands, MnemonicOpsEndInd);
7304 if (!shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7305 MnemonicOpsEndInd) &&
7306 Mnemonic ==
"vmov" && PredicationCode ==
ARMCC::LT) {
7314 Mnemonic.
size() - 1 + CarrySetting);
7318 StringRef(
"vmovlt"), MLoc, *
this));
7319 }
else if (Mnemonic ==
"vcvt" && PredicationCode ==
ARMCC::NE &&
7320 !shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7321 MnemonicOpsEndInd)) {
7330 Mnemonic.
size() - 1 + CarrySetting);
7334 ARMOperand::CreateToken(StringRef(
"vcvtn"), MLoc, *
this));
7335 }
else if (Mnemonic ==
"vmul" && PredicationCode ==
ARMCC::LT &&
7336 !shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7337 MnemonicOpsEndInd)) {
7345 StringRef(
"vmullt"), MLoc, *
this));
7350 if (!shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7351 MnemonicOpsEndInd)) {
7358 if (Mnemonic.
starts_with(
"vcvtt") && MnemonicOpsEndInd > 2) {
7360 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd - 2]);
7362 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd - 1]);
7363 if (!(Sz1.isToken() && Sz1.getToken().starts_with(
".f") &&
7364 Sz2.isToken() && Sz2.getToken().starts_with(
".f"))) {
7369 Mnemonic = Mnemonic.
substr(0, 4);
7371 ARMOperand::CreateToken(Mnemonic, MLoc, *
this));
7375 Mnemonic.
size() + CarrySetting);
7378 ARMOperand::CreateVPTPred(
7380 ++MnemonicOpsEndInd;
7382 }
else if (CanAcceptVPTPredicationCode) {
7386 if (shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7387 MnemonicOpsEndInd)) {
7394 bool usedVPTPredicationCode =
false;
7396 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred())
7397 usedVPTPredicationCode =
true;
7398 if (!usedVPTPredicationCode) {
7406 Mnemonic =
Name.slice(0, Mnemonic.
size() + 1);
7409 ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7418 if (!
isThumb() && Mnemonic ==
"blx" &&
7419 Operands.size() == MnemonicOpsEndInd + 1 &&
7420 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).isImm())
7424 fixupGNULDRDAlias(Mnemonic,
Operands, MnemonicOpsEndInd);
7433 bool IsLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
7434 if (!
isThumb() &&
Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7435 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
7436 Mnemonic ==
"stlexd")) {
7437 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7438 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*
Operands[Idx]);
7439 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*
Operands[Idx + 1]);
7441 const MCRegisterClass &MRC = MRI->
getRegClass(ARM::GPRRegClassID);
7443 if (Op1.isReg() && MRC.
contains(Op1.getReg())) {
7444 MCRegister Reg1 = Op1.getReg();
7446 MCRegister Reg2 = Op2.getReg();
7450 return Error(Op2.getStartLoc(),
7451 IsLoad ?
"destination operands must be sequential"
7452 :
"source operands must be sequential");
7458 IsLoad ?
"destination operands must start start at an even register"
7459 :
"source operands must start start at an even register");
7462 Reg1, ARM::gsub_0, &(MRI->
getRegClass(ARM::GPRPairRegClassID)));
7463 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7464 Op2.getEndLoc(), *
this);
7474 if (isThumbTwo() && Mnemonic ==
"sub" && CarrySetting &&
7475 Operands.size() == MnemonicOpsEndInd + 3 &&
7476 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).isReg() &&
7477 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).getReg() ==
7479 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]).isReg() &&
7480 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]).getReg() ==
7482 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 2]).isImm()) {
7483 Operands.front() = ARMOperand::CreateToken(
"subs", NameLoc, *
this);
7523 return Inst.
getOpcode() == ARM::tBKPT ||
7530 unsigned MnemonicOpsEndInd) {
7531 for (
unsigned I = MnemonicOpsEndInd;
I <
Operands.size(); ++
I) {
7532 const ARMOperand &
Op =
static_cast<const ARMOperand &
>(*
Operands[
I]);
7533 if (
Op.isRegList()) {
7540bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
7542 unsigned MnemonicOpsEndInd,
7543 unsigned ListIndex,
bool IsARPop) {
7548 if (!IsARPop && ListContainsSP)
7551 "SP may not be in the register list");
7552 if (ListContainsPC && ListContainsLR)
7555 "PC and LR may not be in the register list simultaneously");
7559bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
7561 unsigned MnemonicOpsEndInd,
7562 unsigned ListIndex) {
7566 if (ListContainsSP && ListContainsPC)
7569 "SP and PC may not be in the register list");
7573 "SP may not be in the register list");
7577 "PC may not be in the register list");
7582 bool Load,
bool ARMMode,
bool Writeback,
7583 unsigned MnemonicOpsEndInd) {
7584 unsigned RtIndex =
Load || !Writeback ? 0 : 1;
7597 "Rt must be even-numbered");
7600 if (Rt2 != Rt + 1) {
7603 "destination operands must be sequential");
7606 "source operands must be sequential");
7613 if (!ARMMode &&
Load) {
7616 "destination operands can't be identical");
7622 if (Rn == Rt || Rn == Rt2) {
7625 "base register needs to be different from destination "
7628 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7629 "source register and base register can't be identical");
7640 for (
unsigned i = 0; i <
MCID.NumOperands; ++i) {
7652 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
7659bool ARMAsmParser::validateInstruction(MCInst &Inst,
7661 unsigned MnemonicOpsEndInd) {
7662 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
7663 SMLoc Loc =
Operands[0]->getStartLoc();
7671 return Error(Loc,
"instructions in IT block must be predicable");
7674 if (
Cond != currentITCond()) {
7676 SMLoc CondLoc =
Operands[0]->getEndLoc();
7678 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCondCode())
7680 return Error(CondLoc,
"incorrect condition in IT block; got '" +
7682 "', but expected '" +
7691 return Error(Loc,
"predicated instructions must be in IT block");
7695 return Warning(Loc,
"predicated instructions should be in IT block");
7702 if (MCID.
operands()[i].isPredicate()) {
7704 return Error(Loc,
"instruction is not predicable");
7712 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7713 return Error(Loc,
"instruction must be outside of IT block or the last instruction in an IT block");
7717 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7719 return Error(Loc,
"instruction in VPT block must be predicable");
7722 if (Pred != VPTPred) {
7725 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred())
7727 return Error(PredLoc,
"incorrect predication in VPT block; got '" +
7729 "', but expected '" +
7736 return Error(Loc,
"VPT predicated instructions must be in VPT block");
7738 const unsigned Opcode = Inst.
getOpcode();
7743 case ARM::VLSTM_T2: {
7747 MnemonicOpsEndInd + 2) {
7748 ARMOperand &
Op =
static_cast<ARMOperand &
>(
7751 auto &RegList =
Op.getRegList();
7753 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7754 return Error(
Op.getEndLoc(),
"T2 version requires v8.1-M.Main");
7757 if (hasD32() && RegList.size() != 32) {
7758 return Error(
Op.getEndLoc(),
"operand must be exactly {d0-d31}");
7761 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7763 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7779 return Error(Loc,
"unpredictable IT predicate sequence");
7783 if (validateLDRDSTRD(Inst,
Operands,
true,
true,
7784 false, MnemonicOpsEndInd))
7788 case ARM::LDRD_POST:
7789 if (validateLDRDSTRD(Inst,
Operands,
true,
true,
7790 true, MnemonicOpsEndInd))
7794 if (validateLDRDSTRD(Inst,
Operands,
true,
false,
7795 false, MnemonicOpsEndInd))
7798 case ARM::t2LDRD_PRE:
7799 case ARM::t2LDRD_POST:
7800 if (validateLDRDSTRD(Inst,
Operands,
true,
false,
7801 true, MnemonicOpsEndInd))
7807 if (RmReg == ARM::SP && !hasV8Ops())
7809 "r13 (SP) is an unpredictable operand to BXJ");
7813 if (validateLDRDSTRD(Inst,
Operands,
false,
true,
7814 false, MnemonicOpsEndInd))
7818 case ARM::STRD_POST:
7819 if (validateLDRDSTRD(Inst,
Operands,
false,
true,
7820 true, MnemonicOpsEndInd))
7823 case ARM::t2STRD_PRE:
7824 case ARM::t2STRD_POST:
7825 if (validateLDRDSTRD(Inst,
Operands,
false,
false,
7826 true, MnemonicOpsEndInd))
7829 case ARM::STR_PRE_IMM:
7830 case ARM::STR_PRE_REG:
7831 case ARM::t2STR_PRE:
7832 case ARM::STR_POST_IMM:
7833 case ARM::STR_POST_REG:
7834 case ARM::t2STR_POST:
7836 case ARM::t2STRH_PRE:
7837 case ARM::STRH_POST:
7838 case ARM::t2STRH_POST:
7839 case ARM::STRB_PRE_IMM:
7840 case ARM::STRB_PRE_REG:
7841 case ARM::t2STRB_PRE:
7842 case ARM::STRB_POST_IMM:
7843 case ARM::STRB_POST_REG:
7844 case ARM::t2STRB_POST: {
7850 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7851 "source register and base register can't be identical");
7854 case ARM::t2LDR_PRE_imm:
7855 case ARM::t2LDR_POST_imm:
7856 case ARM::t2STR_PRE_imm:
7857 case ARM::t2STR_POST_imm: {
7864 "destination register and base register can't be identical");
7865 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7866 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7868 if (
Imm > 255 ||
Imm < -255)
7869 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7870 "operand must be in range [-255, 255]");
7872 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7873 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7876 "operand must be a register in range [r0, r14]");
7882 case ARM::t2LDRB_OFFSET_imm:
7883 case ARM::t2LDRB_PRE_imm:
7884 case ARM::t2LDRB_POST_imm:
7885 case ARM::t2STRB_OFFSET_imm:
7886 case ARM::t2STRB_PRE_imm:
7887 case ARM::t2STRB_POST_imm: {
7888 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7889 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7890 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7891 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7893 if (
Imm > 255 ||
Imm < -255)
7894 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7895 "operand must be in range [-255, 255]");
7896 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7897 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7899 if (
Imm > 0 ||
Imm < -255)
7900 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7901 "operand must be in range [0, 255] with a negative sign");
7905 "if operand is PC, should call the LDRB (literal)");
7910 case ARM::t2LDRH_OFFSET_imm:
7911 case ARM::t2LDRH_PRE_imm:
7912 case ARM::t2LDRH_POST_imm:
7913 case ARM::t2STRH_OFFSET_imm:
7914 case ARM::t2STRH_PRE_imm:
7915 case ARM::t2STRH_POST_imm: {
7916 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7917 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7918 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7919 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7921 if (
Imm > 255 ||
Imm < -255)
7922 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7923 "operand must be in range [-255, 255]");
7924 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7925 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7927 if (
Imm > 0 ||
Imm < -255)
7928 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7929 "operand must be in range [0, 255] with a negative sign");
7933 "if operand is PC, should call the LDRH (literal)");
7938 case ARM::t2LDRSB_OFFSET_imm:
7939 case ARM::t2LDRSB_PRE_imm:
7940 case ARM::t2LDRSB_POST_imm: {
7941 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7942 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7944 if (
Imm > 255 ||
Imm < -255)
7945 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7946 "operand must be in range [-255, 255]");
7947 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7949 if (
Imm > 0 ||
Imm < -255)
7950 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7951 "operand must be in range [0, 255] with a negative sign");
7954 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7955 "if operand is PC, should call the LDRH (literal)");
7960 case ARM::t2LDRSH_OFFSET_imm:
7961 case ARM::t2LDRSH_PRE_imm:
7962 case ARM::t2LDRSH_POST_imm: {
7963 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7964 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7966 if (
Imm > 255 ||
Imm < -255)
7967 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7968 "operand must be in range [-255, 255]");
7969 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7971 if (
Imm > 0 ||
Imm < -255)
7972 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7973 "operand must be in range [0, 255] with a negative sign");
7977 "if operand is PC, should call the LDRH (literal)");
7982 case ARM::LDR_PRE_IMM:
7983 case ARM::LDR_PRE_REG:
7984 case ARM::t2LDR_PRE:
7985 case ARM::LDR_POST_IMM:
7986 case ARM::LDR_POST_REG:
7987 case ARM::t2LDR_POST:
7989 case ARM::t2LDRH_PRE:
7990 case ARM::LDRH_POST:
7991 case ARM::t2LDRH_POST:
7992 case ARM::LDRSH_PRE:
7993 case ARM::t2LDRSH_PRE:
7994 case ARM::LDRSH_POST:
7995 case ARM::t2LDRSH_POST:
7996 case ARM::LDRB_PRE_IMM:
7997 case ARM::LDRB_PRE_REG:
7998 case ARM::t2LDRB_PRE:
7999 case ARM::LDRB_POST_IMM:
8000 case ARM::LDRB_POST_REG:
8001 case ARM::t2LDRB_POST:
8002 case ARM::LDRSB_PRE:
8003 case ARM::t2LDRSB_PRE:
8004 case ARM::LDRSB_POST:
8005 case ARM::t2LDRSB_POST: {
8012 "destination register and base register can't be identical");
8016 case ARM::MVE_VLDRBU8_rq:
8017 case ARM::MVE_VLDRBU16_rq:
8018 case ARM::MVE_VLDRBS16_rq:
8019 case ARM::MVE_VLDRBU32_rq:
8020 case ARM::MVE_VLDRBS32_rq:
8021 case ARM::MVE_VLDRHU16_rq:
8022 case ARM::MVE_VLDRHU16_rq_u:
8023 case ARM::MVE_VLDRHU32_rq:
8024 case ARM::MVE_VLDRHU32_rq_u:
8025 case ARM::MVE_VLDRHS32_rq:
8026 case ARM::MVE_VLDRHS32_rq_u:
8027 case ARM::MVE_VLDRWU32_rq:
8028 case ARM::MVE_VLDRWU32_rq_u:
8029 case ARM::MVE_VLDRDU64_rq:
8030 case ARM::MVE_VLDRDU64_rq_u:
8031 case ARM::MVE_VLDRWU32_qi:
8032 case ARM::MVE_VLDRWU32_qi_pre:
8033 case ARM::MVE_VLDRDU64_qi:
8034 case ARM::MVE_VLDRDU64_qi_pre: {
8036 unsigned QdIdx = 0, QmIdx = 2;
8037 bool QmIsPointer =
false;
8039 case ARM::MVE_VLDRWU32_qi:
8040 case ARM::MVE_VLDRDU64_qi:
8044 case ARM::MVE_VLDRWU32_qi_pre:
8045 case ARM::MVE_VLDRDU64_qi_pre:
8056 Twine(
"destination vector register and vector ") +
8057 (QmIsPointer ?
"pointer" :
"offset") +
8058 " register can't be identical");
8070 if (Widthm1 >= 32 - LSB)
8071 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8072 "bitfield width must be in range [1,32-lsb]");
8084 bool HasWritebackToken =
8085 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8087 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8090 bool ListContainsBase;
8095 "registers must be in range r0-r7");
8097 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8100 "writeback operator '!' expected");
8103 if (ListContainsBase && HasWritebackToken)
8104 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8105 "writeback operator '!' not allowed when base register "
8106 "in register list");
8108 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8112 case ARM::LDMIA_UPD:
8113 case ARM::LDMDB_UPD:
8114 case ARM::LDMIB_UPD:
8115 case ARM::LDMDA_UPD:
8122 "writeback register not allowed in register list");
8126 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8131 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8134 case ARM::t2LDMIA_UPD:
8135 case ARM::t2LDMDB_UPD:
8136 case ARM::t2STMIA_UPD:
8137 case ARM::t2STMDB_UPD:
8140 "writeback register not allowed in register list");
8142 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8143 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8146 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8151 case ARM::sysLDMIA_UPD:
8152 case ARM::sysLDMDA_UPD:
8153 case ARM::sysLDMDB_UPD:
8154 case ARM::sysLDMIB_UPD:
8156 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8157 "writeback register only allowed on system LDM "
8158 "if PC in register-list");
8160 case ARM::sysSTMIA_UPD:
8161 case ARM::sysSTMDA_UPD:
8162 case ARM::sysSTMDB_UPD:
8163 case ARM::sysSTMIB_UPD:
8165 "system STM cannot have writeback register");
8170 bool ListContainsBase;
8172 ListContainsBase) &&
8175 "registers must be in range r0-r7 or pc");
8176 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 2, !isMClass()))
8181 bool ListContainsBase;
8183 ListContainsBase) &&
8186 "registers must be in range r0-r7 or lr");
8187 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 2))
8191 case ARM::tSTMIA_UPD: {
8192 bool ListContainsBase, InvalidLowList;
8194 0, ListContainsBase);
8195 if (InvalidLowList && !isThumbTwo())
8196 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8197 "registers must be in range r0-r7");
8201 if (InvalidLowList && ListContainsBase)
8203 "writeback operator '!' not allowed when base register "
8204 "in register list");
8206 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 4))
8213 if (!isThumbTwo() &&
8215 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8216 "source register must be the same as destination");
8226 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8227 "source register must be sp if destination is sp");
8232 if (!(
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]))
8233 .isSignedOffset<11, 1>())
8235 "branch target out of range");
8238 int op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8239 : MnemonicOpsEndInd + 1;
8240 ARMOperand &Operand =
static_cast<ARMOperand &
>(*
Operands[
op]);
8243 !Operand.isSignedOffset<24, 1>())
8244 return Error(
Operands[
op]->getStartLoc(),
"branch target out of range");
8249 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8250 .isSignedOffset<8, 1>())
8252 "branch target out of range");
8255 int Op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8256 : MnemonicOpsEndInd + 1;
8257 if (!
static_cast<ARMOperand &
>(*
Operands[
Op]).isSignedOffset<20, 1>())
8258 return Error(
Operands[
Op]->getStartLoc(),
"branch target out of range");
8263 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8264 .isUnsignedOffset<6, 1>())
8265 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8266 "branch target out of range");
8272 case ARM::t2MOVTi16:
8280 int i = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8281 : MnemonicOpsEndInd + 1;
8282 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[i]);
8283 const MCExpr *
E =
Op.getImm();
8287 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8291 "immediate expression for mov requires :lower16: or :upper16");
8295 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8296 : MnemonicOpsEndInd + 2;
8299 return Error(
Op.getStartLoc(),
8300 "Immediate expression for Thumb adds requires :lower0_7:,"
8301 " :lower8_15:, :upper0_7: or :upper8_15:");
8305 MCParsedAsmOperand &
Op = *
Operands[MnemonicOpsEndInd + 1];
8307 return Error(
Op.getStartLoc(),
8308 "Immediate expression for Thumb movs requires :lower0_7:,"
8309 " :lower8_15:, :upper0_7: or :upper8_15:");
8318 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
8319 return Error(
Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8320 "predicable, but condition "
8323 return Error(
Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8324 "predicable, but condition "
8332 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8333 .isUnsignedOffset<4, 1>() ||
8336 "branch location out of range or not a multiple of 2");
8339 if (Opcode == ARM::t2BFi) {
8340 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8341 .isSignedOffset<16, 1>())
8343 "branch target out of range or not a multiple of 2");
8344 }
else if (Opcode == ARM::t2BFLi) {
8345 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8346 .isSignedOffset<18, 1>())
8348 "branch target out of range or not a multiple of 2");
8353 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8354 .isUnsignedOffset<4, 1>() ||
8357 "branch location out of range or not a multiple of 2");
8359 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8360 .isSignedOffset<16, 1>())
8361 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8362 "branch target out of range or not a multiple of 2");
8365 "branch location and else branch target should either both be "
8366 "immediates or both labels");
8370 if (Diff != 4 && Diff != 2)
8373 "else branch target must be 2 or 4 greater than the branch location");
8380 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8383 "invalid register in register list. Valid registers are "
8384 "r0-r12, lr/r14 and APSR.");
8401 "instruction 'ssbb' is not predicable, but condition code "
8405 "instruction 'pssbb' is not predicable, but condition code "
8409 case ARM::VMOVRRS: {
8414 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8415 "source operands must be sequential");
8418 case ARM::VMOVSRR: {
8424 "destination operands must be sequential");
8428 case ARM::VSTMDIA: {
8430 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
8431 auto &RegList =
Op.getRegList();
8432 if (RegList.size() < 1 || RegList.size() > 16)
8433 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8434 "list of registers must be at least 1 and at most 16");
8437 case ARM::MVE_VQDMULLs32bh:
8438 case ARM::MVE_VQDMULLs32th:
8439 case ARM::MVE_VCMULf32:
8440 case ARM::MVE_VMULLBs32:
8441 case ARM::MVE_VMULLTs32:
8442 case ARM::MVE_VMULLBu32:
8443 case ARM::MVE_VMULLTu32: {
8447 "Qd register and Qn register can't be identical");
8452 "Qd register and Qm register can't be identical");
8456 case ARM::MVE_VREV64_8:
8457 case ARM::MVE_VREV64_16:
8458 case ARM::MVE_VREV64_32:
8459 case ARM::MVE_VQDMULL_qr_s32bh:
8460 case ARM::MVE_VQDMULL_qr_s32th: {
8464 "Qd register and Qn register can't be identical");
8468 case ARM::MVE_VCADDi32:
8469 case ARM::MVE_VCADDf32:
8470 case ARM::MVE_VHCADDs32: {
8474 "Qd register and Qm register can't be identical");
8478 case ARM::MVE_VMOV_rr_q: {
8481 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8482 "Q-registers must be the same");
8483 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8484 .getVectorIndex() !=
8485 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 5])
8488 return Error(
Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8489 "Q-register indexes must be 2 and 0 or 3 and 1");
8492 case ARM::MVE_VMOV_q_rr: {
8496 "Q-registers must be the same");
8497 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8498 .getVectorIndex() !=
8499 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8502 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8503 "Q-register indexes must be 2 and 0 or 3 and 1");
8506 case ARM::MVE_SQRSHR:
8507 case ARM::MVE_UQRSHL: {
8511 "Rda register and Rm register can't be identical");
8532 case ARM::t2SMLALBB:
8533 case ARM::t2SMLALBT:
8535 case ARM::t2SMLALDX:
8536 case ARM::t2SMLALTB:
8537 case ARM::t2SMLALTT:
8539 case ARM::t2SMLSLDX:
8540 case ARM::t2SMULL: {
8545 "unpredictable instruction, RdHi and RdLo must be different");
8553 case ARM::CDE_CX1DA:
8557 case ARM::CDE_CX2DA:
8561 case ARM::CDE_CX3DA:
8562 case ARM::CDE_VCX1_vec:
8563 case ARM::CDE_VCX1_fpsp:
8564 case ARM::CDE_VCX1_fpdp:
8565 case ARM::CDE_VCX1A_vec:
8566 case ARM::CDE_VCX1A_fpsp:
8567 case ARM::CDE_VCX1A_fpdp:
8568 case ARM::CDE_VCX2_vec:
8569 case ARM::CDE_VCX2_fpsp:
8570 case ARM::CDE_VCX2_fpdp:
8571 case ARM::CDE_VCX2A_vec:
8572 case ARM::CDE_VCX2A_fpsp:
8573 case ARM::CDE_VCX2A_fpdp:
8574 case ARM::CDE_VCX3_vec:
8575 case ARM::CDE_VCX3_fpsp:
8576 case ARM::CDE_VCX3_fpdp:
8577 case ARM::CDE_VCX3A_vec:
8578 case ARM::CDE_VCX3A_fpsp:
8579 case ARM::CDE_VCX3A_fpdp: {
8581 "CDE operand 1 must be a coprocessor ID");
8585 "coprocessor must be configured as CDE");
8586 else if (Coproc >= 8)
8588 "coprocessor must be in the range [p0, p7]");
8594 case ARM::t2LDC2L_OFFSET:
8595 case ARM::t2LDC2L_OPTION:
8596 case ARM::t2LDC2L_POST:
8597 case ARM::t2LDC2L_PRE:
8598 case ARM::t2LDC2_OFFSET:
8599 case ARM::t2LDC2_OPTION:
8600 case ARM::t2LDC2_POST:
8601 case ARM::t2LDC2_PRE:
8602 case ARM::t2LDCL_OFFSET:
8603 case ARM::t2LDCL_OPTION:
8604 case ARM::t2LDCL_POST:
8605 case ARM::t2LDCL_PRE:
8606 case ARM::t2LDC_OFFSET:
8607 case ARM::t2LDC_OPTION:
8608 case ARM::t2LDC_POST:
8609 case ARM::t2LDC_PRE:
8618 case ARM::t2STC2L_OFFSET:
8619 case ARM::t2STC2L_OPTION:
8620 case ARM::t2STC2L_POST:
8621 case ARM::t2STC2L_PRE:
8622 case ARM::t2STC2_OFFSET:
8623 case ARM::t2STC2_OPTION:
8624 case ARM::t2STC2_POST:
8625 case ARM::t2STC2_PRE:
8626 case ARM::t2STCL_OFFSET:
8627 case ARM::t2STCL_OPTION:
8628 case ARM::t2STCL_POST:
8629 case ARM::t2STCL_PRE:
8630 case ARM::t2STC_OFFSET:
8631 case ARM::t2STC_OPTION:
8632 case ARM::t2STC_POST:
8633 case ARM::t2STC_PRE: {
8638 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8640 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8643 "Operand must be a coprocessor ID");
8648 "coprocessor must be configured as GCP");
8679 "source and destination registers must be the same");
8691 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8693 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8694 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8695 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8696 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8697 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8698 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8699 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8702 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8704 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8706 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8708 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8709 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8710 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8711 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8712 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8714 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8715 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8716 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8717 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8718 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8721 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8723 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8725 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8726 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8727 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8728 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8729 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8730 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8731 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8732 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8733 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8734 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8735 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8738 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8739 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8740 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8741 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8742 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8743 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8744 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8745 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8746 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8747 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8748 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8749 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8750 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8751 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8752 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8753 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8754 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8755 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8758 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8760 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8762 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8763 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8764 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8765 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8766 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8767 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8768 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8769 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8770 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8771 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8772 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8775 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8776 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8777 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8778 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8779 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8780 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8781 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8782 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8783 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8784 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8785 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8786 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8787 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8788 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8789 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8790 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8791 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8792 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8800 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8802 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8805 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8806 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8807 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8808 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8811 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8813 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8815 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8818 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8820 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8821 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8822 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8823 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8824 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8825 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8828 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8830 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8833 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8836 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8839 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8840 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8841 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8842 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8843 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8844 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8845 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8848 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8850 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8852 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8855 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8857 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8858 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8859 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8860 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8861 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8862 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8865 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8867 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8870 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8871 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8872 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8873 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8874 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8875 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8876 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8877 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8878 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8879 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8880 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8881 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8882 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8885 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8887 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8889 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8892 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8894 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8895 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8896 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8897 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8898 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8899 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8902 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8904 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8907 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8910 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8913 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8914 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8915 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8916 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8917 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8918 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8919 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8922 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8924 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8927 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8928 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8929 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8930 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8931 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8932 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8933 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8934 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8935 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8936 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8937 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8938 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8939 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8943bool ARMAsmParser::processInstruction(MCInst &Inst,
8945 unsigned MnemonicOpsEndInd,
8949 bool HasWideQualifier =
false;
8951 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8952 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8953 HasWideQualifier =
true;
8964 MnemonicOpsEndInd + 2) {
8965 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8968 auto &RegList =
Op.getRegList();
8971 if (RegList.size() == 32) {
8972 const unsigned Opcode =
8973 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8987 case ARM::LDRT_POST:
8988 case ARM::LDRBT_POST: {
8989 const unsigned Opcode =
8990 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8991 : ARM::LDRBT_POST_IMM;
9007 case ARM::LDRSHTii: {
9012 else if (Inst.
getOpcode() == ARM::LDRHTii)
9014 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9025 case ARM::STRT_POST:
9026 case ARM::STRBT_POST: {
9027 const unsigned Opcode =
9028 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9029 : ARM::STRBT_POST_IMM;
9078 case ARM::t2LDR_PRE_imm:
9079 case ARM::t2LDR_POST_imm: {
9093 case ARM::t2STR_PRE_imm:
9094 case ARM::t2STR_POST_imm: {
9108 case ARM::t2LDRB_OFFSET_imm: {
9118 case ARM::t2LDRB_PRE_imm:
9119 case ARM::t2LDRB_POST_imm: {
9123 : ARM::t2LDRB_POST);
9134 case ARM::t2STRB_OFFSET_imm: {
9144 case ARM::t2STRB_PRE_imm:
9145 case ARM::t2STRB_POST_imm: {
9149 : ARM::t2STRB_POST);
9160 case ARM::t2LDRH_OFFSET_imm: {
9170 case ARM::t2LDRH_PRE_imm:
9171 case ARM::t2LDRH_POST_imm: {
9175 : ARM::t2LDRH_POST);
9186 case ARM::t2STRH_OFFSET_imm: {
9196 case ARM::t2STRH_PRE_imm:
9197 case ARM::t2STRH_POST_imm: {
9201 : ARM::t2STRH_POST);
9212 case ARM::t2LDRSB_OFFSET_imm: {
9222 case ARM::t2LDRSB_PRE_imm:
9223 case ARM::t2LDRSB_POST_imm: {
9227 : ARM::t2LDRSB_POST);
9238 case ARM::t2LDRSH_OFFSET_imm: {
9248 case ARM::t2LDRSH_PRE_imm:
9249 case ARM::t2LDRSH_POST_imm: {
9253 : ARM::t2LDRSH_POST);
9264 case ARM::t2LDRpcrel:
9273 case ARM::t2LDRBpcrel:
9276 case ARM::t2LDRHpcrel:
9279 case ARM::t2LDRSBpcrel:
9282 case ARM::t2LDRSHpcrel:
9285 case ARM::LDRConstPool:
9286 case ARM::tLDRConstPool:
9287 case ARM::t2LDRConstPool: {
9292 if (Inst.
getOpcode() == ARM::LDRConstPool)
9294 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9296 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9298 const ARMOperand &PoolOperand =
9299 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
9300 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9308 bool MovHasS =
true;
9309 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9319 else if (hasV6T2Ops() &&
9332 else if (hasThumb2() &&
9337 else if (hasV8MBaseline() &&
9357 const MCExpr *CPLoc =
9358 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9359 PoolOperand.getStartLoc());
9370 case ARM::VST1LNdWB_register_Asm_8:
9371 case ARM::VST1LNdWB_register_Asm_16:
9372 case ARM::VST1LNdWB_register_Asm_32: {
9390 case ARM::VST2LNdWB_register_Asm_8:
9391 case ARM::VST2LNdWB_register_Asm_16:
9392 case ARM::VST2LNdWB_register_Asm_32:
9393 case ARM::VST2LNqWB_register_Asm_16:
9394 case ARM::VST2LNqWB_register_Asm_32: {
9414 case ARM::VST3LNdWB_register_Asm_8:
9415 case ARM::VST3LNdWB_register_Asm_16:
9416 case ARM::VST3LNdWB_register_Asm_32:
9417 case ARM::VST3LNqWB_register_Asm_16:
9418 case ARM::VST3LNqWB_register_Asm_32: {
9440 case ARM::VST4LNdWB_register_Asm_8:
9441 case ARM::VST4LNdWB_register_Asm_16:
9442 case ARM::VST4LNdWB_register_Asm_32:
9443 case ARM::VST4LNqWB_register_Asm_16:
9444 case ARM::VST4LNqWB_register_Asm_32: {
9468 case ARM::VST1LNdWB_fixed_Asm_8:
9469 case ARM::VST1LNdWB_fixed_Asm_16:
9470 case ARM::VST1LNdWB_fixed_Asm_32: {
9488 case ARM::VST2LNdWB_fixed_Asm_8:
9489 case ARM::VST2LNdWB_fixed_Asm_16:
9490 case ARM::VST2LNdWB_fixed_Asm_32:
9491 case ARM::VST2LNqWB_fixed_Asm_16:
9492 case ARM::VST2LNqWB_fixed_Asm_32: {
9512 case ARM::VST3LNdWB_fixed_Asm_8:
9513 case ARM::VST3LNdWB_fixed_Asm_16:
9514 case ARM::VST3LNdWB_fixed_Asm_32:
9515 case ARM::VST3LNqWB_fixed_Asm_16:
9516 case ARM::VST3LNqWB_fixed_Asm_32: {
9538 case ARM::VST4LNdWB_fixed_Asm_8:
9539 case ARM::VST4LNdWB_fixed_Asm_16:
9540 case ARM::VST4LNdWB_fixed_Asm_32:
9541 case ARM::VST4LNqWB_fixed_Asm_16:
9542 case ARM::VST4LNqWB_fixed_Asm_32: {
9566 case ARM::VST1LNdAsm_8:
9567 case ARM::VST1LNdAsm_16:
9568 case ARM::VST1LNdAsm_32: {