69#define DEBUG_TYPE "asm-parser"
76enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
79 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
80 cl::desc(
"Allow conditional instructions outside of an IT block"),
82 "Accept in both ISAs, emit implicit ITs in Thumb"),
84 "Warn in ARM, reject in Thumb"),
86 "Accept in ARM, reject in Thumb"),
87 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
88 "Warn in ARM, emit implicit ITs in Thumb")));
93enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
95static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
102 return (Mask >> (5 - Position) & 1);
111 Locs PersonalityLocs;
112 Locs PersonalityIndexLocs;
113 Locs HandlerDataLocs;
119 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
120 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
121 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
123 bool hasPersonality()
const {
124 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
127 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
128 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
129 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
130 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
131 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
136 void emitFnStartLocNotes()
const {
138 Parser.
Note(
Loc,
".fnstart was specified here");
141 void emitCantUnwindLocNotes()
const {
143 Parser.
Note(
Loc,
".cantunwind was specified here");
146 void emitHandlerDataLocNotes()
const {
148 Parser.
Note(
Loc,
".handlerdata was specified here");
151 void emitPersonalityLocNotes()
const {
153 PE = PersonalityLocs.end(),
154 PII = PersonalityIndexLocs.begin(),
155 PIE = PersonalityIndexLocs.end();
156 PI != PE || PII != PIE;) {
157 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
158 Parser.
Note(*PI++,
".personality was specified here");
159 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
160 Parser.
Note(*PII++,
".personalityindex was specified here");
163 "at the same location");
168 FnStartLocs = Locs();
169 CantUnwindLocs = Locs();
170 PersonalityLocs = Locs();
171 HandlerDataLocs = Locs();
172 PersonalityIndexLocs = Locs();
178class ARMMnemonicSets {
189 return CDE.
count(Mnemonic);
194 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
197 return CDEWithVPTSuffix.
count(Mnemonic);
202 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
212 bool isCDEDualRegInstr(
StringRef Mnemonic) {
215 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
216 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
217 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
222 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
223 "cx2",
"cx2a",
"cx2d",
"cx2da",
224 "cx3",
"cx3a",
"cx3d",
"cx3da", })
227 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
229 CDEWithVPTSuffix.
insert(Mnemonic);
230 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"t");
231 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"e");
241 assert(getParser().getStreamer().getTargetStreamer() &&
242 "do not have a target streamer");
250 bool NextSymbolIsThumb;
252 bool useImplicitITThumb()
const {
253 return ImplicitItMode == ImplicitItModeTy::Always ||
254 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
257 bool useImplicitITARM()
const {
258 return ImplicitItMode == ImplicitItModeTy::Always ||
259 ImplicitItMode == ImplicitItModeTy::ARMOnly;
274 unsigned CurPosition;
289 void onEndOfFile()
override {
290 flushPendingInstructions(getParser().getStreamer());
293 void flushPendingInstructions(
MCStreamer &Out)
override {
294 if (!inImplicitITBlock()) {
308 for (
const MCInst &Inst : PendingConditionalInsts) {
311 PendingConditionalInsts.clear();
315 ITState.CurPosition = ~0U;
318 bool inITBlock() {
return ITState.CurPosition != ~0U; }
319 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
320 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
322 bool lastInITBlock() {
326 void forwardITPosition() {
327 if (!inITBlock())
return;
332 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
333 ITState.CurPosition = ~0U;
337 void rewindImplicitITPosition() {
338 assert(inImplicitITBlock());
339 assert(ITState.CurPosition > 1);
340 ITState.CurPosition--;
342 unsigned NewMask = 0;
343 NewMask |= ITState.Mask & (0xC << TZ);
344 NewMask |= 0x2 << TZ;
345 ITState.Mask = NewMask;
350 void discardImplicitITBlock() {
351 assert(inImplicitITBlock());
352 assert(ITState.CurPosition == 1);
353 ITState.CurPosition = ~0U;
358 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
364 void invertCurrentITCondition() {
365 if (ITState.CurPosition == 1) {
368 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
373 bool isITBlockFull() {
374 return inITBlock() && (ITState.Mask & 1);
380 assert(inImplicitITBlock());
385 unsigned NewMask = 0;
387 NewMask |= ITState.Mask & (0xE << TZ);
389 NewMask |= (
Cond != ITState.Cond) << TZ;
391 NewMask |= 1 << (TZ - 1);
392 ITState.Mask = NewMask;
396 void startImplicitITBlock() {
400 ITState.CurPosition = 1;
401 ITState.IsExplicit =
false;
412 ITState.CurPosition = 0;
413 ITState.IsExplicit =
true;
418 unsigned CurPosition;
420 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
421 void forwardVPTPosition() {
422 if (!inVPTBlock())
return;
424 if (++VPTState.CurPosition == 5 - TZ)
425 VPTState.CurPosition = ~0U;
429 return getParser().Note(L,
Msg,
Range);
433 return getParser().Warning(L,
Msg,
Range);
437 return getParser().Error(L,
Msg,
Range);
441 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
442 bool IsARPop =
false);
444 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
446 MCRegister tryParseRegister(
bool AllowOutofBoundReg =
false);
449 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
450 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
451 bool AllowRAAC =
false,
bool IsLazyLoadStore =
false,
452 bool IsVSCCLRM =
false);
455 bool parseImmExpr(int64_t &Out);
458 unsigned &ShiftAmount);
459 bool parseLiteralValues(
unsigned Size,
SMLoc L);
460 bool parseDirectiveThumb(
SMLoc L);
461 bool parseDirectiveARM(
SMLoc L);
462 bool parseDirectiveThumbFunc(
SMLoc L);
463 bool parseDirectiveCode(
SMLoc L);
464 bool parseDirectiveSyntax(
SMLoc L);
466 bool parseDirectiveUnreq(
SMLoc L);
467 bool parseDirectiveArch(
SMLoc L);
468 bool parseDirectiveEabiAttr(
SMLoc L);
469 bool parseDirectiveCPU(
SMLoc L);
470 bool parseDirectiveFPU(
SMLoc L);
471 bool parseDirectiveFnStart(
SMLoc L);
472 bool parseDirectiveFnEnd(
SMLoc L);
473 bool parseDirectiveCantUnwind(
SMLoc L);
474 bool parseDirectivePersonality(
SMLoc L);
475 bool parseDirectiveHandlerData(
SMLoc L);
476 bool parseDirectiveSetFP(
SMLoc L);
477 bool parseDirectivePad(
SMLoc L);
478 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
479 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
480 bool parseDirectiveLtorg(
SMLoc L);
481 bool parseDirectiveEven(
SMLoc L);
482 bool parseDirectivePersonalityIndex(
SMLoc L);
483 bool parseDirectiveUnwindRaw(
SMLoc L);
484 bool parseDirectiveTLSDescSeq(
SMLoc L);
485 bool parseDirectiveMovSP(
SMLoc L);
486 bool parseDirectiveObjectArch(
SMLoc L);
487 bool parseDirectiveArchExtension(
SMLoc L);
488 bool parseDirectiveAlign(
SMLoc L);
489 bool parseDirectiveThumbSet(
SMLoc L);
491 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
492 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
493 bool parseDirectiveSEHSaveSP(
SMLoc L);
494 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
495 bool parseDirectiveSEHSaveLR(
SMLoc L);
496 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
497 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
498 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
499 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
500 bool parseDirectiveSEHCustom(
SMLoc L);
502 std::unique_ptr<ARMOperand> defaultCondCodeOp();
503 std::unique_ptr<ARMOperand> defaultCCOutOp();
504 std::unique_ptr<ARMOperand> defaultVPTPredOp();
510 bool &CarrySetting,
unsigned &ProcessorIMod,
513 StringRef FullInst,
bool &CanAcceptCarrySet,
514 bool &CanAcceptPredicationCode,
515 bool &CanAcceptVPTPredicationCode);
518 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
521 unsigned MnemonicOpsEndInd);
524 unsigned MnemonicOpsEndInd);
528 return getSTI().hasFeature(ARM::ModeThumb);
531 bool isThumbOne()
const {
532 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
535 bool isThumbTwo()
const {
536 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
539 bool hasThumb()
const {
540 return getSTI().hasFeature(ARM::HasV4TOps);
543 bool hasThumb2()
const {
544 return getSTI().hasFeature(ARM::FeatureThumb2);
547 bool hasV6Ops()
const {
548 return getSTI().hasFeature(ARM::HasV6Ops);
551 bool hasV6T2Ops()
const {
552 return getSTI().hasFeature(ARM::HasV6T2Ops);
555 bool hasV6MOps()
const {
556 return getSTI().hasFeature(ARM::HasV6MOps);
559 bool hasV7Ops()
const {
560 return getSTI().hasFeature(ARM::HasV7Ops);
563 bool hasV8Ops()
const {
564 return getSTI().hasFeature(ARM::HasV8Ops);
567 bool hasV8MBaseline()
const {
568 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
571 bool hasV8MMainline()
const {
572 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
574 bool hasV8_1MMainline()
const {
575 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
577 bool hasMVEFloat()
const {
578 return getSTI().hasFeature(ARM::HasMVEFloatOps);
580 bool hasCDE()
const {
581 return getSTI().hasFeature(ARM::HasCDEOps);
583 bool has8MSecExt()
const {
584 return getSTI().hasFeature(ARM::Feature8MSecExt);
587 bool hasARM()
const {
588 return !getSTI().hasFeature(ARM::FeatureNoARM);
591 bool hasDSP()
const {
592 return getSTI().hasFeature(ARM::FeatureDSP);
595 bool hasD32()
const {
596 return getSTI().hasFeature(ARM::FeatureD32);
599 bool hasV8_1aOps()
const {
600 return getSTI().hasFeature(ARM::HasV8_1aOps);
603 bool hasRAS()
const {
604 return getSTI().hasFeature(ARM::FeatureRAS);
609 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
610 setAvailableFeatures(FB);
613 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
615 bool isMClass()
const {
616 return getSTI().hasFeature(ARM::FeatureMClass);
622#define GET_ASSEMBLER_HEADER
623#include "ARMGenAsmMatcher.inc"
654 ParseStatus parseVectorLane(VectorLaneTy &LaneKind,
unsigned &Index,
663 unsigned MnemonicOpsEndInd);
665 unsigned MnemonicOpsEndInd, MCStreamer &Out);
666 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
668 unsigned MnemonicOpsEndInd);
669 bool isITBlockTerminator(MCInst &Inst)
const;
672 unsigned MnemonicOpsEndInd);
674 bool ARMMode,
bool Writeback,
675 unsigned MnemonicOpsEndInd);
678 enum ARMMatchResultTy {
679 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
680 Match_RequiresNotITBlock,
682 Match_RequiresThumb2,
684 Match_RequiresFlagSetting,
685#define GET_OPERAND_DIAGNOSTIC_TYPES
686#include "ARMGenAsmMatcher.inc"
690 ARMAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
691 const MCInstrInfo &MII)
692 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
699 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
703 getTargetStreamer().emitTargetAttributes(STI);
706 ITState.CurPosition = ~0
U;
708 VPTState.CurPosition = ~0
U;
710 NextSymbolIsThumb =
false;
714 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
715 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
716 SMLoc &EndLoc)
override;
717 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
719 bool ParseDirective(AsmToken DirectiveID)
override;
721 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
722 unsigned Kind)
override;
723 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
725 checkEarlyTargetMatchPredicate(MCInst &Inst,
728 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
731 bool MatchingInlineAsm)
override;
733 SmallVectorImpl<NearMissInfo> &NearMisses,
734 bool MatchingInlineAsm,
bool &EmitInITBlock,
737 struct NearMissMessage {
739 SmallString<128> Message;
742 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
744 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
745 SmallVectorImpl<NearMissMessage> &NearMissesOut,
747 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
750 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
752 void onLabelParsed(MCSymbol *Symbol)
override;
754 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
755 return MII.get(Opcode);
758 bool hasMVE()
const {
return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
761 MCRegister getDRegFromQReg(MCRegister QReg)
const {
762 return MRI->
getSubReg(QReg, ARM::dsub_0);
765 const MCRegisterInfo *getMRI()
const {
return MRI; }
770class ARMOperand :
public MCParsedAsmOperand {
781 k_InstSyncBarrierOpt,
782 k_TraceSyncBarrierOpt,
791 k_RegisterListWithAPSR,
794 k_FPSRegisterListWithVPR,
795 k_FPDRegisterListWithVPR,
797 k_VectorListAllLanes,
804 k_ConstantPoolImmediate,
805 k_BitfieldDescriptor,
809 SMLoc StartLoc, EndLoc, AlignmentLoc;
812 ARMAsmParser *Parser;
826 struct CoprocOptionOp {
868 struct VectorListOp {
875 struct VectorIndexOp {
885 MCRegister BaseRegNum;
888 const MCExpr *OffsetImm;
889 MCRegister OffsetRegNum;
894 unsigned isNegative : 1;
897 struct PostIdxRegOp {
904 struct ShifterImmOp {
909 struct RegShiftedRegOp {
916 struct RegShiftedImmOp {
940 struct CoprocOptionOp CoprocOption;
941 struct MBOptOp MBOpt;
942 struct ISBOptOp ISBOpt;
943 struct TSBOptOp TSBOpt;
944 struct ITMaskOp ITMask;
946 struct MMaskOp MMask;
947 struct BankedRegOp BankedReg;
950 struct VectorListOp VectorList;
951 struct VectorIndexOp VectorIndex;
953 struct MemoryOp Memory;
954 struct PostIdxRegOp PostIdxReg;
955 struct ShifterImmOp ShifterImm;
956 struct RegShiftedRegOp RegShiftedReg;
957 struct RegShiftedImmOp RegShiftedImm;
958 struct RotImmOp RotImm;
959 struct ModImmOp ModImm;
964 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(
K), Parser(&Parser) {}
967 SMLoc getStartLoc()
const override {
return StartLoc; }
970 SMLoc getEndLoc()
const override {
return EndLoc; }
974 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
977 SMLoc getAlignmentLoc()
const {
978 assert(Kind == k_Memory &&
"Invalid access!");
983 assert(Kind == k_CondCode &&
"Invalid access!");
988 assert(isVPTPred() &&
"Invalid access!");
992 unsigned getCoproc()
const {
993 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
998 assert(Kind == k_Token &&
"Invalid access!");
999 return StringRef(Tok.Data, Tok.Length);
1002 MCRegister
getReg()
const override {
1003 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1007 const SmallVectorImpl<MCRegister> &getRegList()
const {
1008 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1009 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1010 Kind == k_FPSRegisterListWithVPR ||
1011 Kind == k_FPDRegisterListWithVPR) &&
1016 const MCExpr *
getImm()
const {
1017 assert(isImm() &&
"Invalid access!");
1021 const MCExpr *getConstantPoolImm()
const {
1022 assert(isConstantPoolImm() &&
"Invalid access!");
1026 unsigned getVectorIndex()
const {
1027 assert(Kind == k_VectorIndex &&
"Invalid access!");
1028 return VectorIndex.Val;
1032 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1037 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1042 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1047 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1051 unsigned getMSRMask()
const {
1052 assert(Kind == k_MSRMask &&
"Invalid access!");
1056 unsigned getBankedReg()
const {
1057 assert(Kind == k_BankedReg &&
"Invalid access!");
1058 return BankedReg.Val;
1061 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1062 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1063 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1064 bool isCondCode()
const {
return Kind == k_CondCode; }
1065 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1066 bool isCCOut()
const {
return Kind == k_CCOut; }
1067 bool isITMask()
const {
return Kind == k_ITCondMask; }
1068 bool isITCondCode()
const {
return Kind == k_CondCode; }
1069 bool isImm()
const override {
1070 return Kind == k_Immediate;
1073 bool isARMBranchTarget()
const {
1074 if (!isImm())
return false;
1077 return CE->getValue() % 4 == 0;
1082 bool isThumbBranchTarget()
const {
1083 if (!isImm())
return false;
1086 return CE->getValue() % 2 == 0;
1092 template<
unsigned w
idth,
unsigned scale>
1093 bool isUnsignedOffset()
const {
1094 if (!isImm())
return false;
1097 int64_t Val =
CE->getValue();
1099 int64_t
Max =
Align * ((1LL << width) - 1);
1100 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1107 template<
unsigned w
idth,
unsigned scale>
1108 bool isSignedOffset()
const {
1109 if (!isImm())
return false;
1112 int64_t Val =
CE->getValue();
1114 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1115 int64_t Min = -
Align * (1LL << (width-1));
1116 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1123 bool isLEOffset()
const {
1124 if (!isImm())
return false;
1127 int64_t Val =
CE->getValue();
1128 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1137 bool isThumbMemPC()
const {
1142 if (!CE)
return false;
1143 Val =
CE->getValue();
1145 else if (isGPRMem()) {
1146 if(!Memory.OffsetImm || Memory.OffsetRegNum)
return false;
1147 if(Memory.BaseRegNum != ARM::PC)
return false;
1149 Val =
CE->getValue();
1154 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1157 bool isFPImm()
const {
1158 if (!isImm())
return false;
1166 template<
int64_t N,
int64_t M>
1167 bool isImmediate()
const {
1168 if (!isImm())
return false;
1170 if (!CE)
return false;
1171 int64_t
Value =
CE->getValue();
1175 template<
int64_t N,
int64_t M>
1176 bool isImmediateS4()
const {
1177 if (!isImm())
return false;
1179 if (!CE)
return false;
1180 int64_t
Value =
CE->getValue();
1186 Value == std::numeric_limits<int32_t>::min();
1188 template<
int64_t N,
int64_t M>
1189 bool isImmediateS2()
const {
1190 if (!isImm())
return false;
1192 if (!CE)
return false;
1193 int64_t
Value =
CE->getValue();
1196 bool isFBits16()
const {
1197 return isImmediate<0, 17>();
1199 bool isFBits32()
const {
1200 return isImmediate<1, 33>();
1202 bool isImm8s4()
const {
1203 return isImmediateS4<-1020, 1020>();
1205 bool isImm7s4()
const {
1206 return isImmediateS4<-508, 508>();
1208 bool isImm7Shift0()
const {
1209 return isImmediate<-127, 127>();
1211 bool isImm7Shift1()
const {
1212 return isImmediateS2<-255, 255>();
1214 bool isImm7Shift2()
const {
1215 return isImmediateS4<-511, 511>();
1217 bool isImm7()
const {
1218 return isImmediate<-127, 127>();
1220 bool isImm0_1020s4()
const {
1221 return isImmediateS4<0, 1020>();
1223 bool isImm0_508s4()
const {
1224 return isImmediateS4<0, 508>();
1226 bool isImm0_508s4Neg()
const {
1227 if (!isImm())
return false;
1229 if (!CE)
return false;
1230 int64_t
Value = -
CE->getValue();
1235 bool isImm0_4095Neg()
const {
1236 if (!isImm())
return false;
1238 if (!CE)
return false;
1243 if ((
CE->getValue() >> 32) > 0)
return false;
1244 uint32_t
Value = -
static_cast<uint32_t
>(
CE->getValue());
1248 bool isImm0_7()
const {
1249 return isImmediate<0, 7>();
1252 bool isImm1_16()
const {
1253 return isImmediate<1, 16>();
1256 bool isImm1_32()
const {
1257 return isImmediate<1, 32>();
1260 bool isImm8_255()
const {
1261 return isImmediate<8, 255>();
1264 bool isImm0_255Expr()
const {
1272 int64_t
Value =
CE->getValue();
1276 bool isImm256_65535Expr()
const {
1277 if (!isImm())
return false;
1281 if (!CE)
return true;
1282 int64_t
Value =
CE->getValue();
1286 bool isImm0_65535Expr()
const {
1287 if (!isImm())
return false;
1291 if (!CE)
return true;
1292 int64_t
Value =
CE->getValue();
1296 bool isImm24bit()
const {
1297 return isImmediate<0, 0xffffff + 1>();
1300 bool isImmThumbSR()
const {
1301 return isImmediate<1, 33>();
1304 bool isPKHLSLImm()
const {
1305 return isImmediate<0, 32>();
1308 bool isPKHASRImm()
const {
1309 return isImmediate<0, 33>();
1312 bool isAdrLabel()
const {
1319 if (!isImm())
return false;
1321 if (!CE)
return false;
1322 int64_t
Value =
CE->getValue();
1327 bool isT2SOImm()
const {
1334 return (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
1337 if (!isImm())
return false;
1339 if (!CE)
return false;
1340 int64_t
Value =
CE->getValue();
1344 bool isT2SOImmNot()
const {
1345 if (!isImm())
return false;
1347 if (!CE)
return false;
1348 int64_t
Value =
CE->getValue();
1353 bool isT2SOImmNeg()
const {
1354 if (!isImm())
return false;
1356 if (!CE)
return false;
1357 int64_t
Value =
CE->getValue();
1363 bool isSetEndImm()
const {
1364 if (!isImm())
return false;
1366 if (!CE)
return false;
1367 int64_t
Value =
CE->getValue();
1371 bool isReg()
const override {
return Kind == k_Register; }
1372 bool isRegList()
const {
return Kind == k_RegisterList; }
1373 bool isRegListWithAPSR()
const {
1374 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1376 bool isDReg()
const {
1378 getARMMCRegisterClass(ARM::DPRRegClassID).contains(
Reg.RegNum);
1380 bool isQReg()
const {
1382 getARMMCRegisterClass(ARM::QPRRegClassID).contains(
Reg.RegNum);
1384 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1385 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1386 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1387 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1388 bool isToken()
const override {
return Kind == k_Token; }
1389 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1390 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1391 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1392 bool isMem()
const override {
1393 return isGPRMem() || isMVEMem();
1395 bool isMVEMem()
const {
1396 if (Kind != k_Memory)
1398 if (Memory.BaseRegNum &&
1399 !getARMMCRegisterClass(ARM::GPRRegClassID)
1401 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1403 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1408 bool isGPRMem()
const {
1409 if (Kind != k_Memory)
1411 if (Memory.BaseRegNum &&
1412 !getARMMCRegisterClass(ARM::GPRRegClassID).
contains(Memory.BaseRegNum))
1414 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1419 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1420 bool isRegShiftedReg()
const {
1421 return Kind == k_ShiftedRegister &&
1422 getARMMCRegisterClass(ARM::GPRRegClassID)
1423 .contains(RegShiftedReg.SrcReg) &&
1424 getARMMCRegisterClass(ARM::GPRRegClassID)
1425 .contains(RegShiftedReg.ShiftReg);
1427 bool isRegShiftedImm()
const {
1428 return Kind == k_ShiftedImmediate &&
1429 getARMMCRegisterClass(ARM::GPRRegClassID)
1430 .contains(RegShiftedImm.SrcReg);
1432 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1434 template<
unsigned Min,
unsigned Max>
1435 bool isPowerTwoInRange()
const {
1436 if (!isImm())
return false;
1438 if (!CE)
return false;
1439 int64_t
Value =
CE->getValue();
1443 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1445 bool isModImmNot()
const {
1446 if (!isImm())
return false;
1448 if (!CE)
return false;
1449 int64_t
Value =
CE->getValue();
1453 bool isModImmNeg()
const {
1454 if (!isImm())
return false;
1456 if (!CE)
return false;
1457 int64_t
Value =
CE->getValue();
1462 bool isThumbModImmNeg1_7()
const {
1463 if (!isImm())
return false;
1465 if (!CE)
return false;
1466 int32_t
Value = -(int32_t)
CE->getValue();
1470 bool isThumbModImmNeg8_255()
const {
1471 if (!isImm())
return false;
1473 if (!CE)
return false;
1474 int32_t
Value = -(int32_t)
CE->getValue();
1478 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1479 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1480 bool isPostIdxRegShifted()
const {
1481 return Kind == k_PostIndexRegister &&
1482 getARMMCRegisterClass(ARM::GPRRegClassID)
1483 .contains(PostIdxReg.RegNum);
1485 bool isPostIdxReg()
const {
1488 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1492 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1493 (alignOK || Memory.Alignment ==
Alignment);
1495 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1499 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1504 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1505 (alignOK || Memory.Alignment ==
Alignment);
1507 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1511 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).
contains(Memory.BaseRegNum))
1515 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1516 (alignOK || Memory.Alignment ==
Alignment);
1518 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1522 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).
contains(Memory.BaseRegNum))
1526 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1527 (alignOK || Memory.Alignment ==
Alignment);
1529 bool isMemPCRelImm12()
const {
1530 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1533 if (Memory.BaseRegNum != ARM::PC)
1536 if (!Memory.OffsetImm)
return true;
1538 int64_t Val =
CE->getValue();
1539 return (Val > -4096 && Val < 4096) ||
1540 (Val == std::numeric_limits<int32_t>::min());
1545 bool isAlignedMemory()
const {
1546 return isMemNoOffset(
true);
1549 bool isAlignedMemoryNone()
const {
1550 return isMemNoOffset(
false, 0);
1553 bool isDupAlignedMemoryNone()
const {
1554 return isMemNoOffset(
false, 0);
1557 bool isAlignedMemory16()
const {
1558 if (isMemNoOffset(
false, 2))
1560 return isMemNoOffset(
false, 0);
1563 bool isDupAlignedMemory16()
const {
1564 if (isMemNoOffset(
false, 2))
1566 return isMemNoOffset(
false, 0);
1569 bool isAlignedMemory32()
const {
1570 if (isMemNoOffset(
false, 4))
1572 return isMemNoOffset(
false, 0);
1575 bool isDupAlignedMemory32()
const {
1576 if (isMemNoOffset(
false, 4))
1578 return isMemNoOffset(
false, 0);
1581 bool isAlignedMemory64()
const {
1582 if (isMemNoOffset(
false, 8))
1584 return isMemNoOffset(
false, 0);
1587 bool isDupAlignedMemory64()
const {
1588 if (isMemNoOffset(
false, 8))
1590 return isMemNoOffset(
false, 0);
1593 bool isAlignedMemory64or128()
const {
1594 if (isMemNoOffset(
false, 8))
1596 if (isMemNoOffset(
false, 16))
1598 return isMemNoOffset(
false, 0);
1601 bool isDupAlignedMemory64or128()
const {
1602 if (isMemNoOffset(
false, 8))
1604 if (isMemNoOffset(
false, 16))
1606 return isMemNoOffset(
false, 0);
1609 bool isAlignedMemory64or128or256()
const {
1610 if (isMemNoOffset(
false, 8))
1612 if (isMemNoOffset(
false, 16))
1614 if (isMemNoOffset(
false, 32))
1616 return isMemNoOffset(
false, 0);
1619 bool isAddrMode2()
const {
1620 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1622 if (Memory.OffsetRegNum)
return true;
1624 if (!Memory.OffsetImm)
return true;
1626 int64_t Val =
CE->getValue();
1627 return Val > -4096 && Val < 4096;
1632 bool isAM2OffsetImm()
const {
1633 if (!isImm())
return false;
1636 if (!CE)
return false;
1637 int64_t Val =
CE->getValue();
1638 return (Val == std::numeric_limits<int32_t>::min()) ||
1639 (Val > -4096 && Val < 4096);
1642 bool isAddrMode3()
const {
1648 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1652 if (Memory.OffsetRegNum)
return true;
1654 if (!Memory.OffsetImm)
return true;
1656 int64_t Val =
CE->getValue();
1659 return (Val > -256 && Val < 256) ||
1660 Val == std::numeric_limits<int32_t>::min();
1665 bool isAM3Offset()
const {
1672 if (!CE)
return false;
1673 int64_t Val =
CE->getValue();
1675 return (Val > -256 && Val < 256) ||
1676 Val == std::numeric_limits<int32_t>::min();
1679 bool isAddrMode5()
const {
1685 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1687 if (Memory.OffsetRegNum)
return false;
1689 if (!Memory.OffsetImm)
return true;
1691 int64_t Val =
CE->getValue();
1692 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1693 Val == std::numeric_limits<int32_t>::min();
1698 bool isAddrMode5FP16()
const {
1704 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1706 if (Memory.OffsetRegNum)
return false;
1708 if (!Memory.OffsetImm)
return true;
1710 int64_t Val =
CE->getValue();
1711 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1712 Val == std::numeric_limits<int32_t>::min();
1717 bool isMemTBB()
const {
1718 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1724 bool isMemTBH()
const {
1725 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1726 Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm != 1 ||
1727 Memory.Alignment != 0 )
1732 bool isMemRegOffset()
const {
1733 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1738 bool isT2MemRegOffset()
const {
1739 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1740 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1745 if (Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm > 3)
1750 bool isMemThumbRR()
const {
1753 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1760 bool isMemThumbRIs4()
const {
1761 if (!isGPRMem() || Memory.OffsetRegNum ||
1765 if (!Memory.OffsetImm)
return true;
1767 int64_t Val =
CE->getValue();
1768 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1773 bool isMemThumbRIs2()
const {
1774 if (!isGPRMem() || Memory.OffsetRegNum ||
1778 if (!Memory.OffsetImm)
return true;
1780 int64_t Val =
CE->getValue();
1781 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1786 bool isMemThumbRIs1()
const {
1787 if (!isGPRMem() || Memory.OffsetRegNum ||
1791 if (!Memory.OffsetImm)
return true;
1793 int64_t Val =
CE->getValue();
1794 return Val >= 0 && Val <= 31;
1799 bool isMemThumbSPI()
const {
1800 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1801 Memory.Alignment != 0)
1804 if (!Memory.OffsetImm)
return true;
1806 int64_t Val =
CE->getValue();
1807 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1812 bool isMemImm8s4Offset()
const {
1818 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1821 if (!Memory.OffsetImm)
return true;
1823 int64_t Val =
CE->getValue();
1825 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1826 Val == std::numeric_limits<int32_t>::min();
1831 bool isMemImm7s4Offset()
const {
1837 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1838 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1842 if (!Memory.OffsetImm)
return true;
1844 int64_t Val =
CE->getValue();
1846 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1851 bool isMemImm0_1020s4Offset()
const {
1852 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1855 if (!Memory.OffsetImm)
return true;
1857 int64_t Val =
CE->getValue();
1858 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1863 bool isMemImm8Offset()
const {
1864 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1867 if (Memory.BaseRegNum == ARM::PC)
return false;
1869 if (!Memory.OffsetImm)
return true;
1871 int64_t Val =
CE->getValue();
1872 return (Val == std::numeric_limits<int32_t>::min()) ||
1873 (Val > -256 && Val < 256);
1878 template<
unsigned Bits,
unsigned RegClassID>
1879 bool isMemImm7ShiftedOffset()
const {
1880 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1881 !getARMMCRegisterClass(RegClassID).
contains(Memory.BaseRegNum))
1887 if (!Memory.OffsetImm)
return true;
1889 int64_t Val =
CE->getValue();
1893 if (Val == INT32_MIN)
1896 unsigned Divisor = 1U <<
Bits;
1899 if (Val % Divisor != 0)
1904 return (Val >= -127 && Val <= 127);
1909 template <
int shift>
bool isMemRegRQOffset()
const {
1910 if (!isMVEMem() || Memory.OffsetImm !=
nullptr || Memory.Alignment != 0)
1913 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1916 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1924 (Memory.ShiftType !=
ARM_AM::uxtw || Memory.ShiftImm != shift))
1930 template <
int shift>
bool isMemRegQOffset()
const {
1931 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1934 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1937 if (!Memory.OffsetImm)
1939 static_assert(shift < 56,
1940 "Such that we dont shift by a value higher than 62");
1942 int64_t Val =
CE->getValue();
1945 if ((Val & ((1U << shift) - 1)) != 0)
1951 int64_t
Range = (1U << (7 + shift)) - 1;
1952 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1957 bool isMemPosImm8Offset()
const {
1958 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1961 if (!Memory.OffsetImm)
return true;
1963 int64_t Val =
CE->getValue();
1964 return Val >= 0 && Val < 256;
1969 bool isMemNegImm8Offset()
const {
1970 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1973 if (Memory.BaseRegNum == ARM::PC)
return false;
1975 if (!Memory.OffsetImm)
return false;
1977 int64_t Val =
CE->getValue();
1978 return (Val == std::numeric_limits<int32_t>::min()) ||
1979 (Val > -256 && Val < 0);
1984 bool isMemUImm12Offset()
const {
1985 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1988 if (!Memory.OffsetImm)
return true;
1990 int64_t Val =
CE->getValue();
1991 return (Val >= 0 && Val < 4096);
1996 bool isMemImm12Offset()
const {
2004 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2007 if (!Memory.OffsetImm)
return true;
2009 int64_t Val =
CE->getValue();
2010 return (Val > -4096 && Val < 4096) ||
2011 (Val == std::numeric_limits<int32_t>::min());
2018 bool isConstPoolAsmImm()
const {
2021 return (isConstantPoolImm());
2024 bool isPostIdxImm8()
const {
2025 if (!isImm())
return false;
2027 if (!CE)
return false;
2028 int64_t Val =
CE->getValue();
2029 return (Val > -256 && Val < 256) ||
2030 (Val == std::numeric_limits<int32_t>::min());
2033 bool isPostIdxImm8s4()
const {
2034 if (!isImm())
return false;
2036 if (!CE)
return false;
2037 int64_t Val =
CE->getValue();
2038 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2039 (Val == std::numeric_limits<int32_t>::min());
2042 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2043 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2044 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2047 bool isAnyVectorList()
const {
2048 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2049 Kind == k_VectorListIndexed;
2052 bool isVectorList()
const {
return Kind == k_VectorList; }
2054 bool isSingleSpacedVectorList()
const {
2055 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2058 bool isDoubleSpacedVectorList()
const {
2059 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2062 bool isVecListOneD()
const {
2064 if (isDReg() && !Parser->hasMVE())
2066 if (!isSingleSpacedVectorList())
return false;
2067 return VectorList.Count == 1;
2070 bool isVecListTwoMQ()
const {
2071 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2072 getARMMCRegisterClass(ARM::MQPRRegClassID)
2073 .contains(VectorList.RegNum);
2076 bool isVecListDPair()
const {
2079 if (isQReg() && !Parser->hasMVE())
2081 if (!isSingleSpacedVectorList())
return false;
2082 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2086 bool isVecListThreeD()
const {
2087 if (!isSingleSpacedVectorList())
return false;
2088 return VectorList.Count == 3;
2091 bool isVecListFourD()
const {
2092 if (!isSingleSpacedVectorList())
return false;
2093 return VectorList.Count == 4;
2096 bool isVecListDPairSpaced()
const {
2097 if (Kind != k_VectorList)
return false;
2098 if (isSingleSpacedVectorList())
return false;
2099 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2103 bool isVecListThreeQ()
const {
2104 if (!isDoubleSpacedVectorList())
return false;
2105 return VectorList.Count == 3;
2108 bool isVecListFourQ()
const {
2109 if (!isDoubleSpacedVectorList())
return false;
2110 return VectorList.Count == 4;
2113 bool isVecListFourMQ()
const {
2114 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2115 getARMMCRegisterClass(ARM::MQPRRegClassID)
2116 .contains(VectorList.RegNum);
2119 bool isSingleSpacedVectorAllLanes()
const {
2120 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2123 bool isDoubleSpacedVectorAllLanes()
const {
2124 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2127 bool isVecListOneDAllLanes()
const {
2128 if (!isSingleSpacedVectorAllLanes())
return false;
2129 return VectorList.Count == 1;
2132 bool isVecListDPairAllLanes()
const {
2133 if (!isSingleSpacedVectorAllLanes())
return false;
2134 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2138 bool isVecListDPairSpacedAllLanes()
const {
2139 if (!isDoubleSpacedVectorAllLanes())
return false;
2140 return VectorList.Count == 2;
2143 bool isVecListThreeDAllLanes()
const {
2144 if (!isSingleSpacedVectorAllLanes())
return false;
2145 return VectorList.Count == 3;
2148 bool isVecListThreeQAllLanes()
const {
2149 if (!isDoubleSpacedVectorAllLanes())
return false;
2150 return VectorList.Count == 3;
2153 bool isVecListFourDAllLanes()
const {
2154 if (!isSingleSpacedVectorAllLanes())
return false;
2155 return VectorList.Count == 4;
2158 bool isVecListFourQAllLanes()
const {
2159 if (!isDoubleSpacedVectorAllLanes())
return false;
2160 return VectorList.Count == 4;
2163 bool isSingleSpacedVectorIndexed()
const {
2164 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2167 bool isDoubleSpacedVectorIndexed()
const {
2168 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2171 bool isVecListOneDByteIndexed()
const {
2172 if (!isSingleSpacedVectorIndexed())
return false;
2173 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2176 bool isVecListOneDHWordIndexed()
const {
2177 if (!isSingleSpacedVectorIndexed())
return false;
2178 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2181 bool isVecListOneDWordIndexed()
const {
2182 if (!isSingleSpacedVectorIndexed())
return false;
2183 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2186 bool isVecListTwoDByteIndexed()
const {
2187 if (!isSingleSpacedVectorIndexed())
return false;
2188 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2191 bool isVecListTwoDHWordIndexed()
const {
2192 if (!isSingleSpacedVectorIndexed())
return false;
2193 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2196 bool isVecListTwoQWordIndexed()
const {
2197 if (!isDoubleSpacedVectorIndexed())
return false;
2198 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2201 bool isVecListTwoQHWordIndexed()
const {
2202 if (!isDoubleSpacedVectorIndexed())
return false;
2203 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2206 bool isVecListTwoDWordIndexed()
const {
2207 if (!isSingleSpacedVectorIndexed())
return false;
2208 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2211 bool isVecListThreeDByteIndexed()
const {
2212 if (!isSingleSpacedVectorIndexed())
return false;
2213 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2216 bool isVecListThreeDHWordIndexed()
const {
2217 if (!isSingleSpacedVectorIndexed())
return false;
2218 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2221 bool isVecListThreeQWordIndexed()
const {
2222 if (!isDoubleSpacedVectorIndexed())
return false;
2223 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2226 bool isVecListThreeQHWordIndexed()
const {
2227 if (!isDoubleSpacedVectorIndexed())
return false;
2228 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2231 bool isVecListThreeDWordIndexed()
const {
2232 if (!isSingleSpacedVectorIndexed())
return false;
2233 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2236 bool isVecListFourDByteIndexed()
const {
2237 if (!isSingleSpacedVectorIndexed())
return false;
2238 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2241 bool isVecListFourDHWordIndexed()
const {
2242 if (!isSingleSpacedVectorIndexed())
return false;
2243 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2246 bool isVecListFourQWordIndexed()
const {
2247 if (!isDoubleSpacedVectorIndexed())
return false;
2248 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2251 bool isVecListFourQHWordIndexed()
const {
2252 if (!isDoubleSpacedVectorIndexed())
return false;
2253 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2256 bool isVecListFourDWordIndexed()
const {
2257 if (!isSingleSpacedVectorIndexed())
return false;
2258 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2261 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2263 template <
unsigned NumLanes>
2264 bool isVectorIndexInRange()
const {
2265 if (Kind != k_VectorIndex)
return false;
2266 return VectorIndex.Val < NumLanes;
2269 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2270 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2271 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2272 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2274 template<
int PermittedValue,
int OtherPermittedValue>
2275 bool isMVEPairVectorIndex()
const {
2276 if (Kind != k_VectorIndex)
return false;
2277 return VectorIndex.Val == PermittedValue ||
2278 VectorIndex.Val == OtherPermittedValue;
2281 bool isNEONi8splat()
const {
2282 if (!isImm())
return false;
2285 if (!CE)
return false;
2286 int64_t
Value =
CE->getValue();
2293 if (isNEONByteReplicate(2))
2299 if (!CE)
return false;
2300 unsigned Value =
CE->getValue();
2304 bool isNEONi16splatNot()
const {
2309 if (!CE)
return false;
2310 unsigned Value =
CE->getValue();
2315 if (isNEONByteReplicate(4))
2321 if (!CE)
return false;
2322 unsigned Value =
CE->getValue();
2326 bool isNEONi32splatNot()
const {
2331 if (!CE)
return false;
2332 unsigned Value =
CE->getValue();
2336 static bool isValidNEONi32vmovImm(int64_t
Value) {
2339 return ((
Value & 0xffffffffffffff00) == 0) ||
2340 ((
Value & 0xffffffffffff00ff) == 0) ||
2341 ((
Value & 0xffffffffff00ffff) == 0) ||
2342 ((
Value & 0xffffffff00ffffff) == 0) ||
2343 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2344 ((
Value & 0xffffffffff00ffff) == 0xffff);
2347 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2348 assert((Width == 8 || Width == 16 || Width == 32) &&
2349 "Invalid element width");
2350 assert(NumElems * Width <= 64 &&
"Invalid result width");
2358 int64_t
Value =
CE->getValue();
2366 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2368 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2371 for (
unsigned i = 1; i < NumElems; ++i) {
2373 if ((
Value & Mask) != Elem)
2379 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2380 return isNEONReplicate(8, NumBytes,
false);
2383 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2384 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2385 "Invalid source width");
2386 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2387 "Invalid destination width");
2388 assert(FromW < ToW &&
"ToW is not less than FromW");
2391 template<
unsigned FromW,
unsigned ToW>
2392 bool isNEONmovReplicate()
const {
2393 checkNeonReplicateArgs(FromW, ToW);
2394 if (ToW == 64 && isNEONi64splat())
2396 return isNEONReplicate(FromW, ToW / FromW,
false);
2399 template<
unsigned FromW,
unsigned ToW>
2400 bool isNEONinvReplicate()
const {
2401 checkNeonReplicateArgs(FromW, ToW);
2402 return isNEONReplicate(FromW, ToW / FromW,
true);
2405 bool isNEONi32vmov()
const {
2406 if (isNEONByteReplicate(4))
2414 return isValidNEONi32vmovImm(
CE->getValue());
2417 bool isNEONi32vmovNeg()
const {
2418 if (!isImm())
return false;
2421 if (!CE)
return false;
2422 return isValidNEONi32vmovImm(~
CE->getValue());
2425 bool isNEONi64splat()
const {
2426 if (!isImm())
return false;
2429 if (!CE)
return false;
2432 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2433 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2437 template<
int64_t Angle,
int64_t Remainder>
2438 bool isComplexRotation()
const {
2439 if (!isImm())
return false;
2442 if (!CE)
return false;
2445 return (
Value % Angle == Remainder &&
Value <= 270);
2448 bool isMVELongShift()
const {
2449 if (!isImm())
return false;
2452 if (!CE)
return false;
2457 bool isMveSaturateOp()
const {
2458 if (!isImm())
return false;
2460 if (!CE)
return false;
2465 bool isITCondCodeNoAL()
const {
2466 if (!isITCondCode())
return false;
2471 bool isITCondCodeRestrictedI()
const {
2472 if (!isITCondCode())
2478 bool isITCondCodeRestrictedS()
const {
2479 if (!isITCondCode())
2486 bool isITCondCodeRestrictedU()
const {
2487 if (!isITCondCode())
2493 bool isITCondCodeRestrictedFP()
const {
2494 if (!isITCondCode())
2501 void setVecListDPair(
unsigned int DPair) {
2502 Kind = k_VectorList;
2503 VectorList.RegNum = DPair;
2504 VectorList.Count = 2;
2505 VectorList.isDoubleSpaced =
false;
2508 void setVecListOneD(
unsigned int DReg) {
2509 Kind = k_VectorList;
2510 VectorList.RegNum =
DReg;
2511 VectorList.Count = 1;
2512 VectorList.isDoubleSpaced =
false;
2515 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
2525 void addARMBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2526 assert(
N == 1 &&
"Invalid number of operands!");
2530 void addThumbBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2531 assert(
N == 1 &&
"Invalid number of operands!");
2535 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2536 assert(
N == 2 &&
"Invalid number of operands!");
2542 void addVPTPredNOperands(MCInst &Inst,
unsigned N)
const {
2543 assert(
N == 3 &&
"Invalid number of operands!");
2545 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2550 void addVPTPredROperands(MCInst &Inst,
unsigned N)
const {
2551 assert(
N == 4 &&
"Invalid number of operands!");
2552 addVPTPredNOperands(Inst,
N-1);
2555 RegNum = ARM::NoRegister;
2558 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2559 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2561 "Inactive register in vpred_r is not tied to an output!");
2567 void addCoprocNumOperands(MCInst &Inst,
unsigned N)
const {
2568 assert(
N == 1 &&
"Invalid number of operands!");
2572 void addCoprocRegOperands(MCInst &Inst,
unsigned N)
const {
2573 assert(
N == 1 &&
"Invalid number of operands!");
2577 void addCoprocOptionOperands(MCInst &Inst,
unsigned N)
const {
2578 assert(
N == 1 &&
"Invalid number of operands!");
2582 void addITMaskOperands(MCInst &Inst,
unsigned N)
const {
2583 assert(
N == 1 &&
"Invalid number of operands!");
2587 void addITCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2588 assert(
N == 1 &&
"Invalid number of operands!");
2592 void addITCondCodeInvOperands(MCInst &Inst,
unsigned N)
const {
2593 assert(
N == 1 &&
"Invalid number of operands!");
2597 void addCCOutOperands(MCInst &Inst,
unsigned N)
const {
2598 assert(
N == 1 &&
"Invalid number of operands!");
2602 void addRegOperands(MCInst &Inst,
unsigned N)
const {
2603 assert(
N == 1 &&
"Invalid number of operands!");
2607 void addRegShiftedRegOperands(MCInst &Inst,
unsigned N)
const {
2608 assert(
N == 3 &&
"Invalid number of operands!");
2609 assert(isRegShiftedReg() &&
2610 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2617 void addRegShiftedImmOperands(MCInst &Inst,
unsigned N)
const {
2618 assert(
N == 2 &&
"Invalid number of operands!");
2619 assert(isRegShiftedImm() &&
2620 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2623 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2628 void addShifterImmOperands(MCInst &Inst,
unsigned N)
const {
2629 assert(
N == 1 &&
"Invalid number of operands!");
2634 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
2635 assert(
N == 1 &&
"Invalid number of operands!");
2636 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2637 for (MCRegister
Reg : RegList)
2641 void addRegListWithAPSROperands(MCInst &Inst,
unsigned N)
const {
2642 assert(
N == 1 &&
"Invalid number of operands!");
2643 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2644 for (MCRegister
Reg : RegList)
2648 void addDPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2649 addRegListOperands(Inst,
N);
2652 void addSPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2653 addRegListOperands(Inst,
N);
2656 void addFPSRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2657 addRegListOperands(Inst,
N);
2660 void addFPDRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2661 addRegListOperands(Inst,
N);
2664 void addRotImmOperands(MCInst &Inst,
unsigned N)
const {
2665 assert(
N == 1 &&
"Invalid number of operands!");
2670 void addModImmOperands(MCInst &Inst,
unsigned N)
const {
2671 assert(
N == 1 &&
"Invalid number of operands!");
2675 return addImmOperands(Inst,
N);
2680 void addModImmNotOperands(MCInst &Inst,
unsigned N)
const {
2681 assert(
N == 1 &&
"Invalid number of operands!");
2687 void addModImmNegOperands(MCInst &Inst,
unsigned N)
const {
2688 assert(
N == 1 &&
"Invalid number of operands!");
2694 void addThumbModImmNeg8_255Operands(MCInst &Inst,
unsigned N)
const {
2695 assert(
N == 1 &&
"Invalid number of operands!");
2697 uint32_t Val = -
CE->getValue();
2701 void addThumbModImmNeg1_7Operands(MCInst &Inst,
unsigned N)
const {
2702 assert(
N == 1 &&
"Invalid number of operands!");
2704 uint32_t Val = -
CE->getValue();
2708 void addBitfieldOperands(MCInst &Inst,
unsigned N)
const {
2709 assert(
N == 1 &&
"Invalid number of operands!");
2714 uint32_t
Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2715 (32 - (lsb + width)));
2719 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2720 assert(
N == 1 &&
"Invalid number of operands!");
2724 void addFBits16Operands(MCInst &Inst,
unsigned N)
const {
2725 assert(
N == 1 &&
"Invalid number of operands!");
2730 void addFBits32Operands(MCInst &Inst,
unsigned N)
const {
2731 assert(
N == 1 &&
"Invalid number of operands!");
2736 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2737 assert(
N == 1 &&
"Invalid number of operands!");
2743 void addImm8s4Operands(MCInst &Inst,
unsigned N)
const {
2744 assert(
N == 1 &&
"Invalid number of operands!");
2751 void addImm7s4Operands(MCInst &Inst,
unsigned N)
const {
2752 assert(
N == 1 &&
"Invalid number of operands!");
2759 void addImm7Shift0Operands(MCInst &Inst,
unsigned N)
const {
2760 assert(
N == 1 &&
"Invalid number of operands!");
2765 void addImm7Shift1Operands(MCInst &Inst,
unsigned N)
const {
2766 assert(
N == 1 &&
"Invalid number of operands!");
2771 void addImm7Shift2Operands(MCInst &Inst,
unsigned N)
const {
2772 assert(
N == 1 &&
"Invalid number of operands!");
2777 void addImm7Operands(MCInst &Inst,
unsigned N)
const {
2778 assert(
N == 1 &&
"Invalid number of operands!");
2783 void addImm0_1020s4Operands(MCInst &Inst,
unsigned N)
const {
2784 assert(
N == 1 &&
"Invalid number of operands!");
2791 void addImm0_508s4NegOperands(MCInst &Inst,
unsigned N)
const {
2792 assert(
N == 1 &&
"Invalid number of operands!");
2799 void addImm0_508s4Operands(MCInst &Inst,
unsigned N)
const {
2800 assert(
N == 1 &&
"Invalid number of operands!");
2807 void addImm1_16Operands(MCInst &Inst,
unsigned N)
const {
2808 assert(
N == 1 &&
"Invalid number of operands!");
2815 void addImm1_32Operands(MCInst &Inst,
unsigned N)
const {
2816 assert(
N == 1 &&
"Invalid number of operands!");
2823 void addImmThumbSROperands(MCInst &Inst,
unsigned N)
const {
2824 assert(
N == 1 &&
"Invalid number of operands!");
2828 unsigned Imm =
CE->getValue();
2832 void addPKHASRImmOperands(MCInst &Inst,
unsigned N)
const {
2833 assert(
N == 1 &&
"Invalid number of operands!");
2837 int Val =
CE->getValue();
2841 void addT2SOImmNotOperands(MCInst &Inst,
unsigned N)
const {
2842 assert(
N == 1 &&
"Invalid number of operands!");
2849 void addT2SOImmNegOperands(MCInst &Inst,
unsigned N)
const {
2850 assert(
N == 1 &&
"Invalid number of operands!");
2857 void addImm0_4095NegOperands(MCInst &Inst,
unsigned N)
const {
2858 assert(
N == 1 &&
"Invalid number of operands!");
2865 void addUnsignedOffset_b8s2Operands(MCInst &Inst,
unsigned N)
const {
2874 void addThumbMemPCOperands(MCInst &Inst,
unsigned N)
const {
2875 assert(
N == 1 &&
"Invalid number of operands!");
2887 assert(isGPRMem() &&
"Unknown value type!");
2895 void addMemBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2896 assert(
N == 1 &&
"Invalid number of operands!");
2900 void addInstSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2901 assert(
N == 1 &&
"Invalid number of operands!");
2905 void addTraceSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2906 assert(
N == 1 &&
"Invalid number of operands!");
2910 void addMemNoOffsetOperands(MCInst &Inst,
unsigned N)
const {
2911 assert(
N == 1 &&
"Invalid number of operands!");
2915 void addMemNoOffsetT2Operands(MCInst &Inst,
unsigned N)
const {
2916 assert(
N == 1 &&
"Invalid number of operands!");
2920 void addMemNoOffsetT2NoSpOperands(MCInst &Inst,
unsigned N)
const {
2921 assert(
N == 1 &&
"Invalid number of operands!");
2925 void addMemNoOffsetTOperands(MCInst &Inst,
unsigned N)
const {
2926 assert(
N == 1 &&
"Invalid number of operands!");
2930 void addMemPCRelImm12Operands(MCInst &Inst,
unsigned N)
const {
2931 assert(
N == 1 &&
"Invalid number of operands!");
2938 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2939 assert(
N == 1 &&
"Invalid number of operands!");
2940 assert(isImm() &&
"Not an immediate!");
2950 int Val =
CE->getValue();
2954 void addAlignedMemoryOperands(MCInst &Inst,
unsigned N)
const {
2955 assert(
N == 2 &&
"Invalid number of operands!");
2960 void addDupAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2961 addAlignedMemoryOperands(Inst,
N);
2964 void addAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2965 addAlignedMemoryOperands(Inst,
N);
2968 void addAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2969 addAlignedMemoryOperands(Inst,
N);
2972 void addDupAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2973 addAlignedMemoryOperands(Inst,
N);
2976 void addAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2977 addAlignedMemoryOperands(Inst,
N);
2980 void addDupAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2981 addAlignedMemoryOperands(Inst,
N);
2984 void addAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2985 addAlignedMemoryOperands(Inst,
N);
2988 void addDupAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2989 addAlignedMemoryOperands(Inst,
N);
2992 void addAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2993 addAlignedMemoryOperands(Inst,
N);
2996 void addDupAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2997 addAlignedMemoryOperands(Inst,
N);
3000 void addAlignedMemory64or128or256Operands(MCInst &Inst,
unsigned N)
const {
3001 addAlignedMemoryOperands(Inst,
N);
3004 void addAddrMode2Operands(MCInst &Inst,
unsigned N)
const {
3005 assert(
N == 3 &&
"Invalid number of operands!");
3008 if (!Memory.OffsetRegNum) {
3009 if (!Memory.OffsetImm)
3012 int32_t Val =
CE->getValue();
3015 if (Val == std::numeric_limits<int32_t>::min())
3028 Memory.ShiftImm, Memory.ShiftType);
3033 void addAM2OffsetImmOperands(MCInst &Inst,
unsigned N)
const {
3034 assert(
N == 2 &&
"Invalid number of operands!");
3036 assert(CE &&
"non-constant AM2OffsetImm operand!");
3037 int32_t Val =
CE->getValue();
3040 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3041 if (Val < 0) Val = -Val;
3047 void addAddrMode3Operands(MCInst &Inst,
unsigned N)
const {
3048 assert(
N == 3 &&
"Invalid number of operands!");
3061 if (!Memory.OffsetRegNum) {
3062 if (!Memory.OffsetImm)
3065 int32_t Val =
CE->getValue();
3068 if (Val == std::numeric_limits<int32_t>::min())
3085 void addAM3OffsetOperands(MCInst &Inst,
unsigned N)
const {
3086 assert(
N == 2 &&
"Invalid number of operands!");
3087 if (Kind == k_PostIndexRegister) {
3096 const MCConstantExpr *
CE =
static_cast<const MCConstantExpr*
>(
getImm());
3097 int32_t Val =
CE->getValue();
3100 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3101 if (Val < 0) Val = -Val;
3107 void addAddrMode5Operands(MCInst &Inst,
unsigned N)
const {
3108 assert(
N == 2 &&
"Invalid number of operands!");
3119 if (!Memory.OffsetImm)
3123 int32_t Val =
CE->getValue() / 4;
3126 if (Val == std::numeric_limits<int32_t>::min())
3136 void addAddrMode5FP16Operands(MCInst &Inst,
unsigned N)
const {
3137 assert(
N == 2 &&
"Invalid number of operands!");
3149 if (!Memory.OffsetImm)
3152 int32_t Val =
CE->getValue() / 2;
3155 if (Val == std::numeric_limits<int32_t>::min())
3165 void addMemImm8s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3166 assert(
N == 2 &&
"Invalid number of operands!");
3177 addExpr(Inst, Memory.OffsetImm);
3180 void addMemImm7s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3181 assert(
N == 2 &&
"Invalid number of operands!");
3192 addExpr(Inst, Memory.OffsetImm);
3195 void addMemImm0_1020s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3196 assert(
N == 2 &&
"Invalid number of operands!");
3198 if (!Memory.OffsetImm)
3207 void addMemImmOffsetOperands(MCInst &Inst,
unsigned N)
const {
3208 assert(
N == 2 &&
"Invalid number of operands!");
3210 addExpr(Inst, Memory.OffsetImm);
3213 void addMemRegRQOffsetOperands(MCInst &Inst,
unsigned N)
const {
3214 assert(
N == 2 &&
"Invalid number of operands!");
3219 void addMemUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3220 assert(
N == 2 &&
"Invalid number of operands!");
3230 addExpr(Inst, Memory.OffsetImm);
3233 void addMemImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3234 assert(
N == 2 &&
"Invalid number of operands!");
3244 addExpr(Inst, Memory.OffsetImm);
3247 void addConstPoolAsmImmOperands(MCInst &Inst,
unsigned N)
const {
3248 assert(
N == 1 &&
"Invalid number of operands!");
3251 addExpr(Inst, getConstantPoolImm());
3254 void addMemTBBOperands(MCInst &Inst,
unsigned N)
const {
3255 assert(
N == 2 &&
"Invalid number of operands!");
3260 void addMemTBHOperands(MCInst &Inst,
unsigned N)
const {
3261 assert(
N == 2 &&
"Invalid number of operands!");
3266 void addMemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3267 assert(
N == 3 &&
"Invalid number of operands!");
3270 Memory.ShiftImm, Memory.ShiftType);
3276 void addT2MemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3277 assert(
N == 3 &&
"Invalid number of operands!");
3283 void addMemThumbRROperands(MCInst &Inst,
unsigned N)
const {
3284 assert(
N == 2 &&
"Invalid number of operands!");
3289 void addMemThumbRIs4Operands(MCInst &Inst,
unsigned N)
const {
3290 assert(
N == 2 &&
"Invalid number of operands!");
3292 if (!Memory.OffsetImm)
3301 void addMemThumbRIs2Operands(MCInst &Inst,
unsigned N)
const {
3302 assert(
N == 2 &&
"Invalid number of operands!");
3304 if (!Memory.OffsetImm)
3312 void addMemThumbRIs1Operands(MCInst &Inst,
unsigned N)
const {
3313 assert(
N == 2 &&
"Invalid number of operands!");
3315 addExpr(Inst, Memory.OffsetImm);
3318 void addMemThumbSPIOperands(MCInst &Inst,
unsigned N)
const {
3319 assert(
N == 2 &&
"Invalid number of operands!");
3321 if (!Memory.OffsetImm)
3330 void addPostIdxImm8Operands(MCInst &Inst,
unsigned N)
const {
3331 assert(
N == 1 &&
"Invalid number of operands!");
3333 assert(CE &&
"non-constant post-idx-imm8 operand!");
3334 int Imm =
CE->getValue();
3335 bool isAdd =
Imm >= 0;
3336 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3341 void addPostIdxImm8s4Operands(MCInst &Inst,
unsigned N)
const {
3342 assert(
N == 1 &&
"Invalid number of operands!");
3344 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3345 int Imm =
CE->getValue();
3346 bool isAdd =
Imm >= 0;
3347 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3353 void addPostIdxRegOperands(MCInst &Inst,
unsigned N)
const {
3354 assert(
N == 2 &&
"Invalid number of operands!");
3359 void addPostIdxRegShiftedOperands(MCInst &Inst,
unsigned N)
const {
3360 assert(
N == 2 &&
"Invalid number of operands!");
3366 PostIdxReg.ShiftTy);
3370 void addPowerTwoOperands(MCInst &Inst,
unsigned N)
const {
3371 assert(
N == 1 &&
"Invalid number of operands!");
3376 void addMSRMaskOperands(MCInst &Inst,
unsigned N)
const {
3377 assert(
N == 1 &&
"Invalid number of operands!");
3381 void addBankedRegOperands(MCInst &Inst,
unsigned N)
const {
3382 assert(
N == 1 &&
"Invalid number of operands!");
3386 void addProcIFlagsOperands(MCInst &Inst,
unsigned N)
const {
3387 assert(
N == 1 &&
"Invalid number of operands!");
3391 void addVecListOperands(MCInst &Inst,
unsigned N)
const {
3392 assert(
N == 1 &&
"Invalid number of operands!");
3394 if (isAnyVectorList())
3396 else if (isDReg() && !Parser->hasMVE()) {
3398 }
else if (isQReg() && !Parser->hasMVE()) {
3399 MCRegister DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3400 DPair = Parser->getMRI()->getMatchingSuperReg(
3401 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3406 "attempted to add a vector list register with wrong type!");
3410 void addMVEVecListOperands(MCInst &Inst,
unsigned N)
const {
3411 assert(
N == 1 &&
"Invalid number of operands!");
3427 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3428 const MCRegisterClass *RC_out =
3429 (VectorList.Count == 2)
3430 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3431 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3434 for (
I = 0;
I <
E;
I++)
3437 assert(
I <
E &&
"Invalid vector list start register!");
3442 void addVecListIndexedOperands(MCInst &Inst,
unsigned N)
const {
3443 assert(
N == 2 &&
"Invalid number of operands!");
3448 void addVectorIndex8Operands(MCInst &Inst,
unsigned N)
const {
3449 assert(
N == 1 &&
"Invalid number of operands!");
3453 void addVectorIndex16Operands(MCInst &Inst,
unsigned N)
const {
3454 assert(
N == 1 &&
"Invalid number of operands!");
3458 void addVectorIndex32Operands(MCInst &Inst,
unsigned N)
const {
3459 assert(
N == 1 &&
"Invalid number of operands!");
3463 void addVectorIndex64Operands(MCInst &Inst,
unsigned N)
const {
3464 assert(
N == 1 &&
"Invalid number of operands!");
3468 void addMVEVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3469 assert(
N == 1 &&
"Invalid number of operands!");
3473 void addMVEPairVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3474 assert(
N == 1 &&
"Invalid number of operands!");
3478 void addNEONi8splatOperands(MCInst &Inst,
unsigned N)
const {
3479 assert(
N == 1 &&
"Invalid number of operands!");
3486 void addNEONi16splatOperands(MCInst &Inst,
unsigned N)
const {
3487 assert(
N == 1 &&
"Invalid number of operands!");
3490 unsigned Value =
CE->getValue();
3495 void addNEONi16splatNotOperands(MCInst &Inst,
unsigned N)
const {
3496 assert(
N == 1 &&
"Invalid number of operands!");
3499 unsigned Value =
CE->getValue();
3504 void addNEONi32splatOperands(MCInst &Inst,
unsigned N)
const {
3505 assert(
N == 1 &&
"Invalid number of operands!");
3508 unsigned Value =
CE->getValue();
3513 void addNEONi32splatNotOperands(MCInst &Inst,
unsigned N)
const {
3514 assert(
N == 1 &&
"Invalid number of operands!");
3517 unsigned Value =
CE->getValue();
3522 void addNEONi8ReplicateOperands(MCInst &Inst,
bool Inv)
const {
3527 "All instructions that wants to replicate non-zero byte "
3528 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3529 unsigned Value =
CE->getValue();
3532 unsigned B =
Value & 0xff;
3537 void addNEONinvi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3538 assert(
N == 1 &&
"Invalid number of operands!");
3539 addNEONi8ReplicateOperands(Inst,
true);
3542 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3545 else if (
Value > 0xffff &&
Value <= 0xffffff)
3547 else if (
Value > 0xffffff)
3552 void addNEONi32vmovOperands(MCInst &Inst,
unsigned N)
const {
3553 assert(
N == 1 &&
"Invalid number of operands!");
3556 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3560 void addNEONvmovi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3561 assert(
N == 1 &&
"Invalid number of operands!");
3562 addNEONi8ReplicateOperands(Inst,
false);
3565 void addNEONvmovi16ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3566 assert(
N == 1 &&
"Invalid number of operands!");
3572 "All instructions that want to replicate non-zero half-word "
3573 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3575 unsigned Elem =
Value & 0xffff;
3577 Elem = (Elem >> 8) | 0x200;
3581 void addNEONi32vmovNegOperands(MCInst &Inst,
unsigned N)
const {
3582 assert(
N == 1 &&
"Invalid number of operands!");
3585 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3589 void addNEONvmovi32ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3590 assert(
N == 1 &&
"Invalid number of operands!");
3596 "All instructions that want to replicate non-zero word "
3597 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3599 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3603 void addNEONi64splatOperands(MCInst &Inst,
unsigned N)
const {
3604 assert(
N == 1 &&
"Invalid number of operands!");
3609 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3615 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
3616 assert(
N == 1 &&
"Invalid number of operands!");
3621 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
3622 assert(
N == 1 &&
"Invalid number of operands!");
3627 void addMveSaturateOperands(MCInst &Inst,
unsigned N)
const {
3628 assert(
N == 1 &&
"Invalid number of operands!");
3630 unsigned Imm =
CE->getValue();
3631 assert((
Imm == 48 ||
Imm == 64) &&
"Invalid saturate operand");
3635 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
3637 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask, SMLoc S,
3638 ARMAsmParser &Parser) {
3639 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3646 static std::unique_ptr<ARMOperand>
3648 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3655 static std::unique_ptr<ARMOperand> CreateVPTPred(
ARMVCC::VPTCodes CC, SMLoc S,
3656 ARMAsmParser &Parser) {
3657 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3664 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal, SMLoc S,
3665 ARMAsmParser &Parser) {
3666 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3667 Op->Cop.Val = CopVal;
3673 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal, SMLoc S,
3674 ARMAsmParser &Parser) {
3675 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3676 Op->Cop.Val = CopVal;
3682 static std::unique_ptr<ARMOperand>
3683 CreateCoprocOption(
unsigned Val, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3684 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3691 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister
Reg, SMLoc S,
3692 ARMAsmParser &Parser) {
3693 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3694 Op->Reg.RegNum =
Reg;
3700 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3701 ARMAsmParser &Parser) {
3702 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3703 Op->Tok.Data = Str.data();
3704 Op->Tok.Length = Str.size();
3710 static std::unique_ptr<ARMOperand> CreateReg(MCRegister
Reg, SMLoc S, SMLoc
E,
3711 ARMAsmParser &Parser) {
3712 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3713 Op->Reg.RegNum =
Reg;
3719 static std::unique_ptr<ARMOperand>
3721 MCRegister ShiftReg,
unsigned ShiftImm, SMLoc S,
3722 SMLoc
E, ARMAsmParser &Parser) {
3723 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3724 Op->RegShiftedReg.ShiftTy = ShTy;
3725 Op->RegShiftedReg.SrcReg = SrcReg;
3726 Op->RegShiftedReg.ShiftReg = ShiftReg;
3727 Op->RegShiftedReg.ShiftImm = ShiftImm;
3733 static std::unique_ptr<ARMOperand>
3735 unsigned ShiftImm, SMLoc S, SMLoc
E,
3736 ARMAsmParser &Parser) {
3737 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3738 Op->RegShiftedImm.ShiftTy = ShTy;
3739 Op->RegShiftedImm.SrcReg = SrcReg;
3740 Op->RegShiftedImm.ShiftImm = ShiftImm;
3746 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3748 ARMAsmParser &Parser) {
3749 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3750 Op->ShifterImm.isASR = isASR;
3751 Op->ShifterImm.Imm =
Imm;
3757 static std::unique_ptr<ARMOperand>
3758 CreateRotImm(
unsigned Imm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3759 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3760 Op->RotImm.Imm =
Imm;
3766 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3768 ARMAsmParser &Parser) {
3769 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3771 Op->ModImm.Rot = Rot;
3777 static std::unique_ptr<ARMOperand>
3778 CreateConstantPoolImm(
const MCExpr *Val, SMLoc S, SMLoc
E,
3779 ARMAsmParser &Parser) {
3780 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3787 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3788 unsigned Width, SMLoc S,
3790 ARMAsmParser &Parser) {
3791 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3792 Op->Bitfield.LSB = LSB;
3793 Op->Bitfield.Width = Width;
3799 static std::unique_ptr<ARMOperand>
3800 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3801 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3802 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3803 KindTy Kind = k_RegisterList;
3805 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3807 if (Regs.back().second == ARM::VPR)
3808 Kind = k_FPDRegisterListWithVPR;
3810 Kind = k_DPRRegisterList;
3811 }
else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3813 if (Regs.back().second == ARM::VPR)
3814 Kind = k_FPSRegisterListWithVPR;
3816 Kind = k_SPRRegisterList;
3817 }
else if (Regs.front().second == ARM::VPR) {
3818 assert(Regs.size() == 1 &&
3819 "Register list starting with VPR expected to only contain VPR");
3820 Kind = k_FPSRegisterListWithVPR;
3823 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3824 Kind = k_RegisterListWithAPSR;
3828 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3829 for (
const auto &
P : Regs)
3830 Op->Registers.push_back(
P.second);
3832 Op->StartLoc = StartLoc;
3833 Op->EndLoc = EndLoc;
3837 static std::unique_ptr<ARMOperand>
3838 CreateVectorList(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced, SMLoc S,
3839 SMLoc
E, ARMAsmParser &Parser) {
3840 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3841 Op->VectorList.RegNum =
Reg;
3843 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3849 static std::unique_ptr<ARMOperand>
3850 CreateVectorListAllLanes(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced,
3851 SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3852 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3853 Op->VectorList.RegNum =
Reg;
3855 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3861 static std::unique_ptr<ARMOperand>
3862 CreateVectorListIndexed(MCRegister
Reg,
unsigned Count,
unsigned Index,
3863 bool isDoubleSpaced, SMLoc S, SMLoc
E,
3864 ARMAsmParser &Parser) {
3865 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3866 Op->VectorList.RegNum =
Reg;
3868 Op->VectorList.LaneIndex =
Index;
3869 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3875 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx, SMLoc S,
3876 SMLoc
E, MCContext &Ctx,
3877 ARMAsmParser &Parser) {
3878 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3879 Op->VectorIndex.Val = Idx;
3885 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val, SMLoc S,
3886 SMLoc
E, ARMAsmParser &Parser) {
3887 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3894 static std::unique_ptr<ARMOperand>
3895 CreateMem(MCRegister BaseReg,
const MCExpr *OffsetImm, MCRegister OffsetReg,
3897 bool isNegative, SMLoc S, SMLoc
E, ARMAsmParser &Parser,
3898 SMLoc AlignmentLoc = SMLoc()) {
3899 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3901 Op->Memory.OffsetImm = OffsetImm;
3902 Op->Memory.OffsetRegNum = OffsetReg;
3903 Op->Memory.ShiftType = ShiftType;
3904 Op->Memory.ShiftImm = ShiftImm;
3906 Op->Memory.isNegative = isNegative;
3909 Op->AlignmentLoc = AlignmentLoc;
3913 static std::unique_ptr<ARMOperand>
3915 unsigned ShiftImm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3916 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3917 Op->PostIdxReg.RegNum =
Reg;
3918 Op->PostIdxReg.isAdd = isAdd;
3919 Op->PostIdxReg.ShiftTy = ShiftTy;
3920 Op->PostIdxReg.ShiftImm = ShiftImm;
3926 static std::unique_ptr<ARMOperand>
3927 CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3928 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3929 Op->MBOpt.Val = Opt;
3935 static std::unique_ptr<ARMOperand>
3937 ARMAsmParser &Parser) {
3938 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3939 Op->ISBOpt.Val = Opt;
3945 static std::unique_ptr<ARMOperand>
3947 ARMAsmParser &Parser) {
3948 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3949 Op->TSBOpt.Val = Opt;
3955 static std::unique_ptr<ARMOperand>
3957 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3964 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask, SMLoc S,
3965 ARMAsmParser &Parser) {
3966 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3967 Op->MMask.Val = MMask;
3973 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg, SMLoc S,
3974 ARMAsmParser &Parser) {
3975 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3976 Op->BankedReg.Val =
Reg;
3985void ARMOperand::print(raw_ostream &OS,
const MCAsmInfo &MAI)
const {
4003 case k_ITCondMask: {
4004 static const char *
const MaskStr[] = {
4005 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4006 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4007 "(t)",
"(tett)",
"(tet)",
"(tete)",
4008 "(te)",
"(teet)",
"(tee)",
"(teee)",
4010 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4011 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4015 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4018 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4020 case k_CoprocOption:
4021 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4024 OS <<
"<mask: " << getMSRMask() <<
">";
4027 OS <<
"<banked reg: " << getBankedReg() <<
">";
4032 case k_MemBarrierOpt:
4033 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4035 case k_InstSyncBarrierOpt:
4036 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4038 case k_TraceSyncBarrierOpt:
4039 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4043 if (Memory.BaseRegNum)
4044 OS <<
" base:" <<
RegName(Memory.BaseRegNum);
4045 if (Memory.OffsetImm) {
4046 OS <<
" offset-imm:";
4049 if (Memory.OffsetRegNum)
4050 OS <<
" offset-reg:" << (Memory.isNegative ?
"-" :
"")
4051 <<
RegName(Memory.OffsetRegNum);
4054 OS <<
" shift-imm:" << Memory.ShiftImm;
4056 if (Memory.Alignment)
4057 OS <<
" alignment:" << Memory.Alignment;
4060 case k_PostIndexRegister:
4061 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4062 <<
RegName(PostIdxReg.RegNum);
4065 << PostIdxReg.ShiftImm;
4068 case k_ProcIFlags: {
4069 OS <<
"<ARM_PROC::";
4070 unsigned IFlags = getProcIFlags();
4071 for (
int i=2; i >= 0; --i)
4072 if (IFlags & (1 << i))
4080 case k_ShifterImmediate:
4081 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4082 <<
" #" << ShifterImm.Imm <<
">";
4084 case k_ShiftedRegister:
4085 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4087 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4089 case k_ShiftedImmediate:
4090 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4092 << RegShiftedImm.ShiftImm <<
">";
4094 case k_RotateImmediate:
4095 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4097 case k_ModifiedImmediate:
4098 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4099 << ModImm.Rot <<
")>";
4101 case k_ConstantPoolImmediate:
4102 OS <<
"<constant_pool_imm #";
4103 MAI.
printExpr(OS, *getConstantPoolImm());
4105 case k_BitfieldDescriptor:
4106 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4107 <<
", width: " <<
Bitfield.Width <<
">";
4109 case k_RegisterList:
4110 case k_RegisterListWithAPSR:
4111 case k_DPRRegisterList:
4112 case k_SPRRegisterList:
4113 case k_FPSRegisterListWithVPR:
4114 case k_FPDRegisterListWithVPR: {
4115 OS <<
"<register_list ";
4117 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4118 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4120 if (++
I <
E) OS <<
", ";
4127 OS <<
"<vector_list " << VectorList.Count <<
" * "
4128 <<
RegName(VectorList.RegNum) <<
">";
4130 case k_VectorListAllLanes:
4131 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4132 <<
RegName(VectorList.RegNum) <<
">";
4134 case k_VectorListIndexed:
4135 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4136 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4142 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4156 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4157 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4158 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4163 unsigned MnemonicOpsEndInd = 1;
4169 static_cast<ARMOperand &
>(*
Operands[1]).getImm()->getKind() ==
4172 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4175 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4177 ++MnemonicOpsEndInd;
4181 bool RHSCondCode =
false;
4182 while (MnemonicOpsEndInd <
Operands.size()) {
4183 auto Op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
4185 if (
Op.isITMask()) {
4187 MnemonicOpsEndInd++;
4188 }
else if (
Op.isToken() &&
4192 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4193 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4199 MnemonicOpsEndInd++;
4202 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4203 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4204 MnemonicOpsEndInd++;
4208 return MnemonicOpsEndInd;
4211bool ARMAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4213 const AsmToken &Tok = getParser().getTok();
4216 Reg = tryParseRegister();
4221ParseStatus ARMAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4223 if (parseRegister(
Reg, StartLoc, EndLoc))
4231MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4232 MCAsmParser &Parser = getParser();
4233 const AsmToken &Tok = Parser.
getTok();
4235 return MCRegister();
4240 Reg = StringSwitch<MCRegister>(lowerCase)
4241 .Case(
"r13", ARM::SP)
4242 .Case(
"r14", ARM::LR)
4243 .Case(
"r15", ARM::PC)
4244 .Case(
"ip", ARM::R12)
4246 .Case(
"a1", ARM::R0)
4247 .Case(
"a2", ARM::R1)
4248 .Case(
"a3", ARM::R2)
4249 .Case(
"a4", ARM::R3)
4250 .Case(
"v1", ARM::R4)
4251 .Case(
"v2", ARM::R5)
4252 .Case(
"v3", ARM::R6)
4253 .Case(
"v4", ARM::R7)
4254 .Case(
"v5", ARM::R8)
4255 .Case(
"v6", ARM::R9)
4256 .Case(
"v7", ARM::R10)
4257 .Case(
"v8", ARM::R11)
4258 .Case(
"sb", ARM::R9)
4259 .Case(
"sl", ARM::R10)
4260 .Case(
"fp", ARM::R11)
4261 .Default(MCRegister());
4267 auto Entry = RegisterReqs.
find(lowerCase);
4269 if (Entry == RegisterReqs.
end())
4270 return MCRegister();
4272 return Entry->getValue();
4276 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4277 return MCRegister();
4284std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4285 MCAsmParser &Parser = getParser();
4286 const AsmToken &Tok = Parser.
getTok();
4288 return std::nullopt;
4291 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4298 .Default(std::nullopt);
4307 MCAsmParser &Parser = getParser();
4310 auto ShiftTyOpt = tryParseShiftToken();
4311 if (ShiftTyOpt == std::nullopt)
4313 auto ShiftTy = ShiftTyOpt.value();
4320 std::unique_ptr<ARMOperand> PrevOp(
4321 (ARMOperand *)
Operands.pop_back_val().release());
4322 if (!PrevOp->isReg())
4323 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4324 MCRegister SrcReg = PrevOp->getReg();
4328 MCRegister ShiftReg;
4340 const MCExpr *ShiftExpr =
nullptr;
4341 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4342 Error(ImmLoc,
"invalid immediate shift value");
4348 Error(ImmLoc,
"invalid immediate shift value");
4354 Imm =
CE->getValue();
4358 Error(ImmLoc,
"immediate shift value out of range");
4368 ShiftReg = tryParseRegister();
4370 Error(L,
"expected immediate or register in shift operand");
4375 "expected immediate or register in shift operand");
4381 Operands.push_back(ARMOperand::CreateShiftedRegister(
4382 ShiftTy, SrcReg, ShiftReg,
Imm, S, EndLoc, *
this));
4384 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg,
Imm,
4397 MCAsmParser &Parser = getParser();
4400 MCRegister
Reg = tryParseRegister();
4404 Operands.push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4406 const AsmToken &ExclaimTok = Parser.
getTok();
4409 ExclaimTok.
getLoc(), *
this));
4421 const MCExpr *ImmVal;
4422 if (getParser().parseExpression(ImmVal))
4426 return TokError(
"immediate value expected for vector index");
4453 if (Name.size() < 2 || Name[0] != CoprocOp)
4455 Name = (Name[1] ==
'r') ? Name.drop_front(2) : Name.drop_front();
4457 switch (Name.size()) {
4480 case '0':
return 10;
4481 case '1':
return 11;
4482 case '2':
return 12;
4483 case '3':
return 13;
4484 case '4':
return 14;
4485 case '5':
return 15;
4492 MCAsmParser &Parser = getParser();
4494 const AsmToken &Tok = Parser.
getTok();
4512 MCAsmParser &Parser = getParser();
4514 const AsmToken &Tok = Parser.
getTok();
4525 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4533 MCAsmParser &Parser = getParser();
4535 const AsmToken &Tok = Parser.
getTok();
4544 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4551 MCAsmParser &Parser = getParser();
4561 if (getParser().parseExpression(Expr))
4562 return Error(Loc,
"illegal expression");
4564 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4566 "coprocessor option must be an immediate in range [0, 255]");
4567 int Val =
CE->getValue();
4575 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4586 if (!getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4590 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4591 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4592 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4593 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4594 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4595 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4596 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4597 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4606 Regs.emplace_back(Enc,
Reg);
4607 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4608 if (J->first == Enc) {
4609 Regs.erase(J.base());
4621 bool AllowRAAC,
bool IsLazyLoadStore,
4623 MCAsmParser &Parser = getParser();
4625 return TokError(
"Token is not a Left Curly Brace");
4632 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4633 MCRegister
Reg = tryParseRegister(AllowOutOfBoundReg);
4635 return Error(RegLoc,
"register expected");
4636 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4637 return Error(RegLoc,
"pseudo-register not allowed");
4648 bool VSCCLRMAdjustEncoding =
false;
4651 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4652 Reg = getDRegFromQReg(
Reg);
4657 const MCRegisterClass *RC;
4658 if (
Reg == ARM::RA_AUTH_CODE ||
4659 getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4660 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4661 else if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg))
4662 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4663 else if (getARMMCRegisterClass(ARM::SPRRegClassID).
contains(
Reg))
4664 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4665 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg))
4666 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4667 else if (
Reg == ARM::VPR)
4668 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4670 return Error(RegLoc,
"invalid register in register list");
4682 if (
Reg == ARM::RA_AUTH_CODE)
4683 return Error(RegLoc,
"pseudo-register not allowed");
4686 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4688 return Error(AfterMinusLoc,
"register expected");
4689 if (EndReg == ARM::RA_AUTH_CODE)
4690 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4692 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4693 EndReg = getDRegFromQReg(EndReg) + 1;
4700 return Error(AfterMinusLoc,
"invalid register in register list");
4703 return Error(AfterMinusLoc,
"bad range in register list");
4706 while (
Reg != EndReg) {
4709 if (VSCCLRMAdjustEncoding)
4712 Warning(AfterMinusLoc, StringRef(
"duplicated register (") +
4714 ") in register list");
4721 MCRegister OldReg =
Reg;
4723 const AsmToken RegTok = Parser.
getTok();
4724 Reg = tryParseRegister(AllowOutOfBoundReg);
4726 return Error(RegLoc,
"register expected");
4727 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4728 return Error(RegLoc,
"pseudo-register not allowed");
4730 bool isQReg =
false;
4731 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4732 Reg = getDRegFromQReg(
Reg);
4736 RC->
getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4737 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg)) {
4740 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4742 if (
Reg == ARM::VPR &&
4743 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4744 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4746 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4750 ") in register list");
4756 if (IsVSCCLRM && OldReg == ARM::S31 &&
Reg ==
ARM::D16) {
4757 VSCCLRMAdjustEncoding =
true;
4758 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4761 if ((
Reg == ARM::RA_AUTH_CODE &&
4762 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4764 return Error(RegLoc,
"invalid register in register list");
4770 if (VSCCLRMAdjustEncoding)
4772 if (EnforceOrder && EReg < EOldReg) {
4773 if (getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4774 Warning(RegLoc,
"register list not in ascending order");
4775 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4777 return Error(RegLoc,
"register list not in ascending order");
4780 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4781 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4782 EReg != EOldReg + 1)
4783 return Error(RegLoc,
"non-contiguous register range");
4787 ") in register list");
4807 ARMOperand::CreateToken(
"^", Parser.
getTok().
getLoc(), *
this));
4815ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4816 unsigned &Index, SMLoc &EndLoc) {
4817 MCAsmParser &Parser = getParser();
4823 LaneKind = AllLanes;
4834 const MCExpr *LaneIndex;
4836 if (getParser().parseExpression(LaneIndex))
4837 return Error(Loc,
"illegal expression");
4840 return Error(Loc,
"lane index must be empty or an integer");
4845 int64_t Val =
CE->getValue();
4848 if (Val < 0 || Val > 7)
4851 LaneKind = IndexedLane;
4860 MCAsmParser &Parser = getParser();
4861 VectorLaneTy LaneKind;
4871 MCRegister
Reg = tryParseRegister();
4874 if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg)) {
4875 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4880 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4884 ARMOperand::CreateVectorListAllLanes(
Reg, 1,
false, S,
E, *
this));
4887 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4888 Reg, 1, LaneIndex,
false, S,
E, *
this));
4893 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4894 Reg = getDRegFromQReg(
Reg);
4895 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4900 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4904 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4906 ARMOperand::CreateVectorListAllLanes(
Reg, 2,
false, S,
E, *
this));
4909 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4910 Reg, 2, LaneIndex,
false, S,
E, *
this));
4915 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4925 MCRegister
Reg = tryParseRegister();
4927 return Error(RegLoc,
"register expected");
4930 MCRegister FirstReg =
Reg;
4932 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
4934 "vector register in range Q0-Q7 expected");
4937 else if (!hasMVE() &&
4938 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4939 FirstReg =
Reg = getDRegFromQReg(
Reg);
4947 if (!parseVectorLane(LaneKind, LaneIndex,
E).isSuccess())
4955 else if (Spacing == 2)
4957 "sequential registers in double spaced list");
4960 MCRegister EndReg = tryParseRegister();
4962 return Error(AfterMinusLoc,
"register expected");
4965 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4966 EndReg = getDRegFromQReg(EndReg) + 1;
4973 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(EndReg)) ||
4975 !getARMMCRegisterClass(ARM::DPRRegClassID).
contains(EndReg)))
4976 return Error(AfterMinusLoc,
"invalid register in register list");
4979 return Error(AfterMinusLoc,
"bad range in register list");
4981 VectorLaneTy NextLaneKind;
4982 unsigned NextLaneIndex;
4983 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
4985 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4986 return Error(AfterMinusLoc,
"mismatched lane index in register list");
4995 MCRegister OldReg =
Reg;
4996 Reg = tryParseRegister();
4998 return Error(RegLoc,
"register expected");
5001 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
5002 return Error(RegLoc,
"vector register in range Q0-Q7 expected");
5011 else if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
5014 else if (Spacing == 2)
5017 "invalid register in double-spaced list (must be 'D' register')");
5018 Reg = getDRegFromQReg(
Reg);
5019 if (
Reg != OldReg + 1)
5020 return Error(RegLoc,
"non-contiguous register range");
5024 VectorLaneTy NextLaneKind;
5025 unsigned NextLaneIndex;
5027 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5029 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5030 return Error(LaneLoc,
"mismatched lane index in register list");
5037 Spacing = 1 + (
Reg == OldReg + 2);
5040 if (
Reg != OldReg + Spacing)
5041 return Error(RegLoc,
"non-contiguous register range");
5044 VectorLaneTy NextLaneKind;
5045 unsigned NextLaneIndex;
5047 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5049 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5050 return Error(EndLoc,
"mismatched lane index in register list");
5063 if (
Count == 2 && !hasMVE()) {
5064 const MCRegisterClass *RC =
5065 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5066 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5069 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5070 ARMOperand::CreateVectorListAllLanes);
5071 Operands.push_back(Create(FirstReg,
Count, (Spacing == 2), S,
E, *
this));
5075 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5076 FirstReg,
Count, LaneIndex, (Spacing == 2), S,
E, *
this));
5084 MCAsmParser &Parser = getParser();
5086 const AsmToken &Tok = Parser.
getTok();
5092 Opt = StringSwitch<unsigned>(OptStr.
lower())
5127 const MCExpr *MemBarrierID;
5128 if (getParser().parseExpression(MemBarrierID))
5129 return Error(Loc,
"illegal expression");
5133 return Error(Loc,
"constant expression expected");
5135 int Val =
CE->getValue();
5137 return Error(Loc,
"immediate value out of range");
5142 "expected an immediate or barrier type");
5151 MCAsmParser &Parser = getParser();
5153 const AsmToken &Tok = Parser.
getTok();
5164 ARMOperand::CreateTraceSyncBarrierOpt(
ARM_TSB::CSYNC, S, *
this));
5171 MCAsmParser &Parser = getParser();
5173 const AsmToken &Tok = Parser.
getTok();
5192 const MCExpr *ISBarrierID;
5193 if (getParser().parseExpression(ISBarrierID))
5194 return Error(Loc,
"illegal expression");
5198 return Error(Loc,
"constant expression expected");
5200 int Val =
CE->getValue();
5202 return Error(Loc,
"immediate value out of range");
5207 "expected an immediate or barrier type");
5209 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5216 MCAsmParser &Parser = getParser();
5218 const AsmToken &Tok = Parser.
getTok();
5226 if (IFlagsStr !=
"none") {
5227 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
5228 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.
substr(i, 1).
lower())
5236 if (Flag == ~0U || (IFlags & Flag))
5252 if (
static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask() ||
5253 static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg())
5255 MCAsmParser &Parser = getParser();
5257 const AsmToken &Tok = Parser.
getTok();
5261 if (Val > 255 || Val < 0) {
5264 unsigned SYSmvalue = Val & 0xFF;
5266 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5275 auto TheReg = ARMSysReg::lookupMClassSysRegByName(
Mask.lower());
5276 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5279 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5282 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5288 StringRef
Flags =
"";
5289 std::string SpecReg =
Mask.slice(Start,
Next).lower();
5296 unsigned FlagsVal = 0;
5298 if (SpecReg ==
"apsr") {
5299 FlagsVal = StringSwitch<unsigned>(Flags)
5302 .Case(
"nzcvqg", 0xc)
5305 if (FlagsVal == ~0U) {
5311 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
5313 if (Flags ==
"all" || Flags ==
"")
5315 for (
int i = 0, e =
Flags.size(); i != e; ++i) {
5316 unsigned Flag = StringSwitch<unsigned>(
Flags.substr(i, 1))
5325 if (Flag == ~0U || (FlagsVal & Flag))
5341 if (SpecReg ==
"spsr")
5345 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *
this));
5353 if (
static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg() ||
5354 static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask())
5356 MCAsmParser &Parser = getParser();
5358 const AsmToken &Tok = Parser.
getTok();
5363 auto TheReg = ARMBankedReg::lookupBankedRegByName(
RegName.lower());
5366 unsigned Encoding = TheReg->Encoding;
5369 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *
this));
5378 MCAsmParser &Parser = getParser();
5379 auto ShiftCodeOpt = tryParseShiftToken();
5381 if (!ShiftCodeOpt.has_value())
5383 auto ShiftCode = ShiftCodeOpt.value();
5387 if (ShiftCode !=
Op)
5399 const MCExpr *ShiftAmount;
5402 if (getParser().parseExpression(ShiftAmount, EndLoc))
5403 return Error(Loc,
"illegal expression");
5406 return Error(Loc,
"constant expression expected");
5407 int Val =
CE->getValue();
5408 if (Val < Low || Val >
High)
5409 return Error(Loc,
"immediate value out of range");
5411 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *
this));
5417 MCAsmParser &Parser = getParser();
5418 const AsmToken &Tok = Parser.
getTok();
5421 return Error(S,
"'be' or 'le' operand expected");
5429 return Error(S,
"'be' or 'le' operand expected");
5430 Operands.push_back(ARMOperand::CreateImm(
5441 MCAsmParser &Parser = getParser();
5442 const AsmToken &Tok = Parser.
getTok();
5448 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
5450 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5463 const MCExpr *ShiftAmount;
5465 if (getParser().parseExpression(ShiftAmount, EndLoc))
5466 return Error(ExLoc,
"malformed shift expression");
5469 return Error(ExLoc,
"shift amount must be an immediate");
5471 int64_t Val =
CE->getValue();
5474 if (Val < 1 || Val > 32)
5475 return Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
5478 return Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
5479 if (Val == 32) Val = 0;
5482 if (Val < 0 || Val > 31)
5483 return Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
5487 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *
this));
5496 MCAsmParser &Parser = getParser();
5497 const AsmToken &Tok = Parser.
getTok();
5502 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
5513 const MCExpr *ShiftAmount;
5515 if (getParser().parseExpression(ShiftAmount, EndLoc))
5516 return Error(ExLoc,
"malformed rotate expression");
5519 return Error(ExLoc,
"rotate amount must be an immediate");
5521 int64_t Val =
CE->getValue();
5525 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5526 return Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
5528 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *
this));
5534 MCAsmParser &Parser = getParser();
5535 AsmLexer &Lexer = getLexer();
5566 const MCExpr *Imm1Exp;
5567 if (getParser().parseExpression(Imm1Exp, Ex1))
5568 return Error(Sx1,
"malformed expression");
5574 Imm1 =
CE->getValue();
5578 Operands.push_back(ARMOperand::CreateModImm(
5579 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *
this));
5590 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5596 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5603 "expected modified immediate operand: #[0, 255], #even[0-30]");
5606 return Error(Sx1,
"immediate operand must a number in the range [0, 255]");
5620 const MCExpr *Imm2Exp;
5621 if (getParser().parseExpression(Imm2Exp, Ex2))
5622 return Error(Sx2,
"malformed expression");
5627 Imm2 =
CE->getValue();
5628 if (!(Imm2 & ~0x1E)) {
5630 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *
this));
5634 "immediate operand must an even number in the range [0, 30]");
5636 return Error(Sx2,
"constant expression expected");
5641 MCAsmParser &Parser = getParser();
5649 const MCExpr *LSBExpr;
5651 if (getParser().parseExpression(LSBExpr))
5652 return Error(
E,
"malformed immediate expression");
5655 return Error(
E,
"'lsb' operand must be an immediate");
5657 int64_t LSB =
CE->getValue();
5659 if (LSB < 0 || LSB > 31)
5660 return Error(
E,
"'lsb' operand must be in the range [0,31]");
5672 const MCExpr *WidthExpr;
5674 if (getParser().parseExpression(WidthExpr, EndLoc))
5675 return Error(
E,
"malformed immediate expression");
5678 return Error(
E,
"'width' operand must be an immediate");
5680 int64_t Width =
CE->getValue();
5682 if (Width < 1 || Width > 32 - LSB)
5683 return Error(
E,
"'width' operand must be in the range [1,32-lsb]");
5685 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *
this));
5699 MCAsmParser &Parser = getParser();
5700 AsmToken Tok = Parser.
getTok();
5702 bool haveEaten =
false;
5714 MCRegister
Reg = tryParseRegister();
5722 unsigned ShiftImm = 0;
5725 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5733 ARMOperand::CreatePostIdxReg(
Reg, isAdd, ShiftTy, ShiftImm, S,
E, *
this));
5750 MCAsmParser &Parser = getParser();
5751 AsmToken Tok = Parser.
getTok();
5763 if (getParser().parseExpression(
Offset,
E))
5767 return Error(S,
"constant expression expected");
5770 int32_t Val =
CE->getValue();
5771 if (isNegative && Val == 0)
5772 Val = std::numeric_limits<int32_t>::min();
5774 Operands.push_back(ARMOperand::CreateImm(
5780 bool haveEaten =
false;
5792 MCRegister
Reg = tryParseRegister();
5799 Operands.push_back(ARMOperand::CreatePostIdxReg(
5807 unsigned MnemonicOpsEndInd) {
5808 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5809 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5810 if (
Op.isCondCode())
5817 unsigned MnemonicOpsEndInd) {
5818 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5819 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5829void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5836 unsigned RegRd = MnemonicOpsEndInd;
5837 unsigned RegRn = MnemonicOpsEndInd + 1;
5838 unsigned RegRm = MnemonicOpsEndInd;
5840 if (
Operands.size() == MnemonicOpsEndInd + 3) {
5845 RegRn = MnemonicOpsEndInd + 2;
5846 RegRm = MnemonicOpsEndInd + 1;
5848 RegRn = MnemonicOpsEndInd + 1;
5849 RegRm = MnemonicOpsEndInd + 2;
5854 ((ARMOperand &)*
Operands[RegRd]).addRegOperands(Inst, 1);
5856 if (CondOutI != 0) {
5857 ((ARMOperand &)*
Operands[CondOutI]).addCCOutOperands(Inst, 1);
5860 *ARMOperand::CreateCCOut(0,
Operands[0]->getEndLoc(), *
this);
5861 Op.addCCOutOperands(Inst, 1);
5864 ((ARMOperand &)*
Operands[RegRn]).addRegOperands(Inst, 1);
5866 ((ARMOperand &)*
Operands[RegRm]).addRegOperands(Inst, 1);
5870 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5872 ARMOperand
Op = *ARMOperand::CreateCondCode(
5874 Op.addCondCodeOperands(Inst, 2);
5878void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5884 :
static_cast<ARMOperand &
>(*
Operands[CondI]).getCondCode());
5892 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5893 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5912 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5913 if (!
op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5919 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5920 if (!
op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5925 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5927 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5929 ARMOperand
Op = *ARMOperand::CreateCondCode(
5931 Op.addCondCodeOperands(Inst, 2);
5935void ARMAsmParser::cvtMVEVMOVQtoDReg(
5944 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1);
5945 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 1])
5946 .addRegOperands(Inst, 1);
5947 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 2])
5948 .addRegOperands(Inst, 1);
5949 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 3])
5950 .addMVEPairVectorIndexOperands(Inst, 1);
5952 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 5])
5953 .addMVEPairVectorIndexOperands(Inst, 1);
5956 .addCondCodeOperands(Inst, 2);
5960 Op.addCondCodeOperands(Inst, 2);
5967 MCAsmParser &Parser = getParser();
5970 return TokError(
"Token is not a Left Bracket");
5974 const AsmToken &BaseRegTok = Parser.
getTok();
5975 MCRegister
BaseReg = tryParseRegister();
5977 return Error(BaseRegTok.
getLoc(),
"register expected");
5980 const AsmToken &Tok = Parser.
getTok();
5983 return Error(Tok.
getLoc(),
"malformed memory operand");
5989 Operands.push_back(ARMOperand::CreateMem(
5996 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6004 "Lost colon or comma in memory operand?!");
6013 SMLoc AlignmentLoc = Tok.
getLoc();
6016 if (getParser().parseExpression(Expr))
6024 return Error (
E,
"constant expression expected");
6027 switch (
CE->getValue()) {
6030 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6031 case 16:
Align = 2;
break;
6032 case 32:
Align = 4;
break;
6033 case 64:
Align = 8;
break;
6034 case 128:
Align = 16;
break;
6035 case 256:
Align = 32;
break;
6046 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, 0,
6048 S,
E, *
this, AlignmentLoc));
6054 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6074 const MCExpr *
Offset, *AdjustedOffset;
6075 if (getParser().parseExpression(
Offset))
6081 int32_t Val =
CE->getValue();
6082 if (isNegative && Val == 0)
6087 AdjustedOffset =
CE;
6090 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6104 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6112 bool isNegative =
false;
6122 MCRegister OffsetReg = tryParseRegister();
6124 return Error(
E,
"register expected");
6128 unsigned ShiftImm = 0;
6131 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6141 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, OffsetReg,
6142 ShiftType, ShiftImm, 0, isNegative,
6149 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6162 MCAsmParser &Parser = getParser();
6164 const AsmToken &Tok = Parser.
getTok();
6166 return Error(Loc,
"illegal shift operator");
6168 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
6169 ShiftName ==
"asl" || ShiftName ==
"ASL")
6171 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
6173 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
6175 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
6177 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
6179 else if (ShiftName ==
"uxtw" || ShiftName ==
"UXTW")
6182 return Error(Loc,
"illegal shift operator");
6190 const AsmToken &HashTok = Parser.
getTok();
6197 if (getParser().parseExpression(Expr))
6204 return Error(Loc,
"shift amount must be an immediate");
6205 int64_t
Imm =
CE->getValue();
6209 return Error(Loc,
"immediate shift value out of range");
6226 MCAsmParser &Parser = getParser();
6253 bool isVmovf =
false;
6255 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
6256 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*
Operands[
I]);
6257 if (TyOp.isToken() &&
6258 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
6259 TyOp.getToken() ==
".f16")) {
6265 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*
Operands[0]);
6266 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
6267 Mnemonic.getToken() ==
"fconsts");
6268 if (!(isVmovf || isFconst))
6274 bool isNegative =
false;
6279 const AsmToken &Tok = Parser.
getTok();
6280 SMLoc Loc = Tok.
getLoc();
6297 if (Val > 255 || Val < 0)
6298 return Error(Loc,
"encoded floating point value out of range");
6300 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
6308 return Error(Loc,
"invalid floating point immediate");
6314 MCAsmParser &Parser = getParser();
6319 ParseStatus ResTy = MatchOperandParserImpl(
Operands, Mnemonic);
6328 switch (getLexer().getKind()) {
6336 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
6338 if (!tryParseRegisterWithWriteBack(
Operands))
6340 int Res = tryParseShiftRegister(
Operands);
6346 if (Mnemonic ==
"vmrs" &&
6350 Operands.push_back(ARMOperand::CreateToken(
"APSR_nzcv", S, *
this));
6365 const MCExpr *IdVal;
6367 if (getParser().parseExpression(IdVal))
6370 Operands.push_back(ARMOperand::CreateImm(IdVal, S,
E, *
this));
6376 bool IsLazyLoadStore = Mnemonic ==
"vlldm" || Mnemonic ==
"vlstm";
6377 bool IsVSCCLRM = Mnemonic ==
"vscclrm";
6379 IsLazyLoadStore, IsVSCCLRM);
6392 auto AdjacentToken = getLexer().peekTok(
false);
6396 if (!ExpectIdentifier) {
6404 const MCExpr *ImmVal;
6405 if (getParser().parseExpression(ImmVal))
6409 int32_t Val =
CE->getValue();
6410 if (IsNegative && Val == 0)
6415 Operands.push_back(ARMOperand::CreateImm(ImmVal, S,
E, *
this));
6421 Operands.push_back(ARMOperand::CreateToken(
6437 if (parsePrefix(Spec))
6440 const MCExpr *SubExprVal;
6441 if (getParser().parseExpression(SubExprVal))
6444 const auto *ExprVal =
6447 Operands.push_back(ARMOperand::CreateImm(ExprVal, S,
E, *
this));
6452 if (Mnemonic !=
"ldr")
6453 return Error(S,
"unexpected token in operand");
6455 const MCExpr *SubExprVal;
6456 if (getParser().parseExpression(SubExprVal))
6463 ARMOperand::CreateConstantPoolImm(SubExprVal, S,
E, *
this));
6469bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6470 const MCExpr *Expr =
nullptr;
6471 SMLoc
L = getParser().getTok().getLoc();
6472 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
6475 if (check(!
Value, L,
"expected constant expression"))
6477 Out =
Value->getValue();
6485 MCAsmParser &Parser = getParser();
6506 static const struct PrefixEntry {
6507 const char *Spelling;
6509 uint8_t SupportedFormats;
6510 } PrefixEntries[] = {
6522 llvm::find_if(PrefixEntries, [&IDVal](
const PrefixEntry &PE) {
6523 return PE.Spelling == IDVal;
6525 if (Prefix == std::end(PrefixEntries)) {
6530 uint8_t CurrentFormat;
6533 CurrentFormat = MACHO;
6536 CurrentFormat =
ELF;
6539 CurrentFormat =
COFF;
6542 CurrentFormat = WASM;
6552 if (~
Prefix->SupportedFormats & CurrentFormat) {
6554 "cannot represent relocation in the current file format");
6578StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6582 unsigned &ProcessorIMod,
6583 StringRef &ITMask) {
6586 CarrySetting =
false;
6592 if ((Mnemonic ==
"movs" &&
isThumb()) || Mnemonic ==
"teq" ||
6593 Mnemonic ==
"vceq" || Mnemonic ==
"svc" || Mnemonic ==
"mls" ||
6594 Mnemonic ==
"smmls" || Mnemonic ==
"vcls" || Mnemonic ==
"vmls" ||
6595 Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" || Mnemonic ==
"vcge" ||
6596 Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" || Mnemonic ==
"vaclt" ||
6597 Mnemonic ==
"vacle" || Mnemonic ==
"hlt" || Mnemonic ==
"vcgt" ||
6598 Mnemonic ==
"vcle" || Mnemonic ==
"smlal" || Mnemonic ==
"umaal" ||
6599 Mnemonic ==
"umlal" || Mnemonic ==
"vabal" || Mnemonic ==
"vmlal" ||
6600 Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" || Mnemonic ==
"fmuls" ||
6601 Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" ||
6602 Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" ||
6603 Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" ||
6604 Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
6605 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vins" ||
6606 Mnemonic ==
"vmovx" || Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
6607 Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" || Mnemonic ==
"vudot" ||
6608 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6609 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"wls" ||
6610 Mnemonic ==
"le" || Mnemonic ==
"dls" || Mnemonic ==
"csel" ||
6611 Mnemonic ==
"csinc" || Mnemonic ==
"csinv" || Mnemonic ==
"csneg" ||
6612 Mnemonic ==
"cinc" || Mnemonic ==
"cinv" || Mnemonic ==
"cneg" ||
6613 Mnemonic ==
"cset" || Mnemonic ==
"csetm" || Mnemonic ==
"aut" ||
6614 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"bti")
6619 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
6620 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
6621 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
6622 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs" &&
6624 (Mnemonic ==
"vmine" || Mnemonic ==
"vshle" || Mnemonic ==
"vshlt" ||
6625 Mnemonic ==
"vshllt" || Mnemonic ==
"vrshle" || Mnemonic ==
"vrshlt" ||
6626 Mnemonic ==
"vmvne" || Mnemonic ==
"vorne" || Mnemonic ==
"vnege" ||
6627 Mnemonic ==
"vnegt" || Mnemonic ==
"vmule" || Mnemonic ==
"vmult" ||
6628 Mnemonic ==
"vrintne" || Mnemonic ==
"vcmult" ||
6629 Mnemonic ==
"vcmule" || Mnemonic ==
"vpsele" || Mnemonic ==
"vpselt" ||
6633 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
6641 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" || Mnemonic ==
"mrs" ||
6642 Mnemonic ==
"smmls" || Mnemonic ==
"vabs" || Mnemonic ==
"vcls" ||
6643 Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" || Mnemonic ==
"vnmls" ||
6644 Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" || Mnemonic ==
"vrsqrts" ||
6645 Mnemonic ==
"srs" || Mnemonic ==
"flds" || Mnemonic ==
"fmrs" ||
6646 Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" || Mnemonic ==
"fsts" ||
6647 Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" || Mnemonic ==
"fmuls" ||
6648 Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" || Mnemonic ==
"vfms" ||
6649 Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" || Mnemonic ==
"bxns" ||
6650 Mnemonic ==
"blxns" || Mnemonic ==
"vfmas" || Mnemonic ==
"vmlas" ||
6651 (Mnemonic ==
"movs" &&
isThumb()))) {
6652 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
6653 CarrySetting =
true;
6661 StringSwitch<unsigned>(Mnemonic.
substr(Mnemonic.
size()-2, 2))
6666 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
6667 ProcessorIMod =
IMod;
6671 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic !=
"vmovlt" &&
6672 Mnemonic !=
"vshllt" && Mnemonic !=
"vrshrnt" && Mnemonic !=
"vshrnt" &&
6673 Mnemonic !=
"vqrshrunt" && Mnemonic !=
"vqshrunt" &&
6674 Mnemonic !=
"vqrshrnt" && Mnemonic !=
"vqshrnt" && Mnemonic !=
"vmullt" &&
6675 Mnemonic !=
"vqmovnt" && Mnemonic !=
"vqmovunt" && Mnemonic !=
"vmovnt" &&
6676 Mnemonic !=
"vqdmullt" && Mnemonic !=
"vpnot" && Mnemonic !=
"vcvtt" &&
6677 Mnemonic !=
"vcvt") {
6681 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-1);
6689 ITMask = Mnemonic.
substr(2);
6690 Mnemonic = Mnemonic.
slice(0, 2);
6694 ITMask = Mnemonic.
substr(4);
6695 Mnemonic = Mnemonic.
slice(0, 4);
6697 ITMask = Mnemonic.
substr(3);
6698 Mnemonic = Mnemonic.
slice(0, 3);
6708void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6709 StringRef ExtraToken,
6711 bool &CanAcceptCarrySet,
6712 bool &CanAcceptPredicationCode,
6713 bool &CanAcceptVPTPredicationCode) {
6714 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6717 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6718 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
6719 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
6720 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
6721 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
6722 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
6723 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
6725 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
6726 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
6728 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
6729 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
6730 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
6732 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vmaxnm" ||
6733 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
6734 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
6735 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
6736 Mnemonic.
starts_with(
"aes") || Mnemonic ==
"hvc" ||
6737 Mnemonic ==
"setpan" || Mnemonic.
starts_with(
"sha1") ||
6740 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" || Mnemonic ==
"vudot" ||
6741 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6742 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"vfmat" ||
6743 Mnemonic ==
"vfmab" || Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" ||
6744 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" || Mnemonic ==
"pssbb" ||
6745 Mnemonic ==
"vsmmla" || Mnemonic ==
"vummla" || Mnemonic ==
"vusmmla" ||
6746 Mnemonic ==
"vusdot" || Mnemonic ==
"vsudot" || Mnemonic ==
"bfcsel" ||
6747 Mnemonic ==
"wls" || Mnemonic ==
"dls" || Mnemonic ==
"le" ||
6748 Mnemonic ==
"csel" || Mnemonic ==
"csinc" || Mnemonic ==
"csinv" ||
6749 Mnemonic ==
"csneg" || Mnemonic ==
"cinc" || Mnemonic ==
"cinv" ||
6750 Mnemonic ==
"cneg" || Mnemonic ==
"cset" || Mnemonic ==
"csetm" ||
6751 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6752 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6754 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"aut" ||
6755 Mnemonic ==
"bti" ||
6762 CanAcceptPredicationCode =
false;
6765 CanAcceptPredicationCode =
6766 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
6767 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
6768 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
6769 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
6770 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
6771 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" && Mnemonic !=
"tsb" &&
6773 }
else if (isThumbOne()) {
6775 CanAcceptPredicationCode = Mnemonic !=
"movs";
6777 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
6779 CanAcceptPredicationCode =
true;
6783 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I) {
6784 auto &
Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
6785 if (
Op.isToken() &&
Op.getToken() ==
".w")
6795void ARMAsmParser::tryConvertingToTwoOperandForm(
6801 if (
Operands.size() != MnemonicOpsEndInd + 3)
6804 const auto &Op3 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
6805 auto &Op4 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
6806 if (!Op3.isReg() || !Op4.isReg())
6809 auto Op3Reg = Op3.getReg();
6810 auto Op4Reg = Op4.getReg();
6816 auto &Op5 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 2]);
6818 if (Mnemonic !=
"add")
6820 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6821 (Op5.isReg() && Op5.getReg() == ARM::PC);
6822 if (!TryTransform) {
6823 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6824 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6825 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6826 Op5.isImm() && !Op5.isImm0_508s4());
6830 }
else if (!isThumbOne())
6833 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
6834 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6835 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
6836 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
6842 bool Transform = Op3Reg == Op4Reg;
6847 const ARMOperand *LastOp = &Op5;
6849 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6850 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
6851 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
6852 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
6863 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
6869 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
6885 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
6895bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6897 if (!hasMVE() ||
Operands.size() <= MnemonicOpsEndInd)
6911 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6912 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6914 getARMMCRegisterClass(ARM::DPRRegClassID)
6915 .
contains((*Operand).getReg())))) {
6925 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6926 static_cast<ARMOperand &
>(*Operand).isQReg())
6942 unsigned VariantID);
6953void ARMAsmParser::fixupGNULDRDAlias(
StringRef Mnemonic,
6955 unsigned MnemonicOpsEndInd) {
6956 if (Mnemonic !=
"ldrd" && Mnemonic !=
"strd" && Mnemonic !=
"ldrexd" &&
6957 Mnemonic !=
"strexd" && Mnemonic !=
"ldaexd" && Mnemonic !=
"stlexd")
6960 unsigned IdX = Mnemonic ==
"strexd" || Mnemonic ==
"stlexd"
6961 ? MnemonicOpsEndInd + 1
6962 : MnemonicOpsEndInd;
6967 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*
Operands[IdX]);
6968 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*
Operands[IdX + 1]);
6972 if (!Op3.isGPRMem())
6980 if (!
isThumb() && (RtEncoding & 1)) {
6985 if (Op2.getReg() == ARM::PC)
6987 MCRegister PairedReg = GPR.
getRegister(RtEncoding + 1);
6988 if (!PairedReg || PairedReg == ARM::PC ||
6989 (PairedReg == ARM::SP && !hasV8Ops()))
6993 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6994 Op2.getEndLoc(), *
this));
7002bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7004 unsigned MnemonicOpsEndInd) {
7005 assert(MS.isCDEDualRegInstr(Mnemonic));
7007 if (
Operands.size() < 3 + MnemonicOpsEndInd)
7011 "operand must be an even-numbered register in the range [r0, r10]");
7013 const MCParsedAsmOperand &Op2 = *
Operands[MnemonicOpsEndInd + 1];
7044 RPair = ARM::R10_R11;
7048 const MCParsedAsmOperand &Op3 = *
Operands[MnemonicOpsEndInd + 2];
7059 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7060 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCondCode()) {
7062 --MnemonicOpsEndInd;
7068 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7069 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCCOut()) {
7071 --MnemonicOpsEndInd;
7077 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7078 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred()) {
7080 --MnemonicOpsEndInd;
7086bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7088 MCAsmParser &Parser = getParser();
7095 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7096 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7102 parseDirectiveReq(Name, NameLoc);
7110 StringRef Mnemonic =
Name.slice(Start,
Next);
7116 unsigned ProcessorIMod;
7119 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7120 CarrySetting, ProcessorIMod, ITMask);
7123 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
7124 return Error(NameLoc,
"conditional execution not supported in Thumb1");
7127 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7140 if (Mnemonic ==
"it" || Mnemonic.
starts_with(
"vpt") ||
7143 Mnemonic ==
"vpt" ? SMLoc::getFromPointer(NameLoc.
getPointer() + 3) :
7144 SMLoc::getFromPointer(NameLoc.
getPointer() + 4);
7145 if (ITMask.
size() > 3) {
7146 if (Mnemonic ==
"it")
7147 return Error(Loc,
"too many conditions on IT instruction");
7148 return Error(Loc,
"too many conditions on VPT instruction");
7152 if (Pos !=
't' && Pos !=
'e') {
7153 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
7159 Operands.push_back(ARMOperand::CreateITMask(Mask, Loc, *
this));
7172 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7173 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7174 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7178 if (!CanAcceptCarrySet && CarrySetting) {
7179 return Error(NameLoc,
"instruction '" + Mnemonic +
7180 "' can not set flags, but 's' suffix specified");
7184 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
7185 return Error(NameLoc,
"instruction '" + Mnemonic +
7186 "' is not predicable, but condition code specified");
7191 if (!CanAcceptVPTPredicationCode && VPTPredicationCode !=
ARMVCC::None) {
7192 return Error(NameLoc,
"instruction '" + Mnemonic +
7193 "' is not VPT predicable, but VPT code T/E is specified");
7197 if (CanAcceptCarrySet && CarrySetting) {
7199 Operands.push_back(ARMOperand::CreateCCOut(
7200 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *
this));
7207 Operands.push_back(ARMOperand::CreateCondCode(
7215 !(Mnemonic.
starts_with(
"vcvt") && Mnemonic !=
"vcvta" &&
7216 Mnemonic !=
"vcvtn" && Mnemonic !=
"vcvtp" && Mnemonic !=
"vcvtm")) {
7219 Operands.push_back(ARMOperand::CreateVPTPred(
7224 if (ProcessorIMod) {
7225 Operands.push_back(ARMOperand::CreateImm(
7228 }
else if (Mnemonic ==
"cps" && isMClass()) {
7229 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
7236 ExtraToken =
Name.slice(Start,
Next);
7245 if (ExtraToken ==
".n" && !
isThumb()) {
7247 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
7254 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
7256 Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc, *
this));
7263 unsigned MnemonicOpsEndInd =
Operands.size();
7268 if (parseOperand(
Operands, Mnemonic)) {
7274 if (parseOperand(
Operands, Mnemonic)) {
7283 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7286 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7294 if (MS.isCDEDualRegInstr(Mnemonic)) {
7296 CDEConvertDualRegOperand(Mnemonic,
Operands, MnemonicOpsEndInd);
7303 if (!shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7304 MnemonicOpsEndInd) &&
7305 Mnemonic ==
"vmov" && PredicationCode ==
ARMCC::LT) {
7313 Mnemonic.
size() - 1 + CarrySetting);
7317 StringRef(
"vmovlt"), MLoc, *
this));
7318 }
else if (Mnemonic ==
"vcvt" && PredicationCode ==
ARMCC::NE &&
7319 !shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7320 MnemonicOpsEndInd)) {
7329 Mnemonic.
size() - 1 + CarrySetting);
7333 ARMOperand::CreateToken(StringRef(
"vcvtn"), MLoc, *
this));
7334 }
else if (Mnemonic ==
"vmul" && PredicationCode ==
ARMCC::LT &&
7335 !shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7336 MnemonicOpsEndInd)) {
7344 StringRef(
"vmullt"), MLoc, *
this));
7349 if (!shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7350 MnemonicOpsEndInd)) {
7357 if (Mnemonic.
starts_with(
"vcvtt") && MnemonicOpsEndInd > 2) {
7359 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd - 2]);
7361 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd - 1]);
7362 if (!(Sz1.isToken() && Sz1.getToken().starts_with(
".f") &&
7363 Sz2.isToken() && Sz2.getToken().starts_with(
".f"))) {
7368 Mnemonic = Mnemonic.
substr(0, 4);
7370 ARMOperand::CreateToken(Mnemonic, MLoc, *
this));
7374 Mnemonic.
size() + CarrySetting);
7377 ARMOperand::CreateVPTPred(
7379 ++MnemonicOpsEndInd;
7381 }
else if (CanAcceptVPTPredicationCode) {
7385 if (shouldOmitVectorPredicateOperand(Mnemonic,
Operands,
7386 MnemonicOpsEndInd)) {
7393 bool usedVPTPredicationCode =
false;
7395 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred())
7396 usedVPTPredicationCode =
true;
7397 if (!usedVPTPredicationCode) {
7405 Mnemonic =
Name.slice(0, Mnemonic.
size() + 1);
7408 ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7417 if (!
isThumb() && Mnemonic ==
"blx" &&
7418 Operands.size() == MnemonicOpsEndInd + 1 &&
7419 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).isImm())
7423 fixupGNULDRDAlias(Mnemonic,
Operands, MnemonicOpsEndInd);
7432 bool IsLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
7433 if (!
isThumb() &&
Operands.size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7434 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
7435 Mnemonic ==
"stlexd")) {
7436 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7437 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*
Operands[Idx]);
7438 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*
Operands[Idx + 1]);
7440 const MCRegisterClass &MRC = MRI->
getRegClass(ARM::GPRRegClassID);
7442 if (Op1.isReg() && MRC.
contains(Op1.getReg())) {
7443 MCRegister Reg1 = Op1.getReg();
7445 MCRegister Reg2 = Op2.getReg();
7449 return Error(Op2.getStartLoc(),
7450 IsLoad ?
"destination operands must be sequential"
7451 :
"source operands must be sequential");
7457 IsLoad ?
"destination operands must start start at an even register"
7458 :
"source operands must start start at an even register");
7461 Reg1, ARM::gsub_0, &(MRI->
getRegClass(ARM::GPRPairRegClassID)));
7462 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7463 Op2.getEndLoc(), *
this);
7473 if (isThumbTwo() && Mnemonic ==
"sub" && CarrySetting &&
7474 Operands.size() == MnemonicOpsEndInd + 3 &&
7475 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).isReg() &&
7476 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]).getReg() ==
7478 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]).isReg() &&
7479 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]).getReg() ==
7481 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 2]).isImm()) {
7482 Operands.front() = ARMOperand::CreateToken(
"subs", NameLoc, *
this);
7522 return Inst.
getOpcode() == ARM::tBKPT ||
7529 unsigned MnemonicOpsEndInd) {
7530 for (
unsigned I = MnemonicOpsEndInd;
I <
Operands.size(); ++
I) {
7531 const ARMOperand &
Op =
static_cast<const ARMOperand &
>(*
Operands[
I]);
7532 if (
Op.isRegList()) {
7539bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
7541 unsigned MnemonicOpsEndInd,
7542 unsigned ListIndex,
bool IsARPop) {
7547 if (!IsARPop && ListContainsSP)
7550 "SP may not be in the register list");
7551 if (ListContainsPC && ListContainsLR)
7554 "PC and LR may not be in the register list simultaneously");
7558bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
7560 unsigned MnemonicOpsEndInd,
7561 unsigned ListIndex) {
7565 if (ListContainsSP && ListContainsPC)
7568 "SP and PC may not be in the register list");
7572 "SP may not be in the register list");
7576 "PC may not be in the register list");
7581 bool Load,
bool ARMMode,
bool Writeback,
7582 unsigned MnemonicOpsEndInd) {
7583 unsigned RtIndex =
Load || !Writeback ? 0 : 1;
7596 "Rt must be even-numbered");
7599 if (Rt2 != Rt + 1) {
7602 "destination operands must be sequential");
7605 "source operands must be sequential");
7612 if (!ARMMode &&
Load) {
7615 "destination operands can't be identical");
7621 if (Rn == Rt || Rn == Rt2) {
7624 "base register needs to be different from destination "
7627 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7628 "source register and base register can't be identical");
7639 for (
unsigned i = 0; i <
MCID.NumOperands; ++i) {
7651 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
7658bool ARMAsmParser::validateInstruction(MCInst &Inst,
7660 unsigned MnemonicOpsEndInd) {
7661 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
7662 SMLoc Loc =
Operands[0]->getStartLoc();
7670 return Error(Loc,
"instructions in IT block must be predicable");
7673 if (
Cond != currentITCond()) {
7675 SMLoc CondLoc =
Operands[0]->getEndLoc();
7677 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCondCode())
7679 return Error(CondLoc,
"incorrect condition in IT block; got '" +
7681 "', but expected '" +
7690 return Error(Loc,
"predicated instructions must be in IT block");
7694 return Warning(Loc,
"predicated instructions should be in IT block");
7701 if (MCID.
operands()[i].isPredicate()) {
7703 return Error(Loc,
"instruction is not predicable");
7711 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7712 return Error(Loc,
"instruction must be outside of IT block or the last instruction in an IT block");
7716 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7718 return Error(Loc,
"instruction in VPT block must be predicable");
7721 if (Pred != VPTPred) {
7724 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred())
7726 return Error(PredLoc,
"incorrect predication in VPT block; got '" +
7728 "', but expected '" +
7735 return Error(Loc,
"VPT predicated instructions must be in VPT block");
7737 const unsigned Opcode = Inst.
getOpcode();
7742 case ARM::VLSTM_T2: {
7746 MnemonicOpsEndInd + 2) {
7747 ARMOperand &
Op =
static_cast<ARMOperand &
>(
7750 auto &RegList =
Op.getRegList();
7752 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7753 return Error(
Op.getEndLoc(),
"T2 version requires v8.1-M.Main");
7756 if (hasD32() && RegList.size() != 32) {
7757 return Error(
Op.getEndLoc(),
"operand must be exactly {d0-d31}");
7760 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7762 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7778 return Error(Loc,
"unpredictable IT predicate sequence");
7782 if (validateLDRDSTRD(Inst,
Operands,
true,
true,
7783 false, MnemonicOpsEndInd))
7787 case ARM::LDRD_POST:
7788 if (validateLDRDSTRD(Inst,
Operands,
true,
true,
7789 true, MnemonicOpsEndInd))
7793 if (validateLDRDSTRD(Inst,
Operands,
true,
false,
7794 false, MnemonicOpsEndInd))
7797 case ARM::t2LDRD_PRE:
7798 case ARM::t2LDRD_POST:
7799 if (validateLDRDSTRD(Inst,
Operands,
true,
false,
7800 true, MnemonicOpsEndInd))
7806 if (RmReg == ARM::SP && !hasV8Ops())
7808 "r13 (SP) is an unpredictable operand to BXJ");
7812 if (validateLDRDSTRD(Inst,
Operands,
false,
true,
7813 false, MnemonicOpsEndInd))
7817 case ARM::STRD_POST:
7818 if (validateLDRDSTRD(Inst,
Operands,
false,
true,
7819 true, MnemonicOpsEndInd))
7822 case ARM::t2STRD_PRE:
7823 case ARM::t2STRD_POST:
7824 if (validateLDRDSTRD(Inst,
Operands,
false,
false,
7825 true, MnemonicOpsEndInd))
7828 case ARM::STR_PRE_IMM:
7829 case ARM::STR_PRE_REG:
7830 case ARM::t2STR_PRE:
7831 case ARM::STR_POST_IMM:
7832 case ARM::STR_POST_REG:
7833 case ARM::t2STR_POST:
7835 case ARM::t2STRH_PRE:
7836 case ARM::STRH_POST:
7837 case ARM::t2STRH_POST:
7838 case ARM::STRB_PRE_IMM:
7839 case ARM::STRB_PRE_REG:
7840 case ARM::t2STRB_PRE:
7841 case ARM::STRB_POST_IMM:
7842 case ARM::STRB_POST_REG:
7843 case ARM::t2STRB_POST: {
7849 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7850 "source register and base register can't be identical");
7853 case ARM::t2LDR_PRE_imm:
7854 case ARM::t2LDR_POST_imm:
7855 case ARM::t2STR_PRE_imm:
7856 case ARM::t2STR_POST_imm: {
7863 "destination register and base register can't be identical");
7864 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7865 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7867 if (
Imm > 255 ||
Imm < -255)
7868 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7869 "operand must be in range [-255, 255]");
7871 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7872 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7875 "operand must be a register in range [r0, r14]");
7881 case ARM::t2LDRB_OFFSET_imm:
7882 case ARM::t2LDRB_PRE_imm:
7883 case ARM::t2LDRB_POST_imm:
7884 case ARM::t2STRB_OFFSET_imm:
7885 case ARM::t2STRB_PRE_imm:
7886 case ARM::t2STRB_POST_imm: {
7887 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7888 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7889 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7890 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7892 if (
Imm > 255 ||
Imm < -255)
7893 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7894 "operand must be in range [-255, 255]");
7895 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7896 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7898 if (
Imm > 0 ||
Imm < -255)
7899 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7900 "operand must be in range [0, 255] with a negative sign");
7904 "if operand is PC, should call the LDRB (literal)");
7909 case ARM::t2LDRH_OFFSET_imm:
7910 case ARM::t2LDRH_PRE_imm:
7911 case ARM::t2LDRH_POST_imm:
7912 case ARM::t2STRH_OFFSET_imm:
7913 case ARM::t2STRH_PRE_imm:
7914 case ARM::t2STRH_POST_imm: {
7915 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7916 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7917 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7918 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7920 if (
Imm > 255 ||
Imm < -255)
7921 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7922 "operand must be in range [-255, 255]");
7923 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7924 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7926 if (
Imm > 0 ||
Imm < -255)
7927 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7928 "operand must be in range [0, 255] with a negative sign");
7932 "if operand is PC, should call the LDRH (literal)");
7937 case ARM::t2LDRSB_OFFSET_imm:
7938 case ARM::t2LDRSB_PRE_imm:
7939 case ARM::t2LDRSB_POST_imm: {
7940 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7941 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7943 if (
Imm > 255 ||
Imm < -255)
7944 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7945 "operand must be in range [-255, 255]");
7946 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7948 if (
Imm > 0 ||
Imm < -255)
7949 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7950 "operand must be in range [0, 255] with a negative sign");
7953 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7954 "if operand is PC, should call the LDRH (literal)");
7959 case ARM::t2LDRSH_OFFSET_imm:
7960 case ARM::t2LDRSH_PRE_imm:
7961 case ARM::t2LDRSH_POST_imm: {
7962 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7963 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7965 if (
Imm > 255 ||
Imm < -255)
7966 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7967 "operand must be in range [-255, 255]");
7968 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7970 if (
Imm > 0 ||
Imm < -255)
7971 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7972 "operand must be in range [0, 255] with a negative sign");
7976 "if operand is PC, should call the LDRH (literal)");
7981 case ARM::LDR_PRE_IMM:
7982 case ARM::LDR_PRE_REG:
7983 case ARM::t2LDR_PRE:
7984 case ARM::LDR_POST_IMM:
7985 case ARM::LDR_POST_REG:
7986 case ARM::t2LDR_POST:
7988 case ARM::t2LDRH_PRE:
7989 case ARM::LDRH_POST:
7990 case ARM::t2LDRH_POST:
7991 case ARM::LDRSH_PRE:
7992 case ARM::t2LDRSH_PRE:
7993 case ARM::LDRSH_POST:
7994 case ARM::t2LDRSH_POST:
7995 case ARM::LDRB_PRE_IMM:
7996 case ARM::LDRB_PRE_REG:
7997 case ARM::t2LDRB_PRE:
7998 case ARM::LDRB_POST_IMM:
7999 case ARM::LDRB_POST_REG:
8000 case ARM::t2LDRB_POST:
8001 case ARM::LDRSB_PRE:
8002 case ARM::t2LDRSB_PRE:
8003 case ARM::LDRSB_POST:
8004 case ARM::t2LDRSB_POST: {
8011 "destination register and base register can't be identical");
8015 case ARM::MVE_VLDRBU8_rq:
8016 case ARM::MVE_VLDRBU16_rq:
8017 case ARM::MVE_VLDRBS16_rq:
8018 case ARM::MVE_VLDRBU32_rq:
8019 case ARM::MVE_VLDRBS32_rq:
8020 case ARM::MVE_VLDRHU16_rq:
8021 case ARM::MVE_VLDRHU16_rq_u:
8022 case ARM::MVE_VLDRHU32_rq:
8023 case ARM::MVE_VLDRHU32_rq_u:
8024 case ARM::MVE_VLDRHS32_rq:
8025 case ARM::MVE_VLDRHS32_rq_u:
8026 case ARM::MVE_VLDRWU32_rq:
8027 case ARM::MVE_VLDRWU32_rq_u:
8028 case ARM::MVE_VLDRDU64_rq:
8029 case ARM::MVE_VLDRDU64_rq_u:
8030 case ARM::MVE_VLDRWU32_qi:
8031 case ARM::MVE_VLDRWU32_qi_pre:
8032 case ARM::MVE_VLDRDU64_qi:
8033 case ARM::MVE_VLDRDU64_qi_pre: {
8035 unsigned QdIdx = 0, QmIdx = 2;
8036 bool QmIsPointer =
false;
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRDU64_qi:
8043 case ARM::MVE_VLDRWU32_qi_pre:
8044 case ARM::MVE_VLDRDU64_qi_pre:
8055 Twine(
"destination vector register and vector ") +
8056 (QmIsPointer ?
"pointer" :
"offset") +
8057 " register can't be identical");
8069 if (Widthm1 >= 32 - LSB)
8070 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8071 "bitfield width must be in range [1,32-lsb]");
8083 bool HasWritebackToken =
8084 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8086 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8089 bool ListContainsBase;
8094 "registers must be in range r0-r7");
8096 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8099 "writeback operator '!' expected");
8102 if (ListContainsBase && HasWritebackToken)
8103 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8104 "writeback operator '!' not allowed when base register "
8105 "in register list");
8107 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8111 case ARM::LDMIA_UPD:
8112 case ARM::LDMDB_UPD:
8113 case ARM::LDMIB_UPD:
8114 case ARM::LDMDA_UPD:
8121 "writeback register not allowed in register list");
8125 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8130 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8133 case ARM::t2LDMIA_UPD:
8134 case ARM::t2LDMDB_UPD:
8135 case ARM::t2STMIA_UPD:
8136 case ARM::t2STMDB_UPD:
8139 "writeback register not allowed in register list");
8141 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8142 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8145 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8150 case ARM::sysLDMIA_UPD:
8151 case ARM::sysLDMDA_UPD:
8152 case ARM::sysLDMDB_UPD:
8153 case ARM::sysLDMIB_UPD:
8155 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8156 "writeback register only allowed on system LDM "
8157 "if PC in register-list");
8159 case ARM::sysSTMIA_UPD:
8160 case ARM::sysSTMDA_UPD:
8161 case ARM::sysSTMDB_UPD:
8162 case ARM::sysSTMIB_UPD:
8164 "system STM cannot have writeback register");
8169 bool ListContainsBase;
8171 ListContainsBase) &&
8174 "registers must be in range r0-r7 or pc");
8175 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 2, !isMClass()))
8180 bool ListContainsBase;
8182 ListContainsBase) &&
8185 "registers must be in range r0-r7 or lr");
8186 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 2))
8190 case ARM::tSTMIA_UPD: {
8191 bool ListContainsBase, InvalidLowList;
8193 0, ListContainsBase);
8194 if (InvalidLowList && !isThumbTwo())
8195 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8196 "registers must be in range r0-r7");
8200 if (InvalidLowList && ListContainsBase)
8202 "writeback operator '!' not allowed when base register "
8203 "in register list");
8205 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 4))
8212 if (!isThumbTwo() &&
8214 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8215 "source register must be the same as destination");
8225 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8226 "source register must be sp if destination is sp");
8231 if (!(
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]))
8232 .isSignedOffset<11, 1>())
8234 "branch target out of range");
8237 int op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8238 : MnemonicOpsEndInd + 1;
8239 ARMOperand &Operand =
static_cast<ARMOperand &
>(*
Operands[
op]);
8242 !Operand.isSignedOffset<24, 1>())
8243 return Error(
Operands[
op]->getStartLoc(),
"branch target out of range");
8248 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8249 .isSignedOffset<8, 1>())
8251 "branch target out of range");
8254 int Op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8255 : MnemonicOpsEndInd + 1;
8256 if (!
static_cast<ARMOperand &
>(*
Operands[
Op]).isSignedOffset<20, 1>())
8257 return Error(
Operands[
Op]->getStartLoc(),
"branch target out of range");
8262 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8263 .isUnsignedOffset<6, 1>())
8264 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8265 "branch target out of range");
8271 case ARM::t2MOVTi16:
8279 int i = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8280 : MnemonicOpsEndInd + 1;
8281 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[i]);
8282 const MCExpr *
E =
Op.getImm();
8286 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8290 "immediate expression for mov requires :lower16: or :upper16");
8294 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8295 : MnemonicOpsEndInd + 2;
8298 return Error(
Op.getStartLoc(),
8299 "Immediate expression for Thumb adds requires :lower0_7:,"
8300 " :lower8_15:, :upper0_7: or :upper8_15:");
8304 MCParsedAsmOperand &
Op = *
Operands[MnemonicOpsEndInd + 1];
8306 return Error(
Op.getStartLoc(),
8307 "Immediate expression for Thumb movs requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8317 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
8318 return Error(
Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8319 "predicable, but condition "
8322 return Error(
Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8323 "predicable, but condition "
8331 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8332 .isUnsignedOffset<4, 1>() ||
8335 "branch location out of range or not a multiple of 2");
8338 if (Opcode == ARM::t2BFi) {
8339 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8340 .isSignedOffset<16, 1>())
8342 "branch target out of range or not a multiple of 2");
8343 }
else if (Opcode == ARM::t2BFLi) {
8344 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8345 .isSignedOffset<18, 1>())
8347 "branch target out of range or not a multiple of 2");
8352 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8353 .isUnsignedOffset<4, 1>() ||
8356 "branch location out of range or not a multiple of 2");
8358 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8359 .isSignedOffset<16, 1>())
8360 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8361 "branch target out of range or not a multiple of 2");
8364 "branch location and else branch target should either both be "
8365 "immediates or both labels");
8369 if (Diff != 4 && Diff != 2)
8372 "else branch target must be 2 or 4 greater than the branch location");
8379 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8382 "invalid register in register list. Valid registers are "
8383 "r0-r12, lr/r14 and APSR.");
8400 "instruction 'ssbb' is not predicable, but condition code "
8404 "instruction 'pssbb' is not predicable, but condition code "
8408 case ARM::VMOVRRS: {
8413 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8414 "source operands must be sequential");
8417 case ARM::VMOVSRR: {
8423 "destination operands must be sequential");
8427 case ARM::VSTMDIA: {
8429 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
8430 auto &RegList =
Op.getRegList();
8431 if (RegList.size() < 1 || RegList.size() > 16)
8432 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8433 "list of registers must be at least 1 and at most 16");
8436 case ARM::MVE_VQDMULLs32bh:
8437 case ARM::MVE_VQDMULLs32th:
8438 case ARM::MVE_VCMULf32:
8439 case ARM::MVE_VMULLBs32:
8440 case ARM::MVE_VMULLTs32:
8441 case ARM::MVE_VMULLBu32:
8442 case ARM::MVE_VMULLTu32: {
8446 "Qd register and Qn register can't be identical");
8451 "Qd register and Qm register can't be identical");
8455 case ARM::MVE_VREV64_8:
8456 case ARM::MVE_VREV64_16:
8457 case ARM::MVE_VREV64_32:
8458 case ARM::MVE_VQDMULL_qr_s32bh:
8459 case ARM::MVE_VQDMULL_qr_s32th: {
8463 "Qd register and Qn register can't be identical");
8467 case ARM::MVE_VCADDi32:
8468 case ARM::MVE_VCADDf32:
8469 case ARM::MVE_VHCADDs32: {
8473 "Qd register and Qm register can't be identical");
8477 case ARM::MVE_VMOV_rr_q: {
8480 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8481 "Q-registers must be the same");
8482 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8483 .getVectorIndex() !=
8484 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 5])
8487 return Error(
Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8488 "Q-register indexes must be 2 and 0 or 3 and 1");
8491 case ARM::MVE_VMOV_q_rr: {
8495 "Q-registers must be the same");
8496 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8497 .getVectorIndex() !=
8498 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8501 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8502 "Q-register indexes must be 2 and 0 or 3 and 1");
8505 case ARM::MVE_SQRSHR:
8506 case ARM::MVE_UQRSHL: {
8510 "Rda register and Rm register can't be identical");
8531 case ARM::t2SMLALBB:
8532 case ARM::t2SMLALBT:
8534 case ARM::t2SMLALDX:
8535 case ARM::t2SMLALTB:
8536 case ARM::t2SMLALTT:
8538 case ARM::t2SMLSLDX:
8539 case ARM::t2SMULL: {
8544 "unpredictable instruction, RdHi and RdLo must be different");
8552 case ARM::CDE_CX1DA:
8556 case ARM::CDE_CX2DA:
8560 case ARM::CDE_CX3DA:
8561 case ARM::CDE_VCX1_vec:
8562 case ARM::CDE_VCX1_fpsp:
8563 case ARM::CDE_VCX1_fpdp:
8564 case ARM::CDE_VCX1A_vec:
8565 case ARM::CDE_VCX1A_fpsp:
8566 case ARM::CDE_VCX1A_fpdp:
8567 case ARM::CDE_VCX2_vec:
8568 case ARM::CDE_VCX2_fpsp:
8569 case ARM::CDE_VCX2_fpdp:
8570 case ARM::CDE_VCX2A_vec:
8571 case ARM::CDE_VCX2A_fpsp:
8572 case ARM::CDE_VCX2A_fpdp:
8573 case ARM::CDE_VCX3_vec:
8574 case ARM::CDE_VCX3_fpsp:
8575 case ARM::CDE_VCX3_fpdp:
8576 case ARM::CDE_VCX3A_vec:
8577 case ARM::CDE_VCX3A_fpsp:
8578 case ARM::CDE_VCX3A_fpdp: {
8580 "CDE operand 1 must be a coprocessor ID");
8584 "coprocessor must be configured as CDE");
8585 else if (Coproc >= 8)
8587 "coprocessor must be in the range [p0, p7]");
8593 case ARM::t2LDC2L_OFFSET:
8594 case ARM::t2LDC2L_OPTION:
8595 case ARM::t2LDC2L_POST:
8596 case ARM::t2LDC2L_PRE:
8597 case ARM::t2LDC2_OFFSET:
8598 case ARM::t2LDC2_OPTION:
8599 case ARM::t2LDC2_POST:
8600 case ARM::t2LDC2_PRE:
8601 case ARM::t2LDCL_OFFSET:
8602 case ARM::t2LDCL_OPTION:
8603 case ARM::t2LDCL_POST:
8604 case ARM::t2LDCL_PRE:
8605 case ARM::t2LDC_OFFSET:
8606 case ARM::t2LDC_OPTION:
8607 case ARM::t2LDC_POST:
8608 case ARM::t2LDC_PRE:
8617 case ARM::t2STC2L_OFFSET:
8618 case ARM::t2STC2L_OPTION:
8619 case ARM::t2STC2L_POST:
8620 case ARM::t2STC2L_PRE:
8621 case ARM::t2STC2_OFFSET:
8622 case ARM::t2STC2_OPTION:
8623 case ARM::t2STC2_POST:
8624 case ARM::t2STC2_PRE:
8625 case ARM::t2STCL_OFFSET:
8626 case ARM::t2STCL_OPTION:
8627 case ARM::t2STCL_POST:
8628 case ARM::t2STCL_PRE:
8629 case ARM::t2STC_OFFSET:
8630 case ARM::t2STC_OPTION:
8631 case ARM::t2STC_POST:
8632 case ARM::t2STC_PRE: {
8637 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8639 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8642 "Operand must be a coprocessor ID");
8647 "coprocessor must be configured as GCP");
8678 "source and destination registers must be the same");
8690 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8691 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8693 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8694 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8695 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8696 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8697 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8698 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8701 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8702 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8704 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8707 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8708 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8709 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8710 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8711 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8713 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8714 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8715 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8716 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8717 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8720 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8721 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8723 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8725 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8726 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8727 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8728 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8729 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8730 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8731 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8732 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8733 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8734 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8737 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8738 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8739 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8740 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8741 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8742 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8743 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8744 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8745 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8746 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8747 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8748 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8749 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8750 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8751 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8752 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8753 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8754 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8757 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8758 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8760 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8762 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8763 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8764 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8765 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8766 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8767 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8768 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8769 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8770 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8771 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8774 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8775 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8776 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8777 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8778 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8779 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8780 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8781 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8782 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8783 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8784 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8785 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8786 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8787 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8788 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8789 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8790 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8791 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8799 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8800 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8802 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8805 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8806 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8807 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8810 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8811 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8813 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8815 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8818 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8820 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8821 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8822 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8823 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8824 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8827 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8828 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8830 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8833 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8836 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8839 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8840 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8841 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8842 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8843 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8844 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8847 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8848 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8850 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8852 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8855 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8857 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8858 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8859 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8860 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8861 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8864 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8865 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8867 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8870 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8871 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8872 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8873 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8874 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8875 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8876 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8877 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8878 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8879 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8880 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8881 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8884 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8885 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8887 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8889 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8892 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8894 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8895 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8896 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8897 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8898 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8901 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8902 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8904 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8907 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8910 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8913 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8914 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8915 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8916 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8917 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8918 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8921 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8922 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8924 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8927 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8928 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8929 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8930 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8931 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8932 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8933 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8934 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8935 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8936 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8937 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8938 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8942bool ARMAsmParser::processInstruction(MCInst &Inst,
8944 unsigned MnemonicOpsEndInd,
8948 bool HasWideQualifier =
false;
8950 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8951 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8952 HasWideQualifier =
true;
8963 MnemonicOpsEndInd + 2) {
8964 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8967 auto &RegList =
Op.getRegList();
8970 if (RegList.size() == 32) {
8971 const unsigned Opcode =
8972 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8986 case ARM::LDRT_POST:
8987 case ARM::LDRBT_POST: {
8988 const unsigned Opcode =
8989 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8990 : ARM::LDRBT_POST_IMM;
9006 case ARM::LDRSHTii: {
9011 else if (Inst.
getOpcode() == ARM::LDRHTii)
9013 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9024 case ARM::STRT_POST:
9025 case ARM::STRBT_POST: {
9026 const unsigned Opcode =
9027 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9028 : ARM::STRBT_POST_IMM;
9077 case ARM::t2LDR_PRE_imm:
9078 case ARM::t2LDR_POST_imm: {
9092 case ARM::t2STR_PRE_imm:
9093 case ARM::t2STR_POST_imm: {
9107 case ARM::t2LDRB_OFFSET_imm: {
9117 case ARM::t2LDRB_PRE_imm:
9118 case ARM::t2LDRB_POST_imm: {
9122 : ARM::t2LDRB_POST);
9133 case ARM::t2STRB_OFFSET_imm: {
9143 case ARM::t2STRB_PRE_imm:
9144 case ARM::t2STRB_POST_imm: {
9148 : ARM::t2STRB_POST);
9159 case ARM::t2LDRH_OFFSET_imm: {
9169 case ARM::t2LDRH_PRE_imm:
9170 case ARM::t2LDRH_POST_imm: {
9174 : ARM::t2LDRH_POST);
9185 case ARM::t2STRH_OFFSET_imm: {
9195 case ARM::t2STRH_PRE_imm:
9196 case ARM::t2STRH_POST_imm: {
9200 : ARM::t2STRH_POST);
9211 case ARM::t2LDRSB_OFFSET_imm: {
9221 case ARM::t2LDRSB_PRE_imm:
9222 case ARM::t2LDRSB_POST_imm: {
9226 : ARM::t2LDRSB_POST);
9237 case ARM::t2LDRSH_OFFSET_imm: {
9247 case ARM::t2LDRSH_PRE_imm:
9248 case ARM::t2LDRSH_POST_imm: {
9252 : ARM::t2LDRSH_POST);
9263 case ARM::t2LDRpcrel:
9272 case ARM::t2LDRBpcrel:
9275 case ARM::t2LDRHpcrel:
9278 case ARM::t2LDRSBpcrel:
9281 case ARM::t2LDRSHpcrel:
9284 case ARM::LDRConstPool:
9285 case ARM::tLDRConstPool:
9286 case ARM::t2LDRConstPool: {
9291 if (Inst.
getOpcode() == ARM::LDRConstPool)
9293 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9295 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9297 const ARMOperand &PoolOperand =
9298 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
9299 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9307 bool MovHasS =
true;
9308 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9318 else if (hasV6T2Ops() &&
9331 else if (hasThumb2() &&
9336 else if (hasV8MBaseline() &&
9356 const MCExpr *CPLoc =
9357 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9358 PoolOperand.getStartLoc());
9369 case ARM::VST1LNdWB_register_Asm_8:
9370 case ARM::VST1LNdWB_register_Asm_16:
9371 case ARM::VST1LNdWB_register_Asm_32: {
9389 case ARM::VST2LNdWB_register_Asm_8:
9390 case ARM::VST2LNdWB_register_Asm_16:
9391 case ARM::VST2LNdWB_register_Asm_32:
9392 case ARM::VST2LNqWB_register_Asm_16:
9393 case ARM::VST2LNqWB_register_Asm_32: {
9413 case ARM::VST3LNdWB_register_Asm_8:
9414 case ARM::VST3LNdWB_register_Asm_16:
9415 case ARM::VST3LNdWB_register_Asm_32:
9416 case ARM::VST3LNqWB_register_Asm_16:
9417 case ARM::VST3LNqWB_register_Asm_32: {
9439 case ARM::VST4LNdWB_register_Asm_8:
9440 case ARM::VST4LNdWB_register_Asm_16:
9441 case ARM::VST4LNdWB_register_Asm_32:
9442 case ARM::VST4LNqWB_register_Asm_16:
9443 case ARM::VST4LNqWB_register_Asm_32: {
9467 case ARM::VST1LNdWB_fixed_Asm_8:
9468 case ARM::VST1LNdWB_fixed_Asm_16:
9469 case ARM::VST1LNdWB_fixed_Asm_32: {
9487 case ARM::VST2LNdWB_fixed_Asm_8:
9488 case ARM::VST2LNdWB_fixed_Asm_16:
9489 case ARM::VST2LNdWB_fixed_Asm_32:
9490 case ARM::VST2LNqWB_fixed_Asm_16:
9491 case ARM::VST2LNqWB_fixed_Asm_32: {
9511 case ARM::VST3LNdWB_fixed_Asm_8:
9512 case ARM::VST3LNdWB_fixed_Asm_16:
9513 case ARM::VST3LNdWB_fixed_Asm_32:
9514 case ARM::VST3LNqWB_fixed_Asm_16:
9515 case ARM::VST3LNqWB_fixed_Asm_32: {
9537 case ARM::VST4LNdWB_fixed_Asm_8:
9538 case ARM::VST4LNdWB_fixed_Asm_16:
9539 case ARM::VST4LNdWB_fixed_Asm_32:
9540 case ARM::VST4LNqWB_fixed_Asm_16:
9541 case ARM::VST4LNqWB_fixed_Asm_32: {
9565 case ARM::VST1LNdAsm_8:
9566 case ARM::VST1LNdAsm_16:
9567 case ARM::VST1LNdAsm_32: {