59 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
60 cl::desc(
"Allow conditional instructions outdside of an IT block"),
62 "Accept in both ISAs, emit implicit ITs in Thumb"),
64 "Warn in ARM, reject in Thumb"),
66 "Accept in ARM, reject in Thumb"),
67 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
68 "Warn in ARM, emit implicit ITs in Thumb")));
82 Locs PersonalityIndexLocs;
89 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
90 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
91 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
92 bool hasPersonality()
const {
93 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
96 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
97 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
98 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
99 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
100 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
102 void saveFPReg(
int Reg) { FPReg =
Reg; }
103 int getFPReg()
const {
return FPReg; }
105 void emitFnStartLocNotes()
const {
106 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
108 Parser.Note(*FI,
".fnstart was specified here");
110 void emitCantUnwindLocNotes()
const {
111 for (Locs::const_iterator UI = CantUnwindLocs.begin(),
112 UE = CantUnwindLocs.end(); UI != UE; ++UI)
113 Parser.Note(*UI,
".cantunwind was specified here");
115 void emitHandlerDataLocNotes()
const {
116 for (Locs::const_iterator
HI = HandlerDataLocs.begin(),
117 HE = HandlerDataLocs.end();
HI != HE; ++
HI)
118 Parser.Note(*
HI,
".handlerdata was specified here");
120 void emitPersonalityLocNotes()
const {
121 for (Locs::const_iterator PI = PersonalityLocs.begin(),
122 PE = PersonalityLocs.end(),
123 PII = PersonalityIndexLocs.begin(),
124 PIE = PersonalityIndexLocs.end();
125 PI != PE || PII != PIE;) {
126 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
127 Parser.Note(*PI++,
".personality was specified here");
128 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
129 Parser.Note(*PII++,
".personalityindex was specified here");
132 "at the same location");
137 FnStartLocs = Locs();
138 CantUnwindLocs = Locs();
139 PersonalityLocs = Locs();
140 HandlerDataLocs = Locs();
141 PersonalityIndexLocs = Locs();
152 assert(getParser().getStreamer().getTargetStreamer() &&
153 "do not have a target streamer");
161 bool NextSymbolIsThumb;
163 bool useImplicitITThumb()
const {
165 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
168 bool useImplicitITARM()
const {
170 ImplicitItMode == ImplicitItModeTy::ARMOnly;
185 unsigned CurPosition;
200 void flushPendingInstructions(
MCStreamer &Out)
override {
201 if (!inImplicitITBlock()) {
202 assert(PendingConditionalInsts.size() == 0);
207 unsigned Mask = getITMaskEncoding();
215 assert(PendingConditionalInsts.size() <= 4);
216 for (
const MCInst &Inst : PendingConditionalInsts) {
219 PendingConditionalInsts.clear();
223 ITState.CurPosition = ~0U;
226 bool inITBlock() {
return ITState.CurPosition != ~0U; }
227 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
228 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
229 bool lastInITBlock() {
232 void forwardITPosition() {
233 if (!inITBlock())
return;
238 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
239 ITState.CurPosition = ~0U;
243 void rewindImplicitITPosition() {
244 assert(inImplicitITBlock());
245 assert(ITState.CurPosition > 1);
246 ITState.CurPosition--;
248 unsigned NewMask = 0;
249 NewMask |= ITState.Mask & (0xC << TZ);
250 NewMask |= 0x2 << TZ;
251 ITState.Mask = NewMask;
256 void discardImplicitITBlock() {
257 assert(inImplicitITBlock());
258 assert(ITState.CurPosition == 1);
259 ITState.CurPosition = ~0U;
264 unsigned getITMaskEncoding() {
266 unsigned Mask = ITState.Mask;
268 if ((ITState.Cond & 1) == 0) {
269 assert(Mask && TZ <= 3 &&
"illegal IT mask value!");
270 Mask ^= (0xE << TZ) & 0xF;
278 if (ITState.CurPosition == 1)
281 MaskBit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
288 void invertCurrentITCondition() {
289 if (ITState.CurPosition == 1) {
292 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
297 bool isITBlockFull() {
298 return inITBlock() && (ITState.Mask & 1);
304 assert(inImplicitITBlock());
306 assert(Cond == ITState.Cond ||
309 unsigned NewMask = 0;
311 NewMask |= ITState.Mask & (0xE << TZ);
313 NewMask |= (Cond == ITState.Cond) << TZ;
315 NewMask |= 1 << (TZ - 1);
316 ITState.Mask = NewMask;
320 void startImplicitITBlock() {
324 ITState.CurPosition = 1;
325 ITState.IsExplicit =
false;
336 ITState.CurPosition = 0;
337 ITState.IsExplicit =
true;
342 return getParser().Note(L, Msg, Range);
345 return getParser().Warning(L, Msg, Range);
348 return getParser().Error(L, Msg, Range);
352 unsigned ListNo,
bool IsARPop =
false);
356 int tryParseRegister();
364 unsigned &ShiftAmount);
365 bool parseLiteralValues(
unsigned Size,
SMLoc L);
366 bool parseDirectiveThumb(
SMLoc L);
367 bool parseDirectiveARM(
SMLoc L);
368 bool parseDirectiveThumbFunc(
SMLoc L);
369 bool parseDirectiveCode(
SMLoc L);
370 bool parseDirectiveSyntax(
SMLoc L);
372 bool parseDirectiveUnreq(
SMLoc L);
373 bool parseDirectiveArch(
SMLoc L);
374 bool parseDirectiveEabiAttr(
SMLoc L);
375 bool parseDirectiveCPU(
SMLoc L);
376 bool parseDirectiveFPU(
SMLoc L);
377 bool parseDirectiveFnStart(
SMLoc L);
378 bool parseDirectiveFnEnd(
SMLoc L);
379 bool parseDirectiveCantUnwind(
SMLoc L);
380 bool parseDirectivePersonality(
SMLoc L);
381 bool parseDirectiveHandlerData(
SMLoc L);
382 bool parseDirectiveSetFP(
SMLoc L);
383 bool parseDirectivePad(
SMLoc L);
384 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
385 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
386 bool parseDirectiveLtorg(
SMLoc L);
387 bool parseDirectiveEven(
SMLoc L);
388 bool parseDirectivePersonalityIndex(
SMLoc L);
389 bool parseDirectiveUnwindRaw(
SMLoc L);
390 bool parseDirectiveTLSDescSeq(
SMLoc L);
391 bool parseDirectiveMovSP(
SMLoc L);
392 bool parseDirectiveObjectArch(
SMLoc L);
393 bool parseDirectiveArchExtension(
SMLoc L);
394 bool parseDirectiveAlign(
SMLoc L);
395 bool parseDirectiveThumbSet(
SMLoc L);
398 bool &CarrySetting,
unsigned &ProcessorIMod,
401 bool &CanAcceptCarrySet,
402 bool &CanAcceptPredicationCode);
404 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
bool CarrySetting,
408 return getSTI().getFeatureBits()[ARM::ModeThumb];
410 bool isThumbOne()
const {
411 return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2];
413 bool isThumbTwo()
const {
414 return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2];
416 bool hasThumb()
const {
417 return getSTI().getFeatureBits()[ARM::HasV4TOps];
419 bool hasThumb2()
const {
420 return getSTI().getFeatureBits()[ARM::FeatureThumb2];
422 bool hasV6Ops()
const {
423 return getSTI().getFeatureBits()[ARM::HasV6Ops];
425 bool hasV6T2Ops()
const {
426 return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
428 bool hasV6MOps()
const {
429 return getSTI().getFeatureBits()[ARM::HasV6MOps];
431 bool hasV7Ops()
const {
432 return getSTI().getFeatureBits()[ARM::HasV7Ops];
434 bool hasV8Ops()
const {
435 return getSTI().getFeatureBits()[ARM::HasV8Ops];
437 bool hasV8MBaseline()
const {
438 return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
440 bool hasV8MMainline()
const {
441 return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps];
443 bool has8MSecExt()
const {
444 return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
446 bool hasARM()
const {
447 return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
449 bool hasDSP()
const {
450 return getSTI().getFeatureBits()[ARM::FeatureDSP];
452 bool hasD16()
const {
453 return getSTI().getFeatureBits()[ARM::FeatureD16];
455 bool hasV8_1aOps()
const {
456 return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
458 bool hasRAS()
const {
459 return getSTI().getFeatureBits()[ARM::FeatureRAS];
464 uint64_t FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
465 setAvailableFeatures(FB);
467 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
468 bool isMClass()
const {
469 return getSTI().getFeatureBits()[ARM::FeatureMClass];
475 #define GET_ASSEMBLER_HEADER
476 #include "ARMGenAsmMatcher.inc"
492 return parsePKHImm(O,
"lsl", 0, 31);
495 return parsePKHImm(O,
"asr", 1, 32);
517 bool isITBlockTerminator(
MCInst &Inst)
const;
520 enum ARMMatchResultTy {
521 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
522 Match_RequiresNotITBlock,
524 Match_RequiresThumb2,
526 Match_RequiresFlagSetting,
527 #define GET_OPERAND_DIAGNOSTIC_TYPES
528 #include "ARMGenAsmMatcher.inc"
538 MRI = getContext().getRegisterInfo();
541 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
544 ITState.CurPosition = ~0U;
546 NextSymbolIsThumb =
false;
550 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
553 bool ParseDirective(
AsmToken DirectiveID)
override;
556 unsigned Kind)
override;
557 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
559 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
562 bool MatchingInlineAsm)
override;
564 uint64_t &
ErrorInfo,
bool MatchingInlineAsm,
584 k_InstSyncBarrierOpt,
596 k_VectorListAllLanes,
603 k_ConstantPoolImmediate,
604 k_BitfieldDescriptor,
608 SMLoc StartLoc, EndLoc, AlignmentLoc;
619 struct CoprocOptionOp {
657 struct VectorListOp {
664 struct VectorIndexOp {
678 unsigned OffsetRegNum;
683 unsigned isNegative : 1;
686 struct PostIdxRegOp {
693 struct ShifterImmOp {
698 struct RegShiftedRegOp {
705 struct RegShiftedImmOp {
728 struct CoprocOptionOp CoprocOption;
729 struct MBOptOp MBOpt;
730 struct ISBOptOp ISBOpt;
731 struct ITMaskOp ITMask;
733 struct MMaskOp MMask;
734 struct BankedRegOp BankedReg;
737 struct VectorListOp VectorList;
738 struct VectorIndexOp VectorIndex;
741 struct PostIdxRegOp PostIdxReg;
742 struct ShifterImmOp ShifterImm;
743 struct RegShiftedRegOp RegShiftedReg;
744 struct RegShiftedImmOp RegShiftedImm;
745 struct RotImmOp RotImm;
746 struct ModImmOp ModImm;
754 SMLoc getStartLoc()
const override {
return StartLoc; }
756 SMLoc getEndLoc()
const override {
return EndLoc; }
762 SMLoc getAlignmentLoc()
const {
763 assert(
Kind == k_Memory &&
"Invalid access!");
768 assert(
Kind == k_CondCode &&
"Invalid access!");
772 unsigned getCoproc()
const {
773 assert((
Kind == k_CoprocNum ||
Kind == k_CoprocReg) &&
"Invalid access!");
782 unsigned getReg()
const override {
783 assert((
Kind == k_Register ||
Kind == k_CCOut) &&
"Invalid access!");
789 Kind == k_SPRRegisterList) &&
"Invalid access!");
793 const MCExpr *getImm()
const {
794 assert(isImm() &&
"Invalid access!");
798 const MCExpr *getConstantPoolImm()
const {
799 assert(isConstantPoolImm() &&
"Invalid access!");
803 unsigned getVectorIndex()
const {
804 assert(
Kind == k_VectorIndex &&
"Invalid access!");
805 return VectorIndex.Val;
809 assert(
Kind == k_MemBarrierOpt &&
"Invalid access!");
814 assert(
Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
819 assert(
Kind == k_ProcIFlags &&
"Invalid access!");
823 unsigned getMSRMask()
const {
824 assert(
Kind == k_MSRMask &&
"Invalid access!");
828 unsigned getBankedReg()
const {
829 assert(
Kind == k_BankedReg &&
"Invalid access!");
830 return BankedReg.Val;
833 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
834 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
835 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
836 bool isCondCode()
const {
return Kind == k_CondCode; }
837 bool isCCOut()
const {
return Kind == k_CCOut; }
838 bool isITMask()
const {
return Kind == k_ITCondMask; }
839 bool isITCondCode()
const {
return Kind == k_CondCode; }
840 bool isImm()
const override {
841 return Kind == k_Immediate;
844 bool isARMBranchTarget()
const {
845 if (!isImm())
return false;
847 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
848 return CE->getValue() % 4 == 0;
853 bool isThumbBranchTarget()
const {
854 if (!isImm())
return false;
856 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
857 return CE->getValue() % 2 == 0;
863 template<
unsigned w
idth,
unsigned scale>
864 bool isUnsignedOffset()
const {
865 if (!isImm())
return false;
866 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
867 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
868 int64_t Val =
CE->getValue();
869 int64_t Align = 1LL <<
scale;
870 int64_t
Max = Align * ((1LL << width) - 1);
871 return ((Val % Align) == 0) && (Val >= 0) && (Val <=
Max);
877 template<
unsigned w
idth,
unsigned scale>
878 bool isSignedOffset()
const {
879 if (!isImm())
return false;
880 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
881 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
882 int64_t Val =
CE->getValue();
883 int64_t Align = 1LL <<
scale;
884 int64_t
Max = Align * ((1LL << (width-1)) - 1);
885 int64_t
Min = -Align * (1LL << (width-1));
886 return ((Val % Align) == 0) && (Val >=
Min) && (Val <=
Max);
895 bool isThumbMemPC()
const {
898 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
900 if (!CE)
return false;
904 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
906 Val =
Memory.OffsetImm->getValue();
909 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
911 bool isFPImm()
const {
912 if (!isImm())
return false;
914 if (!CE)
return false;
918 bool isFBits16()
const {
919 if (!isImm())
return false;
921 if (!CE)
return false;
923 return Value >= 0 && Value <= 16;
925 bool isFBits32()
const {
926 if (!isImm())
return false;
928 if (!CE)
return false;
930 return Value >= 1 && Value <= 32;
932 bool isImm8s4()
const {
933 if (!isImm())
return false;
935 if (!CE)
return false;
937 return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
939 bool isImm0_1020s4()
const {
940 if (!isImm())
return false;
942 if (!CE)
return false;
944 return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
946 bool isImm0_508s4()
const {
947 if (!isImm())
return false;
949 if (!CE)
return false;
951 return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
953 bool isImm0_508s4Neg()
const {
954 if (!isImm())
return false;
956 if (!CE)
return false;
959 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
961 bool isImm0_239()
const {
962 if (!isImm())
return false;
964 if (!CE)
return false;
966 return Value >= 0 && Value < 240;
968 bool isImm0_255()
const {
969 if (!isImm())
return false;
971 if (!CE)
return false;
973 return Value >= 0 && Value < 256;
975 bool isImm0_4095()
const {
976 if (!isImm())
return false;
978 if (!CE)
return false;
980 return Value >= 0 && Value < 4096;
982 bool isImm0_4095Neg()
const {
983 if (!isImm())
return false;
985 if (!CE)
return false;
987 return Value > 0 && Value < 4096;
989 bool isImm0_1()
const {
990 if (!isImm())
return false;
992 if (!CE)
return false;
994 return Value >= 0 && Value < 2;
996 bool isImm0_3()
const {
997 if (!isImm())
return false;
999 if (!CE)
return false;
1001 return Value >= 0 && Value < 4;
1003 bool isImm0_7()
const {
1004 if (!isImm())
return false;
1006 if (!CE)
return false;
1008 return Value >= 0 && Value < 8;
1010 bool isImm0_15()
const {
1011 if (!isImm())
return false;
1013 if (!CE)
return false;
1015 return Value >= 0 && Value < 16;
1017 bool isImm0_31()
const {
1018 if (!isImm())
return false;
1020 if (!CE)
return false;
1022 return Value >= 0 && Value < 32;
1024 bool isImm0_63()
const {
1025 if (!isImm())
return false;
1027 if (!CE)
return false;
1029 return Value >= 0 && Value < 64;
1031 bool isImm8()
const {
1032 if (!isImm())
return false;
1034 if (!CE)
return false;
1038 bool isImm16()
const {
1039 if (!isImm())
return false;
1041 if (!CE)
return false;
1045 bool isImm32()
const {
1046 if (!isImm())
return false;
1048 if (!CE)
return false;
1052 bool isShrImm8()
const {
1053 if (!isImm())
return false;
1055 if (!CE)
return false;
1057 return Value > 0 && Value <= 8;
1059 bool isShrImm16()
const {
1060 if (!isImm())
return false;
1062 if (!CE)
return false;
1064 return Value > 0 && Value <= 16;
1066 bool isShrImm32()
const {
1067 if (!isImm())
return false;
1069 if (!CE)
return false;
1071 return Value > 0 && Value <= 32;
1073 bool isShrImm64()
const {
1074 if (!isImm())
return false;
1076 if (!CE)
return false;
1078 return Value > 0 && Value <= 64;
1080 bool isImm1_7()
const {
1081 if (!isImm())
return false;
1083 if (!CE)
return false;
1085 return Value > 0 && Value < 8;
1087 bool isImm1_15()
const {
1088 if (!isImm())
return false;
1090 if (!CE)
return false;
1092 return Value > 0 && Value < 16;
1094 bool isImm1_31()
const {
1095 if (!isImm())
return false;
1097 if (!CE)
return false;
1099 return Value > 0 && Value < 32;
1101 bool isImm1_16()
const {
1102 if (!isImm())
return false;
1104 if (!CE)
return false;
1106 return Value > 0 && Value < 17;
1108 bool isImm1_32()
const {
1109 if (!isImm())
return false;
1111 if (!CE)
return false;
1113 return Value > 0 && Value < 33;
1115 bool isImm0_32()
const {
1116 if (!isImm())
return false;
1118 if (!CE)
return false;
1120 return Value >= 0 && Value < 33;
1122 bool isImm0_65535()
const {
1123 if (!isImm())
return false;
1125 if (!CE)
return false;
1127 return Value >= 0 && Value < 65536;
1129 bool isImm256_65535Expr()
const {
1130 if (!isImm())
return false;
1134 if (!CE)
return true;
1136 return Value >= 256 && Value < 65536;
1138 bool isImm0_65535Expr()
const {
1139 if (!isImm())
return false;
1143 if (!CE)
return true;
1145 return Value >= 0 && Value < 65536;
1147 bool isImm24bit()
const {
1148 if (!isImm())
return false;
1150 if (!CE)
return false;
1152 return Value >= 0 && Value <= 0xffffff;
1154 bool isImmThumbSR()
const {
1155 if (!isImm())
return false;
1157 if (!CE)
return false;
1159 return Value > 0 && Value < 33;
1161 bool isPKHLSLImm()
const {
1162 if (!isImm())
return false;
1164 if (!CE)
return false;
1166 return Value >= 0 && Value < 32;
1168 bool isPKHASRImm()
const {
1169 if (!isImm())
return false;
1171 if (!CE)
return false;
1173 return Value > 0 && Value <= 32;
1175 bool isAdrLabel()
const {
1178 if (isImm() && !isa<MCConstantExpr>(getImm()))
1182 if (!isImm())
return false;
1184 if (!CE)
return false;
1189 bool isT2SOImm()
const {
1190 if (!isImm())
return false;
1192 if (!CE)
return false;
1196 bool isT2SOImmNot()
const {
1197 if (!isImm())
return false;
1199 if (!CE)
return false;
1204 bool isT2SOImmNeg()
const {
1205 if (!isImm())
return false;
1207 if (!CE)
return false;
1213 bool isSetEndImm()
const {
1214 if (!isImm())
return false;
1216 if (!CE)
return false;
1218 return Value == 1 || Value == 0;
1220 bool isReg()
const override {
return Kind == k_Register; }
1221 bool isRegList()
const {
return Kind == k_RegisterList; }
1222 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1223 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1224 bool isToken()
const override {
return Kind == k_Token; }
1225 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1226 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1227 bool isMem()
const override {
return Kind == k_Memory; }
1228 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1229 bool isRegShiftedReg()
const {
return Kind == k_ShiftedRegister; }
1230 bool isRegShiftedImm()
const {
return Kind == k_ShiftedImmediate; }
1231 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1232 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1233 bool isModImmNot()
const {
1234 if (!isImm())
return false;
1236 if (!CE)
return false;
1240 bool isModImmNeg()
const {
1241 if (!isImm())
return false;
1243 if (!CE)
return false;
1248 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1249 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1250 bool isPostIdxRegShifted()
const {
return Kind == k_PostIndexRegister; }
1251 bool isPostIdxReg()
const {
1254 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1258 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1259 (alignOK ||
Memory.Alignment == Alignment);
1261 bool isMemPCRelImm12()
const {
1268 if (!
Memory.OffsetImm)
return true;
1269 int64_t Val =
Memory.OffsetImm->getValue();
1270 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
1272 bool isAlignedMemory()
const {
1273 return isMemNoOffset(
true);
1275 bool isAlignedMemoryNone()
const {
1276 return isMemNoOffset(
false, 0);
1278 bool isDupAlignedMemoryNone()
const {
1279 return isMemNoOffset(
false, 0);
1281 bool isAlignedMemory16()
const {
1282 if (isMemNoOffset(
false, 2))
1284 return isMemNoOffset(
false, 0);
1286 bool isDupAlignedMemory16()
const {
1287 if (isMemNoOffset(
false, 2))
1289 return isMemNoOffset(
false, 0);
1291 bool isAlignedMemory32()
const {
1292 if (isMemNoOffset(
false, 4))
1294 return isMemNoOffset(
false, 0);
1296 bool isDupAlignedMemory32()
const {
1297 if (isMemNoOffset(
false, 4))
1299 return isMemNoOffset(
false, 0);
1301 bool isAlignedMemory64()
const {
1302 if (isMemNoOffset(
false, 8))
1304 return isMemNoOffset(
false, 0);
1306 bool isDupAlignedMemory64()
const {
1307 if (isMemNoOffset(
false, 8))
1309 return isMemNoOffset(
false, 0);
1311 bool isAlignedMemory64or128()
const {
1312 if (isMemNoOffset(
false, 8))
1314 if (isMemNoOffset(
false, 16))
1316 return isMemNoOffset(
false, 0);
1318 bool isDupAlignedMemory64or128()
const {
1319 if (isMemNoOffset(
false, 8))
1321 if (isMemNoOffset(
false, 16))
1323 return isMemNoOffset(
false, 0);
1325 bool isAlignedMemory64or128or256()
const {
1326 if (isMemNoOffset(
false, 8))
1328 if (isMemNoOffset(
false, 16))
1330 if (isMemNoOffset(
false, 32))
1332 return isMemNoOffset(
false, 0);
1334 bool isAddrMode2()
const {
1335 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1337 if (
Memory.OffsetRegNum)
return true;
1339 if (!
Memory.OffsetImm)
return true;
1340 int64_t Val =
Memory.OffsetImm->getValue();
1341 return Val > -4096 && Val < 4096;
1343 bool isAM2OffsetImm()
const {
1344 if (!isImm())
return false;
1347 if (!CE)
return false;
1349 return (Val == INT32_MIN) || (Val > -4096 && Val < 4096);
1351 bool isAddrMode3()
const {
1355 if (isImm() && !isa<MCConstantExpr>(getImm()))
1357 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1361 if (
Memory.OffsetRegNum)
return true;
1363 if (!
Memory.OffsetImm)
return true;
1364 int64_t Val =
Memory.OffsetImm->getValue();
1367 return (Val > -256 && Val < 256) || Val == INT32_MIN;
1369 bool isAM3Offset()
const {
1370 if (
Kind != k_Immediate &&
Kind != k_PostIndexRegister)
1372 if (
Kind == k_PostIndexRegister)
1376 if (!CE)
return false;
1379 return (Val > -256 && Val < 256) || Val == INT32_MIN;
1381 bool isAddrMode5()
const {
1385 if (isImm() && !isa<MCConstantExpr>(getImm()))
1387 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1389 if (
Memory.OffsetRegNum)
return false;
1391 if (!
Memory.OffsetImm)
return true;
1392 int64_t Val =
Memory.OffsetImm->getValue();
1393 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1396 bool isAddrMode5FP16()
const {
1400 if (isImm() && !isa<MCConstantExpr>(getImm()))
1402 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1404 if (
Memory.OffsetRegNum)
return false;
1406 if (!
Memory.OffsetImm)
return true;
1407 int64_t Val =
Memory.OffsetImm->getValue();
1408 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) || Val == INT32_MIN;
1410 bool isMemTBB()
const {
1416 bool isMemTBH()
const {
1423 bool isMemRegOffset()
const {
1428 bool isT2MemRegOffset()
const {
1439 bool isMemThumbRR()
const {
1448 bool isMemThumbRIs4()
const {
1453 if (!
Memory.OffsetImm)
return true;
1454 int64_t Val =
Memory.OffsetImm->getValue();
1455 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1457 bool isMemThumbRIs2()
const {
1462 if (!
Memory.OffsetImm)
return true;
1463 int64_t Val =
Memory.OffsetImm->getValue();
1464 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1466 bool isMemThumbRIs1()
const {
1471 if (!
Memory.OffsetImm)
return true;
1472 int64_t Val =
Memory.OffsetImm->getValue();
1473 return Val >= 0 && Val <= 31;
1475 bool isMemThumbSPI()
const {
1480 if (!
Memory.OffsetImm)
return true;
1481 int64_t Val =
Memory.OffsetImm->getValue();
1482 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1484 bool isMemImm8s4Offset()
const {
1488 if (isImm() && !isa<MCConstantExpr>(getImm()))
1493 if (!
Memory.OffsetImm)
return true;
1494 int64_t Val =
Memory.OffsetImm->getValue();
1496 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN;
1498 bool isMemImm0_1020s4Offset()
const {
1502 if (!
Memory.OffsetImm)
return true;
1503 int64_t Val =
Memory.OffsetImm->getValue();
1504 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1506 bool isMemImm8Offset()
const {
1512 if (!
Memory.OffsetImm)
return true;
1513 int64_t Val =
Memory.OffsetImm->getValue();
1514 return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1516 bool isMemPosImm8Offset()
const {
1520 if (!
Memory.OffsetImm)
return true;
1521 int64_t Val =
Memory.OffsetImm->getValue();
1522 return Val >= 0 && Val < 256;
1524 bool isMemNegImm8Offset()
const {
1530 if (!
Memory.OffsetImm)
return false;
1531 int64_t Val =
Memory.OffsetImm->getValue();
1532 return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1534 bool isMemUImm12Offset()
const {
1538 if (!
Memory.OffsetImm)
return true;
1539 int64_t Val =
Memory.OffsetImm->getValue();
1540 return (Val >= 0 && Val < 4096);
1542 bool isMemImm12Offset()
const {
1547 if (isImm() && !isa<MCConstantExpr>(getImm()))
1553 if (!
Memory.OffsetImm)
return true;
1554 int64_t Val =
Memory.OffsetImm->getValue();
1555 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
1557 bool isConstPoolAsmImm()
const {
1560 return (isConstantPoolImm());
1562 bool isPostIdxImm8()
const {
1563 if (!isImm())
return false;
1565 if (!CE)
return false;
1567 return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1569 bool isPostIdxImm8s4()
const {
1570 if (!isImm())
return false;
1572 if (!CE)
return false;
1574 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
1578 bool isMSRMask()
const {
return Kind == k_MSRMask; }
1579 bool isBankedReg()
const {
return Kind == k_BankedReg; }
1580 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
1583 bool isSingleSpacedVectorList()
const {
1584 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
1586 bool isDoubleSpacedVectorList()
const {
1587 return Kind == k_VectorList && VectorList.isDoubleSpaced;
1589 bool isVecListOneD()
const {
1590 if (!isSingleSpacedVectorList())
return false;
1591 return VectorList.Count == 1;
1594 bool isVecListDPair()
const {
1595 if (!isSingleSpacedVectorList())
return false;
1596 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1600 bool isVecListThreeD()
const {
1601 if (!isSingleSpacedVectorList())
return false;
1602 return VectorList.Count == 3;
1605 bool isVecListFourD()
const {
1606 if (!isSingleSpacedVectorList())
return false;
1607 return VectorList.Count == 4;
1610 bool isVecListDPairSpaced()
const {
1611 if (
Kind != k_VectorList)
return false;
1612 if (isSingleSpacedVectorList())
return false;
1613 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1617 bool isVecListThreeQ()
const {
1618 if (!isDoubleSpacedVectorList())
return false;
1619 return VectorList.Count == 3;
1622 bool isVecListFourQ()
const {
1623 if (!isDoubleSpacedVectorList())
return false;
1624 return VectorList.Count == 4;
1627 bool isSingleSpacedVectorAllLanes()
const {
1628 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
1630 bool isDoubleSpacedVectorAllLanes()
const {
1631 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
1633 bool isVecListOneDAllLanes()
const {
1634 if (!isSingleSpacedVectorAllLanes())
return false;
1635 return VectorList.Count == 1;
1638 bool isVecListDPairAllLanes()
const {
1639 if (!isSingleSpacedVectorAllLanes())
return false;
1640 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1644 bool isVecListDPairSpacedAllLanes()
const {
1645 if (!isDoubleSpacedVectorAllLanes())
return false;
1646 return VectorList.Count == 2;
1649 bool isVecListThreeDAllLanes()
const {
1650 if (!isSingleSpacedVectorAllLanes())
return false;
1651 return VectorList.Count == 3;
1654 bool isVecListThreeQAllLanes()
const {
1655 if (!isDoubleSpacedVectorAllLanes())
return false;
1656 return VectorList.Count == 3;
1659 bool isVecListFourDAllLanes()
const {
1660 if (!isSingleSpacedVectorAllLanes())
return false;
1661 return VectorList.Count == 4;
1664 bool isVecListFourQAllLanes()
const {
1665 if (!isDoubleSpacedVectorAllLanes())
return false;
1666 return VectorList.Count == 4;
1669 bool isSingleSpacedVectorIndexed()
const {
1670 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
1672 bool isDoubleSpacedVectorIndexed()
const {
1673 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
1675 bool isVecListOneDByteIndexed()
const {
1676 if (!isSingleSpacedVectorIndexed())
return false;
1677 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
1680 bool isVecListOneDHWordIndexed()
const {
1681 if (!isSingleSpacedVectorIndexed())
return false;
1682 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1685 bool isVecListOneDWordIndexed()
const {
1686 if (!isSingleSpacedVectorIndexed())
return false;
1687 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1690 bool isVecListTwoDByteIndexed()
const {
1691 if (!isSingleSpacedVectorIndexed())
return false;
1692 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
1695 bool isVecListTwoDHWordIndexed()
const {
1696 if (!isSingleSpacedVectorIndexed())
return false;
1697 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1700 bool isVecListTwoQWordIndexed()
const {
1701 if (!isDoubleSpacedVectorIndexed())
return false;
1702 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1705 bool isVecListTwoQHWordIndexed()
const {
1706 if (!isDoubleSpacedVectorIndexed())
return false;
1707 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1710 bool isVecListTwoDWordIndexed()
const {
1711 if (!isSingleSpacedVectorIndexed())
return false;
1712 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1715 bool isVecListThreeDByteIndexed()
const {
1716 if (!isSingleSpacedVectorIndexed())
return false;
1717 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
1720 bool isVecListThreeDHWordIndexed()
const {
1721 if (!isSingleSpacedVectorIndexed())
return false;
1722 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1725 bool isVecListThreeQWordIndexed()
const {
1726 if (!isDoubleSpacedVectorIndexed())
return false;
1727 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1730 bool isVecListThreeQHWordIndexed()
const {
1731 if (!isDoubleSpacedVectorIndexed())
return false;
1732 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1735 bool isVecListThreeDWordIndexed()
const {
1736 if (!isSingleSpacedVectorIndexed())
return false;
1737 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1740 bool isVecListFourDByteIndexed()
const {
1741 if (!isSingleSpacedVectorIndexed())
return false;
1742 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1745 bool isVecListFourDHWordIndexed()
const {
1746 if (!isSingleSpacedVectorIndexed())
return false;
1747 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1750 bool isVecListFourQWordIndexed()
const {
1751 if (!isDoubleSpacedVectorIndexed())
return false;
1752 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1755 bool isVecListFourQHWordIndexed()
const {
1756 if (!isDoubleSpacedVectorIndexed())
return false;
1757 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1760 bool isVecListFourDWordIndexed()
const {
1761 if (!isSingleSpacedVectorIndexed())
return false;
1762 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1765 bool isVectorIndex8()
const {
1766 if (
Kind != k_VectorIndex)
return false;
1767 return VectorIndex.Val < 8;
1769 bool isVectorIndex16()
const {
1770 if (
Kind != k_VectorIndex)
return false;
1771 return VectorIndex.Val < 4;
1773 bool isVectorIndex32()
const {
1774 if (
Kind != k_VectorIndex)
return false;
1775 return VectorIndex.Val < 2;
1778 bool isNEONi8splat()
const {
1779 if (!isImm())
return false;
1782 if (!CE)
return false;
1786 return Value >= 0 && Value < 256;
1790 if (isNEONByteReplicate(2))
1796 if (!CE)
return false;
1801 bool isNEONi16splatNot()
const {
1806 if (!CE)
return false;
1812 if (isNEONByteReplicate(4))
1818 if (!CE)
return false;
1823 bool isNEONi32splatNot()
const {
1828 if (!CE)
return false;
1833 bool isNEONByteReplicate(
unsigned NumBytes)
const {
1844 unsigned char B = Value & 0xff;
1845 for (
unsigned i = 1;
i < NumBytes; ++
i) {
1847 if ((Value & 0xff) != B)
1852 bool isNEONi16ByteReplicate()
const {
return isNEONByteReplicate(2); }
1853 bool isNEONi32ByteReplicate()
const {
return isNEONByteReplicate(4); }
1854 bool isNEONi32vmov()
const {
1855 if (isNEONByteReplicate(4))
1867 return (Value >= 0 && Value < 256) ||
1868 (Value >= 0x0100 && Value <= 0xff00) ||
1869 (Value >= 0x010000 && Value <= 0xff0000) ||
1870 (Value >= 0x01000000 && Value <= 0xff000000) ||
1871 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1872 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1874 bool isNEONi32vmovNeg()
const {
1875 if (!isImm())
return false;
1878 if (!CE)
return false;
1883 return (Value >= 0 && Value < 256) ||
1884 (Value >= 0x0100 && Value <= 0xff00) ||
1885 (Value >= 0x010000 && Value <= 0xff0000) ||
1886 (Value >= 0x01000000 && Value <= 0xff000000) ||
1887 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1888 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1891 bool isNEONi64splat()
const {
1892 if (!isImm())
return false;
1895 if (!CE)
return false;
1898 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
1899 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff)
return false;
1907 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1913 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
1914 assert(N == 1 &&
"Invalid number of operands!");
1915 addExpr(Inst, getImm());
1918 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
1919 assert(N == 1 &&
"Invalid number of operands!");
1920 addExpr(Inst, getImm());
1923 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1924 assert(N == 2 &&
"Invalid number of operands!");
1926 unsigned RegNum = getCondCode() ==
ARMCC::AL ? 0: ARM::CPSR;
1930 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
1931 assert(N == 1 &&
"Invalid number of operands!");
1935 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
1936 assert(N == 1 &&
"Invalid number of operands!");
1940 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
1941 assert(N == 1 &&
"Invalid number of operands!");
1945 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
1946 assert(N == 1 &&
"Invalid number of operands!");
1950 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1951 assert(N == 1 &&
"Invalid number of operands!");
1955 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
1956 assert(N == 1 &&
"Invalid number of operands!");
1960 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1961 assert(N == 1 &&
"Invalid number of operands!");
1965 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
1966 assert(N == 3 &&
"Invalid number of operands!");
1967 assert(isRegShiftedReg() &&
1968 "addRegShiftedRegOperands() on non-RegShiftedReg!");
1975 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
1976 assert(N == 2 &&
"Invalid number of operands!");
1977 assert(isRegShiftedImm() &&
1978 "addRegShiftedImmOperands() on non-RegShiftedImm!");
1981 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
1986 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
1987 assert(N == 1 &&
"Invalid number of operands!");
1992 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1993 assert(N == 1 &&
"Invalid number of operands!");
2000 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2001 addRegListOperands(Inst, N);
2004 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2005 addRegListOperands(Inst, N);
2008 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2009 assert(N == 1 &&
"Invalid number of operands!");
2014 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2015 assert(N == 1 &&
"Invalid number of operands!");
2019 return addImmOperands(Inst, N);
2024 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2025 assert(N == 1 &&
"Invalid number of operands!");
2031 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2032 assert(N == 1 &&
"Invalid number of operands!");
2038 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2039 assert(N == 1 &&
"Invalid number of operands!");
2045 (32 - (lsb + width)));
2049 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2050 assert(N == 1 &&
"Invalid number of operands!");
2051 addExpr(Inst, getImm());
2054 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2055 assert(N == 1 &&
"Invalid number of operands!");
2060 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2061 assert(N == 1 &&
"Invalid number of operands!");
2066 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2067 assert(N == 1 &&
"Invalid number of operands!");
2073 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2074 assert(N == 1 &&
"Invalid number of operands!");
2081 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2082 assert(N == 1 &&
"Invalid number of operands!");
2089 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2090 assert(N == 1 &&
"Invalid number of operands!");
2097 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2098 assert(N == 1 &&
"Invalid number of operands!");
2105 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2106 assert(N == 1 &&
"Invalid number of operands!");
2113 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2114 assert(N == 1 &&
"Invalid number of operands!");
2121 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2122 assert(N == 1 &&
"Invalid number of operands!");
2130 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2131 assert(N == 1 &&
"Invalid number of operands!");
2139 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2140 assert(N == 1 &&
"Invalid number of operands!");
2147 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2148 assert(N == 1 &&
"Invalid number of operands!");
2155 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2156 assert(N == 1 &&
"Invalid number of operands!");
2163 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2164 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2170 assert(SR &&
"Unknown value type!");
2174 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2175 assert(N == 1 &&
"Invalid number of operands!");
2185 assert(SR &&
"Unknown value type!");
2191 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2195 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2196 assert(N == 1 &&
"Invalid number of operands!");
2200 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2201 assert(N == 1 &&
"Invalid number of operands!");
2205 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2206 assert(N == 1 &&
"Invalid number of operands!");
2210 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2211 assert(N == 1 &&
"Invalid number of operands!");
2212 int32_t Imm =
Memory.OffsetImm->getValue();
2216 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2217 assert(N == 1 &&
"Invalid number of operands!");
2218 assert(isImm() &&
"Not an immediate!");
2222 if (!isa<MCConstantExpr>(getImm())) {
2232 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2233 assert(N == 2 &&
"Invalid number of operands!");
2238 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2239 addAlignedMemoryOperands(Inst, N);
2242 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2243 addAlignedMemoryOperands(Inst, N);
2246 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2247 addAlignedMemoryOperands(Inst, N);
2250 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2251 addAlignedMemoryOperands(Inst, N);
2254 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2255 addAlignedMemoryOperands(Inst, N);
2258 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2259 addAlignedMemoryOperands(Inst, N);
2262 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2263 addAlignedMemoryOperands(Inst, N);
2266 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2267 addAlignedMemoryOperands(Inst, N);
2270 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2271 addAlignedMemoryOperands(Inst, N);
2274 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2275 addAlignedMemoryOperands(Inst, N);
2278 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2279 addAlignedMemoryOperands(Inst, N);
2282 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
2283 assert(N == 3 &&
"Invalid number of operands!");
2284 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2285 if (!
Memory.OffsetRegNum) {
2288 if (Val == INT32_MIN) Val = 0;
2289 if (Val < 0) Val = -Val;
2302 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
2303 assert(N == 2 &&
"Invalid number of operands!");
2305 assert(CE &&
"non-constant AM2OffsetImm operand!");
2309 if (Val == INT32_MIN) Val = 0;
2310 if (Val < 0) Val = -Val;
2316 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
2317 assert(N == 3 &&
"Invalid number of operands!");
2328 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2329 if (!
Memory.OffsetRegNum) {
2332 if (Val == INT32_MIN) Val = 0;
2333 if (Val < 0) Val = -Val;
2345 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2346 assert(N == 2 &&
"Invalid number of operands!");
2347 if (
Kind == k_PostIndexRegister) {
2360 if (Val == INT32_MIN) Val = 0;
2361 if (Val < 0) Val = -Val;
2367 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
2368 assert(N == 2 &&
"Invalid number of operands!");
2379 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2382 if (Val == INT32_MIN) Val = 0;
2383 if (Val < 0) Val = -Val;
2389 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
2390 assert(N == 2 &&
"Invalid number of operands!");
2401 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 2 : 0;
2404 if (Val == INT32_MIN) Val = 0;
2405 if (Val < 0) Val = -Val;
2411 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2412 assert(N == 2 &&
"Invalid number of operands!");
2422 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2427 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2428 assert(N == 2 &&
"Invalid number of operands!");
2430 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2435 void addMemImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2436 assert(N == 2 &&
"Invalid number of operands!");
2437 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2442 void addMemPosImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2443 addMemImm8OffsetOperands(Inst, N);
2446 void addMemNegImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2447 addMemImm8OffsetOperands(Inst, N);
2450 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2451 assert(N == 2 &&
"Invalid number of operands!");
2454 addExpr(Inst, getImm());
2460 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2465 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2466 assert(N == 2 &&
"Invalid number of operands!");
2469 addExpr(Inst, getImm());
2475 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2480 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
2481 assert(N == 1 &&
"Invalid number of operands!");
2484 addExpr(Inst, getConstantPoolImm());
2488 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
2489 assert(N == 2 &&
"Invalid number of operands!");
2494 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
2495 assert(N == 2 &&
"Invalid number of operands!");
2500 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2501 assert(N == 3 &&
"Invalid number of operands!");
2510 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2511 assert(N == 3 &&
"Invalid number of operands!");
2517 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
2518 assert(N == 2 &&
"Invalid number of operands!");
2523 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
2524 assert(N == 2 &&
"Invalid number of operands!");
2525 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2530 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
2531 assert(N == 2 &&
"Invalid number of operands!");
2532 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 2) : 0;
2537 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
2538 assert(N == 2 &&
"Invalid number of operands!");
2539 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue()) : 0;
2544 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
2545 assert(N == 2 &&
"Invalid number of operands!");
2546 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2551 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
2552 assert(N == 1 &&
"Invalid number of operands!");
2554 assert(CE &&
"non-constant post-idx-imm8 operand!");
2556 bool isAdd = Imm >= 0;
2557 if (Imm == INT32_MIN) Imm = 0;
2558 Imm = (Imm < 0 ? -Imm : Imm) | (
int)isAdd << 8;
2562 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2563 assert(N == 1 &&
"Invalid number of operands!");
2565 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
2567 bool isAdd = Imm >= 0;
2568 if (Imm == INT32_MIN) Imm = 0;
2570 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
2574 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
2575 assert(N == 2 &&
"Invalid number of operands!");
2580 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
2581 assert(N == 2 &&
"Invalid number of operands!");
2587 PostIdxReg.ShiftTy);
2591 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
2592 assert(N == 1 &&
"Invalid number of operands!");
2596 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
2597 assert(N == 1 &&
"Invalid number of operands!");
2601 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
2602 assert(N == 1 &&
"Invalid number of operands!");
2606 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
2607 assert(N == 1 &&
"Invalid number of operands!");
2611 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
2612 assert(N == 2 &&
"Invalid number of operands!");
2617 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
2618 assert(N == 1 &&
"Invalid number of operands!");
2622 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
2623 assert(N == 1 &&
"Invalid number of operands!");
2627 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
2628 assert(N == 1 &&
"Invalid number of operands!");
2632 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
2633 assert(N == 1 &&
"Invalid number of operands!");
2640 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
2641 assert(N == 1 &&
"Invalid number of operands!");
2649 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2650 assert(N == 1 &&
"Invalid number of operands!");
2658 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
2659 assert(N == 1 &&
"Invalid number of operands!");
2667 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2668 assert(N == 1 &&
"Invalid number of operands!");
2676 void addNEONinvByteReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2677 assert(N == 1 &&
"Invalid number of operands!");
2683 "All vmvn instructions that wants to replicate non-zero byte "
2684 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
2685 unsigned B = ((~Value) & 0xff);
2689 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
2690 assert(N == 1 &&
"Invalid number of operands!");
2694 if (Value >= 256 && Value <= 0xffff)
2695 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
2696 else if (Value > 0xffff && Value <= 0xffffff)
2697 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
2698 else if (Value > 0xffffff)
2699 Value = (Value >> 24) | 0x600;
2703 void addNEONvmovByteReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2704 assert(N == 1 &&
"Invalid number of operands!");
2710 "All instructions that wants to replicate non-zero byte "
2711 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
2712 unsigned B = Value & 0xff;
2716 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
2717 assert(N == 1 &&
"Invalid number of operands!");
2721 if (Value >= 256 && Value <= 0xffff)
2722 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
2723 else if (Value > 0xffff && Value <= 0xffffff)
2724 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
2725 else if (Value > 0xffffff)
2726 Value = (Value >> 24) | 0x600;
2730 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
2731 assert(N == 1 &&
"Invalid number of operands!");
2736 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
2737 Imm |= (Value & 1) <<
i;
2744 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S) {
2745 auto Op = make_unique<ARMOperand>(k_ITCondMask);
2754 auto Op = make_unique<ARMOperand>(k_CondCode);
2761 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S) {
2762 auto Op = make_unique<ARMOperand>(k_CoprocNum);
2763 Op->Cop.Val = CopVal;
2769 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S) {
2770 auto Op = make_unique<ARMOperand>(k_CoprocReg);
2771 Op->Cop.Val = CopVal;
2777 static std::unique_ptr<ARMOperand> CreateCoprocOption(
unsigned Val,
SMLoc S,
2779 auto Op = make_unique<ARMOperand>(k_CoprocOption);
2786 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S) {
2787 auto Op = make_unique<ARMOperand>(k_CCOut);
2788 Op->Reg.RegNum = RegNum;
2794 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S) {
2795 auto Op = make_unique<ARMOperand>(k_Token);
2796 Op->Tok.Data = Str.
data();
2797 Op->Tok.Length = Str.
size();
2803 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
2805 auto Op = make_unique<ARMOperand>(k_Register);
2806 Op->Reg.RegNum = RegNum;
2812 static std::unique_ptr<ARMOperand>
2814 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
2816 auto Op = make_unique<ARMOperand>(k_ShiftedRegister);
2817 Op->RegShiftedReg.ShiftTy = ShTy;
2818 Op->RegShiftedReg.SrcReg = SrcReg;
2819 Op->RegShiftedReg.ShiftReg = ShiftReg;
2820 Op->RegShiftedReg.ShiftImm = ShiftImm;
2826 static std::unique_ptr<ARMOperand>
2829 auto Op = make_unique<ARMOperand>(k_ShiftedImmediate);
2830 Op->RegShiftedImm.ShiftTy = ShTy;
2831 Op->RegShiftedImm.SrcReg = SrcReg;
2832 Op->RegShiftedImm.ShiftImm = ShiftImm;
2838 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
2840 auto Op = make_unique<ARMOperand>(k_ShifterImmediate);
2841 Op->ShifterImm.isASR = isASR;
2842 Op->ShifterImm.Imm = Imm;
2848 static std::unique_ptr<ARMOperand> CreateRotImm(
unsigned Imm,
SMLoc S,
2850 auto Op = make_unique<ARMOperand>(k_RotateImmediate);
2851 Op->RotImm.Imm = Imm;
2857 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
2859 auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
2861 Op->ModImm.Rot = Rot;
2867 static std::unique_ptr<ARMOperand>
2869 auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate);
2876 static std::unique_ptr<ARMOperand>
2877 CreateBitfield(
unsigned LSB,
unsigned Width,
SMLoc S,
SMLoc E) {
2878 auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
2879 Op->Bitfield.LSB = LSB;
2880 Op->Bitfield.Width = Width;
2886 static std::unique_ptr<ARMOperand>
2889 assert (
Regs.size() > 0 &&
"RegList contains no registers?");
2890 KindTy
Kind = k_RegisterList;
2892 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Regs.front().second))
2893 Kind = k_DPRRegisterList;
2894 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2896 Kind = k_SPRRegisterList;
2901 auto Op = make_unique<ARMOperand>(
Kind);
2904 Op->Registers.push_back(
I->second);
2905 Op->StartLoc = StartLoc;
2906 Op->EndLoc = EndLoc;
2910 static std::unique_ptr<ARMOperand> CreateVectorList(
unsigned RegNum,
2912 bool isDoubleSpaced,
2914 auto Op = make_unique<ARMOperand>(k_VectorList);
2915 Op->VectorList.RegNum = RegNum;
2916 Op->VectorList.Count = Count;
2917 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2923 static std::unique_ptr<ARMOperand>
2924 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
2926 auto Op = make_unique<ARMOperand>(k_VectorListAllLanes);
2927 Op->VectorList.RegNum = RegNum;
2928 Op->VectorList.Count = Count;
2929 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2935 static std::unique_ptr<ARMOperand>
2936 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
2938 auto Op = make_unique<ARMOperand>(k_VectorListIndexed);
2939 Op->VectorList.RegNum = RegNum;
2940 Op->VectorList.Count = Count;
2941 Op->VectorList.LaneIndex = Index;
2942 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2948 static std::unique_ptr<ARMOperand>
2950 auto Op = make_unique<ARMOperand>(k_VectorIndex);
2951 Op->VectorIndex.Val = Idx;
2957 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
2959 auto Op = make_unique<ARMOperand>(k_Immediate);
2966 static std::unique_ptr<ARMOperand>
2969 unsigned ShiftImm,
unsigned Alignment,
bool isNegative,
SMLoc S,
2971 auto Op = make_unique<ARMOperand>(k_Memory);
2972 Op->Memory.BaseRegNum = BaseRegNum;
2973 Op->Memory.OffsetImm = OffsetImm;
2974 Op->Memory.OffsetRegNum = OffsetRegNum;
2975 Op->Memory.ShiftType = ShiftType;
2976 Op->Memory.ShiftImm = ShiftImm;
2977 Op->Memory.Alignment = Alignment;
2978 Op->Memory.isNegative = isNegative;
2981 Op->AlignmentLoc = AlignmentLoc;
2985 static std::unique_ptr<ARMOperand>
2988 auto Op = make_unique<ARMOperand>(k_PostIndexRegister);
2989 Op->PostIdxReg.RegNum = RegNum;
2990 Op->PostIdxReg.isAdd = isAdd;
2991 Op->PostIdxReg.ShiftTy = ShiftTy;
2992 Op->PostIdxReg.ShiftImm = ShiftImm;
2998 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt,
3000 auto Op = make_unique<ARMOperand>(k_MemBarrierOpt);
3001 Op->MBOpt.Val = Opt;
3007 static std::unique_ptr<ARMOperand>
3009 auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3010 Op->ISBOpt.Val = Opt;
3018 auto Op = make_unique<ARMOperand>(k_ProcIFlags);
3025 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S) {
3026 auto Op = make_unique<ARMOperand>(k_MSRMask);
3027 Op->MMask.Val = MMask;
3033 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S) {
3034 auto Op = make_unique<ARMOperand>(k_BankedReg);
3035 Op->BankedReg.Val =
Reg;
3050 OS <<
"<ccout " <<
getReg() <<
">";
3052 case k_ITCondMask: {
3053 static const char *
const MaskStr[] = {
3054 "()",
"(t)",
"(e)",
"(tt)",
"(et)",
"(te)",
"(ee)",
"(ttt)",
"(ett)",
3055 "(tet)",
"(eet)",
"(tte)",
"(ete)",
"(tee)",
"(eee)"
3057 assert((ITMask.Mask & 0xf) == ITMask.Mask);
3058 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
3062 OS <<
"<coprocessor number: " << getCoproc() <<
">";
3065 OS <<
"<coprocessor register: " << getCoproc() <<
">";
3067 case k_CoprocOption:
3068 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
3071 OS <<
"<mask: " << getMSRMask() <<
">";
3074 OS <<
"<banked reg: " << getBankedReg() <<
">";
3079 case k_MemBarrierOpt:
3080 OS <<
"<ARM_MB::" <<
MemBOptToString(getMemBarrierOpt(),
false) <<
">";
3082 case k_InstSyncBarrierOpt:
3087 <<
" base:" <<
Memory.BaseRegNum;
3090 case k_PostIndexRegister:
3091 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
3092 << PostIdxReg.RegNum;
3095 << PostIdxReg.ShiftImm;
3098 case k_ProcIFlags: {
3099 OS <<
"<ARM_PROC::";
3100 unsigned IFlags = getProcIFlags();
3101 for (
int i=2;
i >= 0; --
i)
3102 if (IFlags & (1 <<
i))
3108 OS <<
"<register " <<
getReg() <<
">";
3110 case k_ShifterImmediate:
3111 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
3112 <<
" #" << ShifterImm.Imm <<
">";
3114 case k_ShiftedRegister:
3115 OS <<
"<so_reg_reg "
3116 << RegShiftedReg.SrcReg <<
" "
3118 <<
" " << RegShiftedReg.ShiftReg <<
">";
3120 case k_ShiftedImmediate:
3121 OS <<
"<so_reg_imm "
3122 << RegShiftedImm.SrcReg <<
" "
3124 <<
" #" << RegShiftedImm.ShiftImm <<
">";
3126 case k_RotateImmediate:
3127 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
3129 case k_ModifiedImmediate:
3130 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
3131 << ModImm.Rot <<
")>";
3133 case k_ConstantPoolImmediate:
3134 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
3136 case k_BitfieldDescriptor:
3137 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
3138 <<
", width: " <<
Bitfield.Width <<
">";
3140 case k_RegisterList:
3141 case k_DPRRegisterList:
3142 case k_SPRRegisterList: {
3143 OS <<
"<register_list ";
3149 if (++I <
E) OS <<
", ";
3156 OS <<
"<vector_list " << VectorList.Count <<
" * "
3157 << VectorList.RegNum <<
">";
3159 case k_VectorListAllLanes:
3160 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
3161 << VectorList.RegNum <<
">";
3163 case k_VectorListIndexed:
3164 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
3165 << VectorList.Count <<
" * " << VectorList.RegNum <<
">";
3171 OS <<
"<vectorindex " << getVectorIndex() <<
">";
3183 bool ARMAsmParser::ParseRegister(
unsigned &RegNo,
3185 const AsmToken &Tok = getParser().getTok();
3188 RegNo = tryParseRegister();
3190 return (RegNo == (
unsigned)-1);
3197 int ARMAsmParser::tryParseRegister() {
3206 .Case(
"r13", ARM::SP)
3207 .
Case(
"r14", ARM::LR)
3209 .
Case(
"ip", ARM::R12)
3211 .
Case(
"a1", ARM::R0)
3212 .
Case(
"a2", ARM::R1)
3214 .
Case(
"a4", ARM::R3)
3216 .
Case(
"v2", ARM::R5)
3218 .
Case(
"v4", ARM::R7)
3219 .
Case(
"v5", ARM::R8)
3220 .
Case(
"v6", ARM::R9)
3221 .
Case(
"v7", ARM::R10)
3222 .
Case(
"v8", ARM::R11)
3223 .
Case(
"sb", ARM::R9)
3224 .
Case(
"sl", ARM::R10)
3225 .
Case(
"fp", ARM::R11)
3234 if (Entry == RegisterReqs.
end())
3237 return Entry->getValue();
3241 if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
3254 int ARMAsmParser::tryParseShiftRegister(
OperandVector &Operands) {
3279 std::unique_ptr<ARMOperand> PrevOp(
3281 if (!PrevOp->isReg())
3282 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
3283 int SrcReg = PrevOp->getReg();
3299 const MCExpr *ShiftExpr =
nullptr;
3300 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
3301 Error(ImmLoc,
"invalid immediate shift value");
3307 Error(ImmLoc,
"invalid immediate shift value");
3317 Error(ImmLoc,
"immediate shift value out of range");
3327 ShiftReg = tryParseRegister();
3328 if (ShiftReg == -1) {
3329 Error(L,
"expected immediate or register in shift operand");
3334 "expected immediate or register in shift operand");
3340 Operands.
push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
3344 Operands.
push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
3357 bool ARMAsmParser::tryParseRegisterWithWriteBack(
OperandVector &Operands) {
3360 int RegNo = tryParseRegister();
3383 if (getParser().parseExpression(ImmVal))
3387 return TokError(
"immediate value expected for vector index");
3415 if (Name.
size() < 2 || Name[0] != CoprocOp)
3419 switch (Name.
size()) {
3442 case '0':
return 10;
3443 case '1':
return 11;
3444 case '2':
return 12;
3445 case '3':
return 13;
3446 case '4':
return 14;
3447 case '5':
return 15;
3492 ARMAsmParser::parseCoprocNumOperand(
OperandVector &Operands) {
3503 if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
3507 Operands.
push_back(ARMOperand::CreateCoprocNum(Num, S));
3515 ARMAsmParser::parseCoprocRegOperand(
OperandVector &Operands) {
3527 Operands.
push_back(ARMOperand::CreateCoprocReg(Reg, S));
3534 ARMAsmParser::parseCoprocOptionOperand(
OperandVector &Operands) {
3545 if (getParser().parseExpression(Expr)) {
3546 Error(Loc,
"illegal expression");
3551 Error(Loc,
"coprocessor option must be an immediate in range [0, 255]");
3562 Operands.
push_back(ARMOperand::CreateCoprocOption(Val, S, E));
3573 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3577 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
3580 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
3581 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
3582 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
3583 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
3592 case ARM::Q0:
return ARM::D0;
3593 case ARM::Q1:
return ARM::D2;
3594 case ARM::Q2:
return ARM::D4;
3595 case ARM::Q3:
return ARM::D6;
3596 case ARM::Q4:
return ARM::D8;
3597 case ARM::Q5:
return ARM::D10;
3598 case ARM::Q6:
return ARM::D12;
3599 case ARM::Q7:
return ARM::D14;
3600 case ARM::Q8:
return ARM::D16;
3601 case ARM::Q9:
return ARM::D18;
3602 case ARM::Q10:
return ARM::D20;
3603 case ARM::Q11:
return ARM::D22;
3604 case ARM::Q12:
return ARM::D24;
3605 case ARM::Q13:
return ARM::D26;
3606 case ARM::Q14:
return ARM::D28;
3607 case ARM::Q15:
return ARM::D30;
3612 bool ARMAsmParser::parseRegisterList(
OperandVector &Operands) {
3615 return TokError(
"Token is not a Left Curly Brace");
3622 int Reg = tryParseRegister();
3624 return Error(RegLoc,
"register expected");
3632 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3634 EReg =
MRI->getEncodingValue(Reg);
3635 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3639 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3640 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
3641 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg))
3642 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
3643 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(Reg))
3644 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
3646 return Error(RegLoc,
"invalid register in register list");
3649 EReg =
MRI->getEncodingValue(Reg);
3650 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3660 int EndReg = tryParseRegister();
3662 return Error(AfterMinusLoc,
"register expected");
3664 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
3672 return Error(AfterMinusLoc,
"invalid register in register list");
3674 if (
MRI->getEncodingValue(Reg) >
MRI->getEncodingValue(EndReg))
3675 return Error(AfterMinusLoc,
"bad range in register list");
3678 while (Reg != EndReg) {
3680 EReg =
MRI->getEncodingValue(Reg);
3681 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3689 Reg = tryParseRegister();
3691 return Error(RegLoc,
"register expected");
3693 bool isQReg =
false;
3694 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3700 return Error(RegLoc,
"invalid register in register list");
3702 if (
MRI->getEncodingValue(Reg) <
MRI->getEncodingValue(OldReg)) {
3703 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3704 Warning(RegLoc,
"register list not in ascending order");
3706 return Error(RegLoc,
"register list not in ascending order");
3708 if (
MRI->getEncodingValue(Reg) ==
MRI->getEncodingValue(OldReg)) {
3709 Warning(RegLoc,
"duplicated register (" + RegTok.
getString() +
3710 ") in register list");
3714 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
3716 return Error(RegLoc,
"non-contiguous register range");
3717 EReg =
MRI->getEncodingValue(Reg);
3718 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3720 EReg =
MRI->getEncodingValue(++Reg);
3721 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3731 Operands.
push_back(ARMOperand::CreateRegList(Registers, S, E));
3751 LaneKind = AllLanes;
3764 if (getParser().parseExpression(LaneIndex)) {
3765 Error(Loc,
"illegal expression");
3770 Error(Loc,
"lane index must be empty or an integer");
3782 if (Val < 0 || Val > 7) {
3787 LaneKind = IndexedLane;
3806 int Reg = tryParseRegister();
3809 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg)) {
3815 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 1,
false, S, E));
3818 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1,
false,
3822 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
3829 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3836 Reg =
MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3837 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3838 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 2,
false, S, E));
3841 Reg =
MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3842 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3843 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2,
false,
3847 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
3854 Error(S,
"vector register expected");
3864 int Reg = tryParseRegister();
3866 Error(RegLoc,
"register expected");
3871 unsigned FirstReg =
Reg;
3874 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3891 else if (Spacing == 2) {
3893 "sequential registers in double spaced list");
3898 int EndReg = tryParseRegister();
3900 Error(AfterMinusLoc,
"register expected");
3904 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
3911 if (!ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(EndReg)) {
3912 Error(AfterMinusLoc,
"invalid register in register list");
3917 Error(AfterMinusLoc,
"bad range in register list");
3922 unsigned NextLaneIndex;
3923 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
3926 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3927 Error(AfterMinusLoc,
"mismatched lane index in register list");
3932 Count += EndReg -
Reg;
3939 Reg = tryParseRegister();
3941 Error(RegLoc,
"register expected");
3950 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3953 else if (Spacing == 2) {
3955 "invalid register in double-spaced list (must be 'D' register')");
3959 if (Reg != OldReg + 1) {
3960 Error(RegLoc,
"non-contiguous register range");
3967 unsigned NextLaneIndex;
3969 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
3972 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3973 Error(LaneLoc,
"mismatched lane index in register list");
3982 Spacing = 1 + (Reg == OldReg + 2);
3985 if (Reg != OldReg + Spacing) {
3986 Error(RegLoc,
"non-contiguous register range");
3992 unsigned NextLaneIndex;
3996 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3997 Error(EndLoc,
"mismatched lane index in register list");
4015 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4016 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4017 FirstReg =
MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4020 Operands.
push_back(ARMOperand::CreateVectorList(FirstReg, Count,
4021 (Spacing == 2), S, E));
4028 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4029 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4030 FirstReg =
MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4032 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
4037 Operands.
push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
4048 ARMAsmParser::parseMemBarrierOptOperand(
OperandVector &Operands) {
4092 const MCExpr *MemBarrierID;
4093 if (getParser().parseExpression(MemBarrierID)) {
4094 Error(Loc,
"illegal expression");
4100 Error(Loc,
"constant expression expected");
4106 Error(Loc,
"immediate value out of range");
4120 ARMAsmParser::parseInstSyncBarrierOptOperand(
OperandVector &Operands) {
4142 const MCExpr *ISBarrierID;
4143 if (getParser().parseExpression(ISBarrierID)) {
4144 Error(Loc,
"illegal expression");
4150 Error(Loc,
"constant expression expected");
4156 Error(Loc,
"immediate value out of range");
4164 Operands.
push_back(ARMOperand::CreateInstSyncBarrierOpt(
4172 ARMAsmParser::parseProcIFlagsOperand(
OperandVector &Operands) {
4182 unsigned IFlags = 0;
4183 if (IFlagsStr !=
"none") {
4184 for (
int i = 0, e = IFlagsStr.
size();
i != e; ++
i) {
4193 if (Flag == ~0U || (IFlags & Flag))
4207 ARMAsmParser::parseMSRMaskOperand(
OperandVector &Operands) {
4229 .Case(
"apsr", 0x800)
4230 .
Case(
"apsr_nzcvq", 0x800)
4231 .
Case(
"apsr_g", 0x400)
4232 .
Case(
"apsr_nzcvqg", 0xc00)
4233 .
Case(
"iapsr", 0x801)
4234 .
Case(
"iapsr_nzcvq", 0x801)
4235 .
Case(
"iapsr_g", 0x401)
4236 .
Case(
"iapsr_nzcvqg", 0xc01)
4237 .
Case(
"eapsr", 0x802)
4238 .
Case(
"eapsr_nzcvq", 0x802)
4239 .
Case(
"eapsr_g", 0x402)
4240 .
Case(
"eapsr_nzcvqg", 0xc02)
4241 .
Case(
"xpsr", 0x803)
4242 .
Case(
"xpsr_nzcvq", 0x803)
4243 .
Case(
"xpsr_g", 0x403)
4244 .
Case(
"xpsr_nzcvqg", 0xc03)
4245 .
Case(
"ipsr", 0x805)
4246 .
Case(
"epsr", 0x806)
4247 .
Case(
"iepsr", 0x807)
4250 .
Case(
"primask", 0x810)
4251 .
Case(
"basepri", 0x811)
4252 .
Case(
"basepri_max", 0x812)
4253 .
Case(
"faultmask", 0x813)
4254 .
Case(
"control", 0x814)
4255 .
Case(
"msplim", 0x80a)
4256 .
Case(
"psplim", 0x80b)
4257 .
Case(
"msp_ns", 0x888)
4258 .
Case(
"psp_ns", 0x889)
4259 .
Case(
"msplim_ns", 0x88a)
4260 .
Case(
"psplim_ns", 0x88b)
4261 .
Case(
"primask_ns", 0x890)
4262 .
Case(
"basepri_ns", 0x891)
4263 .
Case(
"basepri_max_ns", 0x892)
4264 .
Case(
"faultmask_ns", 0x893)
4265 .
Case(
"control_ns", 0x894)
4266 .
Case(
"sp_ns", 0x898)
4269 if (FlagsVal == ~0U)
4272 if (!hasDSP() && (FlagsVal & 0x400))
4277 if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
4281 if (!has8MSecExt() && (FlagsVal == 0x80a || FlagsVal == 0x80b ||
4282 (FlagsVal > 0x814 && FlagsVal < 0xc00)))
4285 if (!hasV8MMainline() && (FlagsVal == 0x88a || FlagsVal == 0x88b ||
4286 (FlagsVal > 0x890 && FlagsVal <= 0x893)))
4290 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
4295 size_t Start = 0, Next = Mask.
find(
'_');
4297 std::string SpecReg = Mask.
slice(Start, Next).
lower();
4299 Flags = Mask.
slice(Next+1, Mask.
size());
4304 unsigned FlagsVal = 0;
4306 if (SpecReg ==
"apsr") {
4310 .
Case(
"nzcvqg", 0xc)
4313 if (FlagsVal == ~0U) {
4319 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
4321 if (Flags ==
"all" || Flags ==
"")
4323 for (
int i = 0, e = Flags.
size();
i != e; ++
i) {
4333 if (FlagsVal == ~0U || (FlagsVal & Flag))
4349 if (SpecReg ==
"spsr")
4353 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
4360 ARMAsmParser::parseBankedRegOperand(
OperandVector &Operands) {
4371 .Case(
"r8_usr", 0x00)
4372 .
Case(
"r9_usr", 0x01)
4373 .
Case(
"r10_usr", 0x02)
4374 .
Case(
"r11_usr", 0x03)
4375 .
Case(
"r12_usr", 0x04)
4376 .
Case(
"sp_usr", 0x05)
4377 .
Case(
"lr_usr", 0x06)
4378 .
Case(
"r8_fiq", 0x08)
4379 .
Case(
"r9_fiq", 0x09)
4380 .
Case(
"r10_fiq", 0x0a)
4381 .
Case(
"r11_fiq", 0x0b)
4382 .
Case(
"r12_fiq", 0x0c)
4383 .
Case(
"sp_fiq", 0x0d)
4384 .
Case(
"lr_fiq", 0x0e)
4385 .
Case(
"lr_irq", 0x10)
4386 .
Case(
"sp_irq", 0x11)
4387 .
Case(
"lr_svc", 0x12)
4388 .
Case(
"sp_svc", 0x13)
4389 .
Case(
"lr_abt", 0x14)
4390 .
Case(
"sp_abt", 0x15)
4391 .
Case(
"lr_und", 0x16)
4392 .
Case(
"sp_und", 0x17)
4393 .
Case(
"lr_mon", 0x1c)
4394 .
Case(
"sp_mon", 0x1d)
4395 .
Case(
"elr_hyp", 0x1e)
4396 .
Case(
"sp_hyp", 0x1f)
4397 .
Case(
"spsr_fiq", 0x2e)
4398 .
Case(
"spsr_irq", 0x30)
4399 .
Case(
"spsr_svc", 0x32)
4400 .
Case(
"spsr_abt", 0x34)
4401 .
Case(
"spsr_und", 0x36)
4402 .
Case(
"spsr_mon", 0x3c)
4403 .
Case(
"spsr_hyp", 0x3e)
4406 if (Encoding == ~0U)
4410 Operands.
push_back(ARMOperand::CreateBankedReg(Encoding, S));
4424 std::string LowerOp = Op.
lower();
4425 std::string UpperOp = Op.
upper();
4426 if (ShiftName != LowerOp && ShiftName != UpperOp) {
4440 const MCExpr *ShiftAmount;
4443 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4444 Error(Loc,
"illegal expression");
4449 Error(Loc,
"constant expression expected");
4453 if (Val < Low || Val > High) {
4454 Error(Loc,
"immediate value out of range");
4458 Operands.
push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
4469 Error(S,
"'be' or 'le' operand expected");
4479 Error(S,
"'be' or 'le' operand expected");
4499 Error(S,
"shift operator 'asr' or 'lsl' expected");
4504 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
4506 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
4509 Error(S,
"shift operator 'asr' or 'lsl' expected");
4523 const MCExpr *ShiftAmount;
4525 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4526 Error(ExLoc,
"malformed shift expression");
4531 Error(ExLoc,
"shift amount must be an immediate");
4538 if (Val < 1 || Val > 32) {
4539 Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
4544 Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
4547 if (Val == 32) Val = 0;
4550 if (Val < 0 || Val > 31) {
4551 Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
4556 Operands.
push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
4572 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
4585 const MCExpr *ShiftAmount;
4587 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4588 Error(ExLoc,
"malformed rotate expression");
4593 Error(ExLoc,
"rotate amount must be an immediate");
4601 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
4602 Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
4606 Operands.
push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
4646 if (getParser().parseExpression(Imm1Exp, Ex1)) {
4647 Error(Sx1,
"malformed expression");
4659 Operands.
push_back(ARMOperand::CreateModImm((Enc & 0xFF),
4672 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4678 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4684 Error(Sx1,
"expected modified immediate operand: #[0, 255], #even[0-30]");
4689 Error(Sx1,
"immediate operand must a number in the range [0, 255]");
4706 if (getParser().parseExpression(Imm2Exp, Ex2)) {
4707 Error(Sx2,
"malformed expression");
4715 if (!(Imm2 & ~0x1E)) {
4717 Operands.
push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
4720 Error(Sx2,
"immediate operand must an even number in the range [0, 30]");
4723 Error(Sx2,
"constant expression expected");
4742 if (getParser().parseExpression(LSBExpr)) {
4743 Error(E,
"malformed immediate expression");
4748 Error(E,
"'lsb' operand must be an immediate");
4754 if (LSB < 0 || LSB > 31) {
4755 Error(E,
"'lsb' operand must be in the range [0,31]");
4775 if (getParser().parseExpression(WidthExpr, EndLoc)) {
4776 Error(E,
"malformed immediate expression");
4781 Error(E,
"'width' operand must be an immediate");
4787 if (Width < 1 || Width > 32 - LSB) {
4788 Error(E,
"'width' operand must be in the range [1,32-lsb]");
4792 Operands.
push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
4810 bool haveEaten =
false;
4822 int Reg = tryParseRegister();
4831 unsigned ShiftImm = 0;
4834 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
4841 Operands.
push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
4873 if (getParser().parseExpression(Offset, E))
4877 Error(S,
"constant expression expected");
4882 if (isNegative && Val == 0)
4892 bool haveEaten =
false;
4904 int Reg = tryParseRegister();
4921 void ARMAsmParser::cvtThumbMultiply(
MCInst &Inst,
4923 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
4924 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
4928 if (Operands.
size() == 6 &&
4929 ((ARMOperand &)*Operands[4]).getReg() ==
4930 ((ARMOperand &)*Operands[3]).getReg())
4932 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
4934 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
4937 void ARMAsmParser::cvtThumbBranches(
MCInst &Inst,
4939 int CondOp = -1, ImmOp = -1;
4942 case ARM::tBcc: CondOp = 1; ImmOp = 2;
break;
4945 case ARM::t2Bcc: CondOp = 1; ImmOp = 3;
break;
4955 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
4956 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
4961 unsigned Cond =
static_cast<ARMOperand &
>(*Operands[CondOp]).getCondCode();
4978 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
4979 if (!op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
4985 ARMOperand &op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
4986 if (!op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
4991 ((ARMOperand &)*Operands[ImmOp]).addImmOperands(Inst, 1);
4992 ((ARMOperand &)*Operands[CondOp]).addCondCodeOperands(Inst, 2);
5001 return TokError(
"Token is not a Left Bracket");
5006 int BaseRegNum = tryParseRegister();
5007 if (BaseRegNum == -1)
5008 return Error(BaseRegTok.
getLoc(),
"register expected");
5014 return Error(Tok.getLoc(),
"malformed memory operand");
5017 E = Tok.getEndLoc();
5020 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
5035 "Lost colon or comma in memory operand?!");
5044 SMLoc AlignmentLoc = Tok.getLoc();
5047 if (getParser().parseExpression(Expr))
5055 return Error (E,
"constant expression expected");
5061 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
5062 case 16: Align = 2;
break;
5063 case 32: Align = 4;
break;
5064 case 64: Align = 8;
break;
5065 case 128: Align = 16;
break;
5066 case 256: Align = 32;
break;
5077 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
5079 false, S, E, AlignmentLoc));
5103 if (getParser().parseExpression(Offset))
5111 return Error (E,
"constant expression expected");
5115 if (isNegative && Val == 0)
5126 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
5141 bool isNegative =
false;
5151 int OffsetRegNum = tryParseRegister();
5152 if (OffsetRegNum == -1)
5153 return Error(E,
"register expected");
5157 unsigned ShiftImm = 0;
5160 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
5170 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, OffsetRegNum,
5171 ShiftType, ShiftImm, 0, isNegative,
5196 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
5197 ShiftName ==
"asl" || ShiftName ==
"ASL")
5199 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
5201 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5203 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
5205 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
5208 return Error(Loc,
"illegal shift operator");
5223 if (getParser().parseExpression(Expr))
5230 return Error(Loc,
"shift amount must be an immediate");
5235 return Error(Loc,
"immediate shift value out of range");
5277 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*Operands[2]);
5278 bool isVmovf = TyOp.isToken() &&
5279 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
5280 TyOp.getToken() ==
".f16");
5281 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*Operands[0]);
5282 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
5283 Mnemonic.getToken() ==
"fconsts");
5284 if (!(isVmovf || isFconst))
5290 bool isNegative =
false;
5299 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5301 IntVal ^= (uint64_t)isNegative << 31;
5303 Operands.
push_back(ARMOperand::CreateImm(
5313 if (Val > 255 || Val < 0) {
5314 Error(Loc,
"encoded floating point value out of range");
5318 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
5320 Operands.
push_back(ARMOperand::CreateImm(
5326 Error(Loc,
"invalid floating point immediate");
5347 switch (getLexer().getKind()) {
5355 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
5357 if (!tryParseRegisterWithWriteBack(Operands))
5359 int Res = tryParseShiftRegister(Operands);
5365 if (Mnemonic ==
"vmrs" &&
5369 Operands.
push_back(ARMOperand::CreateToken(
"APSR_nzcv", S));
5385 if (getParser().parseExpression(IdVal))
5388 Operands.
push_back(ARMOperand::CreateImm(IdVal, S, E));
5392 return parseMemory(Operands);
5394 return parseRegisterList(Operands);
5404 if (getParser().parseExpression(ImmVal))
5409 if (isNegative && Val == 0)
5413 Operands.
push_back(ARMOperand::CreateImm(ImmVal, S, E));
5434 if (parsePrefix(RefKind))
5437 const MCExpr *SubExprVal;
5438 if (getParser().parseExpression(SubExprVal))
5444 Operands.
push_back(ARMOperand::CreateImm(ExprVal, S, E));
5449 if (Mnemonic !=
"ldr")
5450 return Error(S,
"unexpected token in operand");
5452 const MCExpr *SubExprVal;
5453 if (getParser().parseExpression(SubExprVal))
5459 Operands.
push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E));
5489 static const struct PrefixEntry {
5490 const char *Spelling;
5492 uint8_t SupportedFormats;
5493 } PrefixEntries[] = {
5502 [&IDVal](
const PrefixEntry &PE) {
5503 return PE.Spelling == IDVal;
5510 uint8_t CurrentFormat;
5511 switch (getContext().getObjectFileInfo()->getObjectFileType()) {
5513 CurrentFormat = MACHO;
5516 CurrentFormat = ELF;
5519 CurrentFormat = COFF;
5523 if (~
Prefix->SupportedFormats & CurrentFormat) {
5525 "cannot represent relocation in the current file format");
5529 RefKind =
Prefix->VariantKind;
5547 unsigned &PredicationCode,
5549 unsigned &ProcessorIMod,
5552 CarrySetting =
false;
5558 if ((Mnemonic ==
"movs" &&
isThumb()) ||
5559 Mnemonic ==
"teq" || Mnemonic ==
"vceq" || Mnemonic ==
"svc" ||
5560 Mnemonic ==
"mls" || Mnemonic ==
"smmls" || Mnemonic ==
"vcls" ||
5561 Mnemonic ==
"vmls" || Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" ||
5562 Mnemonic ==
"vcge" || Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" ||
5563 Mnemonic ==
"vaclt" || Mnemonic ==
"vacle" || Mnemonic ==
"hlt" ||
5564 Mnemonic ==
"vcgt" || Mnemonic ==
"vcle" || Mnemonic ==
"smlal" ||
5565 Mnemonic ==
"umaal" || Mnemonic ==
"umlal" || Mnemonic ==
"vabal" ||
5566 Mnemonic ==
"vmlal" || Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" ||
5567 Mnemonic ==
"fmuls" || Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" ||
5568 Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" ||
5569 Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" ||
5570 Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
5571 Mnemonic.
startswith(
"vsel") || Mnemonic ==
"vins" || Mnemonic ==
"vmovx" ||
5572 Mnemonic ==
"bxns" || Mnemonic ==
"blxns")
5577 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
5578 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
5579 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
5580 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs") {
5601 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
5602 PredicationCode = CC;
5609 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" ||
5610 Mnemonic ==
"mrs" || Mnemonic ==
"smmls" || Mnemonic ==
"vabs" ||
5611 Mnemonic ==
"vcls" || Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" ||
5612 Mnemonic ==
"vnmls" || Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" ||
5613 Mnemonic ==
"vrsqrts" || Mnemonic ==
"srs" || Mnemonic ==
"flds" ||
5614 Mnemonic ==
"fmrs" || Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" ||
5615 Mnemonic ==
"fsts" || Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" ||
5616 Mnemonic ==
"fmuls" || Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" ||
5617 Mnemonic ==
"vfms" || Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" ||
5618 Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
5619 (Mnemonic ==
"movs" &&
isThumb()))) {
5620 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
5621 CarrySetting =
true;
5634 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
5635 ProcessorIMod =
IMod;
5641 ITMask = Mnemonic.
slice(2, Mnemonic.
size());
5642 Mnemonic = Mnemonic.
slice(0, 2);
5653 bool &CanAcceptCarrySet,
5654 bool &CanAcceptPredicationCode) {
5656 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5657 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
5658 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
5659 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
5660 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
5661 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
5662 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
5664 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
5665 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
5667 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
5668 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
5669 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
5671 Mnemonic.
startswith(
"vsel") || Mnemonic ==
"vmaxnm" ||
5672 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
5673 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
5674 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
5675 Mnemonic.
startswith(
"aes") || Mnemonic ==
"hvc" || Mnemonic ==
"setpan" ||
5678 Mnemonic ==
"vmovx" || Mnemonic ==
"vins") {
5680 CanAcceptPredicationCode =
false;
5683 CanAcceptPredicationCode =
5684 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
5685 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
5686 Mnemonic !=
"dmb" && Mnemonic !=
"dsb" && Mnemonic !=
"isb" &&
5687 Mnemonic !=
"pld" && Mnemonic !=
"pli" && Mnemonic !=
"pldw" &&
5688 Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" && Mnemonic !=
"stc2" &&
5689 Mnemonic !=
"stc2l" && !Mnemonic.
startswith(
"rfe") &&
5691 }
else if (isThumbOne()) {
5693 CanAcceptPredicationCode = Mnemonic !=
"movs";
5695 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
5697 CanAcceptPredicationCode =
true;
5704 void ARMAsmParser::tryConvertingToTwoOperandForm(
StringRef Mnemonic,
5707 if (Operands.
size() != 6)
5710 const auto &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
5711 auto &Op4 =
static_cast<ARMOperand &
>(*Operands[4]);
5712 if (!Op3.isReg() || !Op4.isReg())
5715 auto Op3Reg = Op3.getReg();
5716 auto Op4Reg = Op4.getReg();
5722 auto &Op5 =
static_cast<ARMOperand &
>(*Operands[5]);
5724 if (Mnemonic !=
"add")
5727 (Op5.isReg() && Op5.getReg() ==
ARM::PC);
5728 if (!TryTransform) {
5729 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
5730 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
5731 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
5732 Op5.isImm() && !Op5.isImm0_508s4());
5736 }
else if (!isThumbOne())
5739 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
5740 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5741 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
5742 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
5748 bool Transform = Op3Reg == Op4Reg;
5753 const ARMOperand *LastOp = &Op5;
5755 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
5756 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
5757 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
5758 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
5769 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
5775 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
5786 bool ARMAsmParser::shouldOmitCCOutOperand(
StringRef Mnemonic,
5799 if (Mnemonic ==
"mov" && Operands.
size() > 4 && !
isThumb() &&
5800 !
static_cast<ARMOperand &
>(*Operands[4]).isModImm() &&
5801 static_cast<ARMOperand &
>(*Operands[4]).isImm0_65535Expr() &&
5802 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5807 if (
isThumb() && Mnemonic ==
"add" && Operands.
size() == 5 &&
5808 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5809 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5810 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5816 if (((
isThumb() && Mnemonic ==
"add") ||
5817 (isThumbTwo() && Mnemonic ==
"sub")) &&
5818 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5819 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5820 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::SP &&
5821 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5822 ((Mnemonic ==
"add" &&
static_cast<ARMOperand &
>(*Operands[5]).
isReg()) ||
5823 static_cast<ARMOperand &>(*Operands[5]).isImm0_1020s4()))
5830 if (isThumbTwo() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5831 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5832 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5833 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
5841 static_cast<ARMOperand &
>(*Operands[5]).isImm0_7())
5845 if (static_cast<ARMOperand &>(*Operands[4]).getReg() !=
ARM::PC &&
5846 static_cast<ARMOperand &
>(*Operands[5]).isT2SOImm())
5857 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 6 &&
5858 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5859 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5860 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5861 static_cast<ARMOperand &
>(*Operands[5]).
isReg() &&
5869 !inITBlock() || (
static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5870 static_cast<ARMOperand &
>(*Operands[5]).
getReg() &&
5871 static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5872 static_cast<ARMOperand &
>(*Operands[4]).
getReg())))
5877 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 5 &&
5878 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5879 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5880 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5896 if (
isThumb() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5897 (Operands.
size() == 5 || Operands.
size() == 6) &&
5898 static_cast<ARMOperand &>(*Operands[3]).isReg() &&
5899 static_cast<ARMOperand &
>(*Operands[3]).
getReg() == ARM::SP &&
5900 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5901 (
static_cast<ARMOperand &
>(*Operands[4]).isImm() ||
5902 (Operands.
size() == 6 &&
5903 static_cast<ARMOperand &
>(*Operands[5]).isImm())))
5909 bool ARMAsmParser::shouldOmitPredicateOperand(
StringRef Mnemonic,
5912 unsigned RegIdx = 3;
5913 if ((Mnemonic ==
"vrintz" || Mnemonic ==
"vrintx" || Mnemonic ==
"vrintr") &&
5914 (static_cast<ARMOperand &>(*Operands[2]).
getToken() ==
".f32" ||
5915 static_cast<ARMOperand &>(*Operands[2]).
getToken() ==
".f16")) {
5916 if (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
5917 (static_cast<ARMOperand &>(*Operands[3]).
getToken() ==
".f32" ||
5918 static_cast<ARMOperand &>(*Operands[3]).
getToken() ==
".f16"))
5921 if (static_cast<ARMOperand &>(*Operands[RegIdx]).
isReg() &&
5922 (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
5923 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg()) ||
5924 ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
5925 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg())))
5932 return Tok ==
".8" || Tok ==
".16" || Tok ==
".32" || Tok ==
".64" ||
5933 Tok ==
".i8" || Tok ==
".i16" || Tok ==
".i32" || Tok ==
".i64" ||
5934 Tok ==
".u8" || Tok ==
".u16" || Tok ==
".u32" || Tok ==
".u64" ||
5935 Tok ==
".s8" || Tok ==
".s16" || Tok ==
".s32" || Tok ==
".s64" ||
5936 Tok ==
".p8" || Tok ==
".p16" || Tok ==
".f32" || Tok ==
".f64" ||
5937 Tok ==
".f" || Tok ==
".d";
5947 unsigned VariantID);
5950 bool &AcceptSinglePrecisionOnly,
5951 bool &AcceptDoublePrecisionOnly) {
5952 if (Inst.
size() < 7)
5957 if (AddressingMode ==
"ia" || AddressingMode ==
"db" ||
5958 AddressingMode ==
"ea" || AddressingMode ==
"fd") {
5959 AcceptSinglePrecisionOnly = Inst[6] ==
's';
5960 AcceptDoublePrecisionOnly = Inst[6] ==
'd' || Inst[6] ==
'x';
5973 bool RequireVFPRegisterListCheck;
5974 bool AcceptSinglePrecisionOnly;
5975 bool AcceptDoublePrecisionOnly;
5976 RequireVFPRegisterListCheck =
5978 AcceptDoublePrecisionOnly);
5985 uint64_t AvailableFeatures = getAvailableFeatures();
5986 unsigned AssemblerDialect = getParser().getAssemblerDialect();
5992 parseDirectiveReq(Name, NameLoc);
5999 size_t Start = 0, Next = Name.
find(
'.');
6003 unsigned PredicationCode;
6004 unsigned ProcessorIMod;
6007 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
6008 ProcessorIMod, ITMask);
6011 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
6012 return Error(NameLoc,
"conditional execution not supported in Thumb1");
6015 Operands.
push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
6022 if (Mnemonic ==
"it") {
6024 if (ITMask.
size() > 3) {
6025 return Error(Loc,
"too many conditions on IT instruction");
6028 for (
unsigned i = ITMask.
size();
i != 0; --
i) {
6029 char pos = ITMask[
i - 1];
6030 if (pos !=
't' && pos !=
'e') {
6031 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
6034 if (ITMask[
i - 1] ==
't')
6037 Operands.
push_back(ARMOperand::CreateITMask(Mask, Loc));
6050 bool CanAcceptCarrySet, CanAcceptPredicationCode;
6051 getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode);
6055 if (!CanAcceptCarrySet && CarrySetting) {
6056 return Error(NameLoc,
"instruction '" + Mnemonic +
6057 "' can not set flags, but 's' suffix specified");
6061 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
6062 return Error(NameLoc,
"instruction '" + Mnemonic +
6063 "' is not predicable, but condition code specified");
6067 if (CanAcceptCarrySet) {
6069 Operands.
push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
6074 if (CanAcceptPredicationCode) {
6077 Operands.
push_back(ARMOperand::CreateCondCode(
6082 if (ProcessorIMod) {
6083 Operands.
push_back(ARMOperand::CreateImm(
6086 }
else if (Mnemonic ==
"cps" && isMClass()) {
6087 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
6093 Next = Name.
find(
'.', Start + 1);
6103 if (ExtraToken ==
".n" && !
isThumb()) {
6105 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
6112 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
6114 Operands.
push_back(ARMOperand::CreateToken(ExtraToken, Loc));
6121 if (parseOperand(Operands, Mnemonic)) {
6127 if (parseOperand(Operands, Mnemonic)) {
6136 if (RequireVFPRegisterListCheck) {
6137 ARMOperand &Op =
static_cast<ARMOperand &
>(*Operands.
back());
6138 if (AcceptSinglePrecisionOnly && !Op.isSPRRegList())
6139 return Error(Op.getStartLoc(),
6140 "VFP/Neon single precision register expected");
6141 if (AcceptDoublePrecisionOnly && !Op.isDPRRegList())
6142 return Error(Op.getStartLoc(),
6143 "VFP/Neon double precision register expected");
6146 tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
6155 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands))
6161 if (shouldOmitPredicateOperand(Mnemonic, Operands))
6169 if (!
isThumb() && Mnemonic ==
"blx" && Operands.
size() == 3 &&
6170 static_cast<ARMOperand &
>(*Operands[2]).isImm())
6180 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
6181 Mnemonic ==
"stlexd")) {
6182 bool isLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
6183 unsigned Idx = isLoad ? 2 : 3;
6184 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*Operands[Idx]);
6185 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[Idx + 1]);
6189 if (Op1.isReg() && Op2.isReg() && MRC.
contains(Op1.getReg()) &&
6191 unsigned Reg1 = Op1.getReg();
6192 unsigned Reg2 = Op2.getReg();
6193 unsigned Rt =
MRI->getEncodingValue(Reg1);
6194 unsigned Rt2 =
MRI->getEncodingValue(Reg2);
6197 if (Rt + 1 != Rt2 || (Rt & 1)) {
6198 return Error(Op2.getStartLoc(),
6199 isLoad ?
"destination operands must be sequential"
6200 :
"source operands must be sequential");
6202 unsigned NewReg =
MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
6203 &(
MRI->getRegClass(ARM::GPRPairRegClassID)));
6205 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
6211 if ((Mnemonic ==
"ldrd" || Mnemonic ==
"strd")) {
6212 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[2]);
6213 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
6215 assert(Op2.isReg() &&
"expected register argument");
6217 unsigned SuperReg =
MRI->getMatchingSuperReg(
6218 Op2.getReg(), ARM::gsub_0, &
MRI->getRegClass(ARM::GPRPairRegClassID));
6220 assert(SuperReg &&
"expected register pair");
6222 unsigned PairedReg =
MRI->getSubReg(SuperReg, ARM::gsub_1);
6225 Operands.
begin() + 3,
6226 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc()));
6235 if (isThumbTwo() && Mnemonic ==
"sub" && Operands.
size() == 6 &&
6236 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
6237 static_cast<ARMOperand &
>(*Operands[3]).
getReg() ==
ARM::PC &&
6238 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
6239 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::LR &&
6240 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
6241 Operands.
front() = ARMOperand::CreateToken(Name, NameLoc);
6253 unsigned Reg,
unsigned HiReg,
6254 bool &containsReg) {
6255 containsReg =
false;
6281 return Inst.
getOpcode() == ARM::tBKPT ||
6288 bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
6290 unsigned ListNo,
bool IsARPop) {
6291 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6292 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6298 if (!IsARPop && ListContainsSP)
6299 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6300 "SP may not be in the register list");
6301 else if (ListContainsPC && ListContainsLR)
6302 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6303 "PC and LR may not be in the register list simultaneously");
6304 else if (inITBlock() && !lastInITBlock() && ListContainsPC)
6305 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6306 "instruction must be outside of IT block or the last "
6307 "instruction in an IT block");
6311 bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
6314 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6315 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6320 if (ListContainsSP && ListContainsPC)
6321 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6322 "SP and PC may not be in the register list");
6323 else if (ListContainsSP)
6324 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6325 "SP may not be in the register list");
6326 else if (ListContainsPC)
6327 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6328 "PC may not be in the register list");
6333 bool ARMAsmParser::validateInstruction(
MCInst &Inst,
6336 SMLoc Loc = Operands[0]->getStartLoc();
6344 return Error(Loc,
"instructions in IT block must be predicable");
6346 if (Cond != currentITCond()) {
6349 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
6350 if (static_cast<ARMOperand &>(*Operands[
I]).isCondCode())
6351 CondLoc = Operands[I]->getStartLoc();
6352 return Error(CondLoc,
"incorrect condition in IT block; got '" +
6354 "', but expected '" +
6362 return Error(Loc,
"predicated instructions must be in IT block");
6366 return Warning(Loc,
"predicated instructions should be in IT block");
6369 const unsigned Opcode = Inst.
getOpcode();
6373 case ARM::LDRD_POST: {
6377 if (RtReg == ARM::LR)
6378 return Error(Operands[3]->getStartLoc(),
6381 const unsigned Rt =
MRI->getEncodingValue(RtReg);
6384 return Error(Operands[3]->getStartLoc(),
6385 "Rt must be even-numbered");
6390 return Error(Operands[3]->getStartLoc(),
6391 "destination operands must be sequential");
6393 if (Opcode == ARM::LDRD_PRE || Opcode == ARM::LDRD_POST) {
6397 if (Rn == Rt || Rn == Rt2)
6398 return Error(Operands[3]->getStartLoc(),
6399 "base register needs to be different from destination "
6406 case ARM::t2LDRD_PRE:
6407 case ARM::t2LDRD_POST: {
6412 return Error(Operands[3]->getStartLoc(),
6413 "destination operands can't be identical");
6419 if (RmReg == ARM::SP && !hasV8Ops())
6420 return Error(Operands[2]->getStartLoc(),
6421 "r13 (SP) is an unpredictable operand to BXJ");
6429 return Error(Operands[3]->getStartLoc(),
6430 "source operands must be sequential");
6434 case ARM::STRD_POST: {
6439 return Error(Operands[3]->getStartLoc(),
6440 "source operands must be sequential");
6443 case ARM::STR_PRE_IMM:
6444 case ARM::STR_PRE_REG:
6445 case ARM::STR_POST_IMM:
6446 case ARM::STR_POST_REG:
6448 case ARM::STRH_POST:
6449 case ARM::STRB_PRE_IMM:
6450 case ARM::STRB_PRE_REG:
6451 case ARM::STRB_POST_IMM:
6452 case ARM::STRB_POST_REG: {
6458 return Error(Operands[3]->getStartLoc(),
6459 "source register and base register can't be identical");
6462 case ARM::LDR_PRE_IMM:
6463 case ARM::LDR_PRE_REG:
6464 case ARM::LDR_POST_IMM:
6465 case ARM::LDR_POST_REG:
6467 case ARM::LDRH_POST:
6468 case ARM::LDRSH_PRE:
6469 case ARM::LDRSH_POST:
6470 case ARM::LDRB_PRE_IMM:
6471 case ARM::LDRB_PRE_REG:
6472 case ARM::LDRB_POST_IMM:
6473 case ARM::LDRB_POST_REG:
6474 case ARM::LDRSB_PRE:
6475 case ARM::LDRSB_POST: {
6481 return Error(Operands[3]->getStartLoc(),
6482 "destination register and base register can't be identical");
6490 if (Widthm1 >= 32 - LSB)
6491 return Error(Operands[5]->getStartLoc(),
6492 "bitfield width must be in range [1,32-lsb]");
6504 bool HasWritebackToken =
6505 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
6506 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
6507 bool ListContainsBase;
6509 return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
6510 "registers must be in range r0-r7");
6512 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
6513 return Error(Operands[2]->getStartLoc(),
6514 "writeback operator '!' expected");
6517 if (ListContainsBase && HasWritebackToken)
6518 return Error(Operands[3]->getStartLoc(),
6519 "writeback operator '!' not allowed when base register "
6520 "in register list");
6522 if (validatetLDMRegList(Inst, Operands, 3))
6526 case ARM::LDMIA_UPD:
6527 case ARM::LDMDB_UPD:
6528 case ARM::LDMIB_UPD:
6529 case ARM::LDMDA_UPD:
6535 return Error(Operands.
back()->getStartLoc(),
6536 "writeback register not allowed in register list");
6540 if (validatetLDMRegList(Inst, Operands, 3))
6545 if (validatetSTMRegList(Inst, Operands, 3))
6548 case ARM::t2LDMIA_UPD:
6549 case ARM::t2LDMDB_UPD:
6550 case ARM::t2STMIA_UPD:
6551 case ARM::t2STMDB_UPD: {
6553 return Error(Operands.
back()->getStartLoc(),
6554 "writeback register not allowed in register list");
6556 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
6557 if (validatetLDMRegList(Inst, Operands, 3))
6560 if (validatetSTMRegList(Inst, Operands, 3))
6565 case ARM::sysLDMIA_UPD:
6566 case ARM::sysLDMDA_UPD:
6567 case ARM::sysLDMDB_UPD:
6568 case ARM::sysLDMIB_UPD:
6570 return Error(Operands[4]->getStartLoc(),
6571 "writeback register only allowed on system LDM "
6572 "if PC in register-list");
6574 case ARM::sysSTMIA_UPD:
6575 case ARM::sysSTMDA_UPD:
6576 case ARM::sysSTMDB_UPD:
6577 case ARM::sysSTMIB_UPD:
6578 return Error(Operands[2]->getStartLoc(),
6579 "system STM cannot have writeback register");
6589 if (Operands.
size() == 6 && (((ARMOperand &)*Operands[3]).getReg() !=
6590 ((ARMOperand &)*Operands[5]).getReg()) &&
6591 (((ARMOperand &)*Operands[3]).getReg() !=
6592 ((ARMOperand &)*Operands[4]).getReg())) {
6593 return Error(Operands[3]->getStartLoc(),
6594 "destination register must match source register");
6602 bool ListContainsBase;
6605 return Error(Operands[2]->getStartLoc(),
6606 "registers must be in range r0-r7 or pc");
6607 if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
6612 bool ListContainsBase;
6615 return Error(Operands[2]->getStartLoc(),
6616 "registers must be in range r0-r7 or lr");
6617 if (validatetSTMRegList(Inst, Operands, 2))
6621 case ARM::tSTMIA_UPD: {
6622 bool ListContainsBase, InvalidLowList;
6624 0, ListContainsBase);
6625 if (InvalidLowList && !isThumbTwo())
6626 return Error(Operands[4]->getStartLoc(),
6627 "registers must be in range r0-r7");
6631 if (InvalidLowList && ListContainsBase)
6632 return Error(Operands[4]->getStartLoc(),
6633 "writeback operator '!' not allowed when base register "
6634 "in register list");
6636 if (validatetSTMRegList(Inst, Operands, 4))
6640 case ARM::tADDrSP: {
6643 if (!isThumbTwo() &&
6645 return Error(Operands[4]->getStartLoc(),
6646 "source register must be the same as destination");
6652 if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>())
6653 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6656 int op = (Operands[2]->isImm()) ? 2 : 3;
6657 if (!static_cast<ARMOperand &>(*Operands[op]).isSignedOffset<24, 1>())
6658 return Error(Operands[op]->getStartLoc(),
"branch target out of range");
6663 if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<8, 1>())
6664 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6667 int Op = (Operands[2]->isImm()) ? 2 : 3;
6668 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
6669 return Error(Operands[Op]->getStartLoc(),
"branch target out of range");
6674 if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<6, 1>())
6675 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6680 case ARM::t2MOVTi16:
6688 int i = (Operands[3]->isImm()) ? 3 : 4;
6689 ARMOperand &Op =
static_cast<ARMOperand &
>(*Operands[
i]);
6699 "immediate expression for mov requires :lower16: or :upper16");
6709 return Error(Operands[1]->getStartLoc(),
"instruction 'esb' is not "
6710 "predicable, but condition "
6725 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6726 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6727 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6728 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6729 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6730 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6731 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
6732 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
6733 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
6736 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6737 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6738 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6739 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6740 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6742 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6743 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6744 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6745 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6746 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6748 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
6749 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
6750 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
6751 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
6752 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
6755 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6756 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6757 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6758 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
6759 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6760 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6761 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6762 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6763 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
6764 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6765 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
6766 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
6767 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
6768 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
6769 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
6772 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6773 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6774 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6775 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6776 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6777 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6778 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6779 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6780 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6781 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6782 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6783 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6784 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
6785 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
6786 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
6787 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
6788 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
6789 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
6792 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6793 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6794 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6795 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
6796 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6797 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6798 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6799 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6800 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
6801 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6802 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
6803 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
6804 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
6805 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
6806 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
6809 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6810 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6811 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6812 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6813 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6814 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
6815 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6816 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6817 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6818 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6819 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6820 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
6821 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
6822 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
6823 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
6824 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
6825 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
6826 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
6834 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
6835 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
6836 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
6837 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
6838 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
6839 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
6840 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
6841 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
6842 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
6845 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
6846 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
6847 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
6848 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
6849 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
6850 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
6851 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
6852 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
6853 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
6854 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
6855 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
6856 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
6857 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
6858 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
6859 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
6862 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
6863 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
6864 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
6865 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
6866 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
6867 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
6868 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
6869 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
6870 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
6871 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
6872 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
6873 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
6874 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
6875 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
6876 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
6877 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
6878 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
6879 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
6882 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
6883 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
6884 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
6885 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
6886 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
6887 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
6888 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
6889 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
6890 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
6891 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
6892 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
6893 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
6894 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
6895 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
6896 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
6899 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
6900 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
6901 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
6902 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
6903 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
6904 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
6905 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
6906 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
6907 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
6908 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
6909 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
6910 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
6911 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
6912 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
6913 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
6914 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
6915 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
6916 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
6919 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
6920 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
6921 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
6922 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
6923 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
6924 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
6925 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
6926 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
6927 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
6928 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
6929 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
6930 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
6931 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
6932 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
6933 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
6936 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
6937 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
6938 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
6939 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
6940 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
6941 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
6942 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
6943 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
6944 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
6945 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
6946 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
6947 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
6948 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
6949 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
6950 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
6951 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
6952 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
6953 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
6956 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
6957 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
6958 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
6959 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
6960 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
6961 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
6962 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
6963 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
6964 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
6965 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
6966 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
6967 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
6968 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
6969 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
6970 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
6971 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
6972 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
6973 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
6977 bool ARMAsmParser::processInstruction(
MCInst &Inst,
6982 case ARM::LDRT_POST:
6983 case ARM::LDRBT_POST: {
6984 const unsigned Opcode =
6985 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
6986 : ARM::LDRBT_POST_IMM;
7000 case ARM::STRT_POST:
7001 case ARM::STRBT_POST: {
7002 const unsigned Opcode =
7003 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
7004 : ARM::STRBT_POST_IMM;
7036 MCSymbol *Dot = getContext().createTempSymbol();
7055 case ARM::t2LDRpcrel:
7059 !(
static_cast<ARMOperand &
>(*Operands[2]).isToken() &&
7060 static_cast<ARMOperand &
>(*Operands[2]).
getToken() ==
".w"))
7065 case ARM::t2LDRBpcrel:
7068 case ARM::t2LDRHpcrel:
7071 case ARM::t2LDRSBpcrel:
7074 case ARM::t2LDRSHpcrel:
7077 case ARM::LDRConstPool:
7078 case ARM::tLDRConstPool:
7079 case ARM::t2LDRConstPool: {
7084 if (Inst.
getOpcode() == ARM::LDRConstPool)
7086 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
7088 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
7090 const ARMOperand &PoolOperand =
7091 (
static_cast<ARMOperand &
>(*Operands[2]).isToken() &&
7092 static_cast<ARMOperand &
>(*Operands[2]).
getToken() ==
".w") ?
7093 static_cast<ARMOperand &>(*Operands[4]) :
7094 static_cast<ARMOperand &
>(*Operands[3]);
7095 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
7097 if (isa<MCConstantExpr>(SubExprVal) &&
7101 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
7103 bool MovHasS =
true;
7104 if (Inst.
getOpcode() == ARM::LDRConstPool) {
7114 else if (hasV6T2Ops() &&
7115 Value >=0 && Value < 65536) {
7127 else if (hasThumb2() &&
7132 else if (hasV8MBaseline() &&
7133 Value >=0 && Value < 65536) {
7153 getTargetStreamer().addConstantPoolEntry(SubExprVal,
7154 PoolOperand.getStartLoc());
7165 case ARM::VST1LNdWB_register_Asm_8:
7166 case ARM::VST1LNdWB_register_Asm_16:
7167 case ARM::VST1LNdWB_register_Asm_32: {
7185 case ARM::VST2LNdWB_register_Asm_8:
7186 case ARM::VST2LNdWB_register_Asm_16:
7187 case ARM::VST2LNdWB_register_Asm_32:
7188 case ARM::VST2LNqWB_register_Asm_16:
7189 case ARM::VST2LNqWB_register_Asm_32: {
7209 case ARM::VST3LNdWB_register_Asm_8:
7210 case ARM::VST3LNdWB_register_Asm_16:
7211 case ARM::VST3LNdWB_register_Asm_32:
7212 case ARM::VST3LNqWB_register_Asm_16:
7213 case ARM::VST3LNqWB_register_Asm_32: {
7235 case ARM::VST4LNdWB_register_Asm_8:
7236 case ARM::VST4LNdWB_register_Asm_16:
7237 case ARM::VST4LNdWB_register_Asm_32:
7238 case ARM::VST4LNqWB_register_Asm_16:
7239 case ARM::VST4LNqWB_register_Asm_32: {
7263 case ARM::VST1LNdWB_fixed_Asm_8:
7264 case ARM::VST1LNdWB_fixed_Asm_16:
7265 case ARM::VST1LNdWB_fixed_Asm_32: {
7283 case ARM::VST2LNdWB_fixed_Asm_8:
7284 case ARM::VST2LNdWB_fixed_Asm_16:
7285 case ARM::VST2LNdWB_fixed_Asm_32:
7286 case ARM::VST2LNqWB_fixed_Asm_16:
7287 case ARM::VST2LNqWB_fixed_Asm_32: {
7307 case ARM::VST3LNdWB_fixed_Asm_8:
7308 case ARM::VST3LNdWB_fixed_Asm_16:
7309 case ARM::VST3LNdWB_fixed_Asm_32:
7310 case ARM::VST3LNqWB_fixed_Asm_16:
7311 case ARM::VST3LNqWB_fixed_Asm_32: {
7333 case ARM::VST4LNdWB_fixed_Asm_8:
7334 case ARM::VST4LNdWB_fixed_Asm_16:
7335 case ARM::VST4LNdWB_fixed_Asm_32:
7336 case ARM::VST4LNqWB_fixed_Asm_16:
7337 case ARM::VST4LNqWB_fixed_Asm_32: {
7361 case ARM::VST1LNdAsm_8:
7362 case ARM::VST1LNdAsm_16:
7363 case ARM::VST1LNdAsm_32: {
7379 case ARM::VST2LNdAsm_8:
7380 case ARM::VST2LNdAsm_16:
7381 case ARM::VST2LNdAsm_32:
7382 case ARM::VST2LNqAsm_16:
7383 case ARM::VST2LNqAsm_32: {
7401 case ARM::VST3LNdAsm_8:
7402 case ARM::VST3LNdAsm_16:
7403 case ARM::VST3LNdAsm_32:
7404 case ARM::VST3LNqAsm_16:
7405 case ARM::VST3LNqAsm_32: {
7425 case ARM::VST4LNdAsm_8:
7426 case ARM::VST4LNdAsm_16:
7427 case ARM::VST4LNdAsm_32:
7428 case ARM::VST4LNqAsm_16:
7429 case ARM::VST4LNqAsm_32: {
7452 case ARM::VLD1LNdWB_register_Asm_8:
7453 case ARM::VLD1LNdWB_register_Asm_16:
7454 case ARM::VLD1LNdWB_register_Asm_32: {
7473 case ARM::VLD2LNdWB_register_Asm_8:
7474 case ARM::VLD2LNdWB_register_Asm_16:
7475 case ARM::VLD2LNdWB_register_Asm_32:
7476 case ARM::VLD2LNqWB_register_Asm_16:
7477 case ARM::VLD2LNqWB_register_Asm_32: {
7500 case ARM::VLD3LNdWB_register_Asm_8:
7501 case ARM::VLD3LNdWB_register_Asm_16:
7502 case ARM::VLD3LNdWB_register_Asm_32:
7503 case ARM::VLD3LNqWB_register_Asm_16:
7504 case ARM::VLD3LNqWB_register_Asm_32: {
7531 case ARM::VLD4LNdWB_register_Asm_8:
7532 case ARM::VLD4LNdWB_register_Asm_16:
7533 case ARM::VLD4LNdWB_register_Asm_32:
7534 case ARM::VLD4LNqWB_register_Asm_16:
7535 case ARM::VLD4LNqWB_register_Asm_32: {
7566 case ARM::VLD1LNdWB_fixed_Asm_8:
7567 case ARM::VLD1LNdWB_fixed_Asm_16:
7568 case ARM::VLD1LNdWB_fixed_Asm_32: {
7587 case ARM::VLD2LNdWB_fixed_Asm_8:
7588 case ARM::VLD2LNdWB_fixed_Asm_16:
7589 case ARM::VLD2LNdWB_fixed_Asm_32:
7590 case ARM::VLD2LNqWB_fixed_Asm_16:
7591 case ARM::VLD2LNqWB_fixed_Asm_32: {
7614 case ARM::VLD3LNdWB_fixed_Asm_8:
7615 case ARM::VLD3LNdWB_fixed_Asm_16:
7616 case ARM::VLD3LNdWB_fixed_Asm_32:
7617 case ARM::VLD3LNqWB_fixed_Asm_16:
7618 case ARM::VLD3LNqWB_fixed_Asm_32: {
7645 case ARM::VLD4LNdWB_fixed_Asm_8:
7646 case ARM::VLD4LNdWB_fixed_Asm_16:
7647 case ARM::VLD4LNdWB_fixed_Asm_32:
7648 case ARM::VLD4LNqWB_fixed_Asm_16:
7649 case ARM::VLD4LNqWB_fixed_Asm_32: {
7680 case ARM::VLD1LNdAsm_8:
7681 case ARM::VLD1LNdAsm_16:
7682 case ARM::VLD1LNdAsm_32: {
7699 case ARM::VLD2LNdAsm_8:
7700 case ARM::VLD2LNdAsm_16:
7701 case ARM::VLD2LNdAsm_32:
7702 case ARM::VLD2LNqAsm_16:
7703 case ARM::VLD2LNqAsm_32: {
7724 case ARM::VLD3LNdAsm_8:
7725 case ARM::VLD3LNdAsm_16:
7726 case ARM::VLD3LNdAsm_32:
7727 case ARM::VLD3LNqAsm_16:
7728 case ARM::VLD3LNqAsm_32: {
7753 case ARM::VLD4LNdAsm_8:
7754 case ARM::VLD4LNdAsm_16:
7755 case ARM::VLD4LNdAsm_32:
7756 case ARM::VLD4LNqAsm_16:
7757 case ARM::VLD4LNqAsm_32: {
7787 case ARM::VLD3DUPdAsm_8:
7788 case ARM::VLD3DUPdAsm_16:
7789 case ARM::VLD3DUPdAsm_32:
7790 case ARM::VLD3DUPqAsm_8:
7791 case ARM::VLD3DUPqAsm_16:
7792 case ARM::VLD3DUPqAsm_32: {
7809 case ARM::VLD3DUPdWB_fixed_Asm_8:
7810 case ARM::VLD3DUPdWB_fixed_Asm_16:
7811 case ARM::VLD3DUPdWB_fixed_Asm_32:
7812 case ARM::VLD3DUPqWB_fixed_Asm_8:
7813 case ARM::VLD3DUPqWB_fixed_Asm_16:
7814 case ARM::VLD3DUPqWB_fixed_Asm_32: {
7833 case ARM::VLD3DUPdWB_register_Asm_8:
7834 case ARM::VLD3DUPdWB_register_Asm_16:
7835 case ARM::VLD3DUPdWB_register_Asm_32:
7836 case ARM::VLD3DUPqWB_register_Asm_8:
7837 case ARM::VLD3DUPqWB_register_Asm_16:
7838 case ARM::VLD3DUPqWB_register_Asm_32: {
7858 case ARM::VLD3dAsm_8:
7859 case ARM::VLD3dAsm_16:
7860 case ARM::VLD3dAsm_32:
7861 case ARM::VLD3qAsm_8:
7862 case ARM::VLD3qAsm_16:
7863 case ARM::VLD3qAsm_32: {
7880 case ARM::VLD3dWB_fixed_Asm_8:
7881 case ARM::VLD3dWB_fixed_Asm_16:
7882 case ARM::VLD3dWB_fixed_Asm_32:
7883 case ARM::VLD3qWB_fixed_Asm_8:
7884 case ARM::VLD3qWB_fixed_Asm_16:
7885 case ARM::VLD3qWB_fixed_Asm_32: {
7904 case ARM::VLD3dWB_register_Asm_8:
7905 case ARM::VLD3dWB_register_Asm_16:
7906 case ARM::VLD3dWB_register_Asm_32:
7907 case ARM::VLD3qWB_register_Asm_8:
7908 case ARM::VLD3qWB_register_Asm_16:
7909 case ARM::VLD3qWB_register_Asm_32: {
7929 case ARM::VLD4DUPdAsm_8:
7930 case ARM::VLD4DUPdAsm_16:
7931 case ARM::VLD4DUPdAsm_32:
7932 case ARM::VLD4DUPqAsm_8:
7933 case ARM::VLD4DUPqAsm_16:
7934 case ARM::VLD4DUPqAsm_32: {
7953 case ARM::VLD4DUPdWB_fixed_Asm_8:
7954 case ARM::VLD4DUPdWB_fixed_Asm_16:
7955 case ARM::VLD4DUPdWB_fixed_Asm_32:
7956 case ARM::VLD4DUPqWB_fixed_Asm_8:
7957 case ARM::VLD4DUPqWB_fixed_Asm_16:
7958 case ARM::VLD4DUPqWB_fixed_Asm_32: {
7979 case ARM::VLD4DUPdWB_register_Asm_8:
7980 case ARM::VLD4DUPdWB_register_Asm_16:
7981 case ARM::VLD4DUPdWB_register_Asm_32:
7982 case ARM::VLD4DUPqWB_register_Asm_8:
7983 case ARM::VLD4DUPqWB_register_Asm_16:
7984 case ARM::VLD4DUPqWB_register_Asm_32: {
8006 case ARM::VLD4dAsm_8:
8007 case ARM::VLD4dAsm_16:
8008 case ARM::VLD4dAsm_32:
8009 case ARM::VLD4qAsm_8:
8010 case ARM::VLD4qAsm_16:
8011 case ARM::VLD4qAsm_32: {
8030 case ARM::VLD4dWB_fixed_Asm_8:
8031 case ARM::VLD4dWB_fixed_Asm_16:
8032 case ARM::VLD4dWB_fixed_Asm_32:
8033 case ARM::VLD4qWB_fixed_Asm_8:
8034 case ARM::VLD4qWB_fixed_Asm_16:
8035 case ARM::VLD4qWB_fixed_Asm_32: {
8056 case ARM::VLD4dWB_register_Asm_8:
8057 case ARM::VLD4dWB_register_Asm_16:
8058 case ARM::VLD4dWB_register_Asm_32:
8059 case ARM::VLD4qWB_register_Asm_8:
8060 case ARM::VLD4qWB_register_Asm_16:
8061 case ARM::VLD4qWB_register_Asm_32: {
8083 case ARM::VST3dAsm_8:
8084 case ARM::VST3dAsm_16:
8085 case ARM::VST3dAsm_32:
8086 case ARM::VST3qAsm_8:
8087 case ARM::VST3qAsm_16:
8088 case ARM::VST3qAsm_32: {
8105 case ARM::VST3dWB_fixed_Asm_8:
8106 case ARM::VST3dWB_fixed_Asm_16:
8107 case ARM::VST3dWB_fixed_Asm_32:
8108 case ARM::VST3qWB_fixed_Asm_8:
8109 case ARM::VST3qWB_fixed_Asm_16:
8110 case ARM::VST3qWB_fixed_Asm_32: {
8129 case ARM::VST3dWB_register_Asm_8:
8130 case ARM::VST3dWB_register_Asm_16:
8131 case ARM::VST3dWB_register_Asm_32:
8132 case ARM::VST3qWB_register_Asm_8:
8133 case ARM::VST3qWB_register_Asm_16:
8134 case ARM::VST3qWB_register_Asm_32: {
8154 case ARM::VST4dAsm_8:
8155 case ARM::VST4dAsm_16:
8156 case ARM::VST4dAsm_32:
8157 case ARM::VST4qAsm_8:
8158 case ARM::VST4qAsm_16:
8159 case ARM::VST4qAsm_32: {
8178 case ARM::VST4dWB_fixed_Asm_8:
8179 case ARM::VST4dWB_fixed_Asm_16:
8180 case ARM::VST4dWB_fixed_Asm_32:
8181 case ARM::VST4qWB_fixed_Asm_8:
8182 case ARM::VST4qWB_fixed_Asm_16:
8183 case ARM::VST4qWB_fixed_Asm_32: {
8204 case ARM::VST4dWB_register_Asm_8:
8205 case ARM::VST4dWB_register_Asm_16:
8206 case ARM::VST4dWB_register_Asm_32:
8207 case ARM::VST4qWB_register_Asm_8:
8208 case ARM::VST4qWB_register_Asm_16:
8209 case ARM::VST4qWB_register_Asm_32: {
8233 case ARM::t2ASRri: {
8237 !(static_cast<ARMOperand &>(*Operands[3]).isToken() &&
8238 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
".w")) {
8242 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
8243 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
8244 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
8263 case ARM::t2MOVSsr: {
8267 bool isNarrow =
false;
8272 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr))
8278 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
8279 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
8280 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
8281 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
8287 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
8294 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
8299 case ARM::t2MOVSsi: {
8303 bool isNarrow =
false;
8306 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi))
8312 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
8313 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
8314 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
8315 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
8316 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
8319 if (Amount == 32) Amount = 0;
8324 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8326 if (newOpc != ARM::t2RRX)
8332 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8376 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
8385 if (Opc == ARM::MOVsi)
8406 case ARM::t2LDMIA_UPD: {
8422 case ARM::t2STMDB_UPD: {
8438 case ARM::LDMIA_UPD:
8441 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"pop" &&
8456 case ARM::STMDB_UPD:
8459 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"push" &&
8472 case ARM::t2ADDri12:
8475 if (static_cast<ARMOperand &>(*Operands[0]).getToken() !=
"add" ||
8481 case ARM::t2SUBri12:
8484 if (static_cast<ARMOperand &>(*Operands[0]).
getToken() !=
"sub" ||
8511 case ARM::t2SUBri: {
8518 (
unsigned)Inst.getOperand(2).getImm() > 255 ||
8519 ((!inITBlock() && Inst.getOperand(5).
getReg() != ARM::CPSR) ||
8520 (inITBlock() && Inst.getOperand(5).
getReg() != 0)) ||
8521 (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
8522 static_cast<ARMOperand &>(*Operands[3]).
getToken() == ".w"))
8525 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
8526 ARM::tADDi8 : ARM::tSUBi8);
8536 case ARM::t2ADDrr: {
8551 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
8552 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
".w"))
8564 case ARM::tADDrSP: {
8608 bool hasWritebackToken =
8609 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
8610 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
8611 bool listContainsBase;
8613 (!listContainsBase && !hasWritebackToken) ||
8614 (listContainsBase && hasWritebackToken)) {
8617 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
8620 if (hasWritebackToken)
8627 case ARM::tSTMIA_UPD: {
8632 bool listContainsBase;
8642 bool listContainsBase;
8656 bool listContainsBase;
8674 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8675 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8696 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8697 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8719 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8720 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8724 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
8725 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
8726 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
8727 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
8771 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
8772 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
8773 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
8774 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
8775 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
8776 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
8798 unsigned Mask = MO.
getImm();
8803 assert(!inITBlock() &&
"nested IT blocks?!");
8804 startExplicitITBlock(Cond, Mask);
8805 MO.
setImm(getITMaskEncoding());
8821 (!
static_cast<ARMOperand &
>(*Operands[3]).isToken() ||
8822 !
static_cast<ARMOperand &
>(*Operands[3]).
getToken().equals_lower(
8827 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
8828 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
8829 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
8830 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
8831 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
8832 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
8861 (!
static_cast<ARMOperand &
>(*Operands[3]).isToken() ||
8862 !
static_cast<ARMOperand &
>(*Operands[3]).
getToken().equals_lower(
8867 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
8868 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
8869 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
8870 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
8894 unsigned ARMAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
8901 "optionally flag setting instruction missing optional def operand");
8903 "operand count mismatch!");
8912 return Match_RequiresFlagSetting;
8917 return Match_RequiresITBlock;
8920 return Match_RequiresNotITBlock;
8921 }
else if (isThumbOne()) {
8924 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
8927 return Match_RequiresThumb2;
8929 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
8932 return Match_RequiresV6;
8939 return Match_RequiresV8;
8941 return Match_InvalidOperand;
8944 return Match_Success;
8955 bool ARMAsmParser::isITBlockTerminator(
MCInst &Inst)
const {
8965 for (
unsigned OpIdx = 0; OpIdx < MCID.
getNumDefs(); ++OpIdx) {
8979 case ARM::t2LDMIA_UPD:
8981 case ARM::t2LDMDB_UPD:
8996 bool MatchingInlineAsm,
8997 bool &EmitInITBlock,
9000 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
9001 return MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
9005 if (inImplicitITBlock()) {
9006 extendImplicitITBlock(ITState.Cond);
9007 if (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm) ==
9017 if (InstCond == ITCond) {
9018 EmitInITBlock =
true;
9019 return Match_Success;
9021 invertCurrentITCondition();
9022 EmitInITBlock =
true;
9023 return Match_Success;
9027 rewindImplicitITPosition();
9031 flushPendingInstructions(Out);
9032 unsigned PlainMatchResult =
9033 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
9034 if (PlainMatchResult == Match_Success) {
9043 EmitInITBlock =
false;
9044 return Match_Success;
9047 EmitInITBlock =
false;
9048 return Match_Success;
9051 EmitInITBlock =
false;
9052 return Match_Success;
9059 startImplicitITBlock();
9060 if (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm) ==
9067 EmitInITBlock =
true;
9068 return Match_Success;
9071 discardImplicitITBlock();
9075 EmitInITBlock =
false;
9076 return PlainMatchResult;
9080 bool ARMAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
9083 bool MatchingInlineAsm) {
9085 unsigned MatchResult;
9086 bool PendConditionalInstruction =
false;
9088 MatchResult = MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
9089 PendConditionalInstruction, Out);
9091 switch (MatchResult) {
9095 if (validateInstruction(Inst, Operands)) {
9098 forwardITPosition();
9103 bool wasInITBlock = inITBlock();
9109 while (processInstruction(Inst, Operands, Out))
9113 if (wasInITBlock && hasV8Ops() &&
isThumb() &&
9115 Warning(IDLoc,
"deprecated instruction in IT block");
9122 forwardITPosition();
9130 if (PendConditionalInstruction) {
9131 PendingConditionalInsts.push_back(Inst);
9132 if (isITBlockFull() || isITBlockTerminator(Inst))
9133 flushPendingInstructions(Out);
9138 case Match_MissingFeature: {
9139 assert(ErrorInfo &&
"Unknown missing feature!");
9142 std::string Msg =
"instruction requires:";
9144 for (
unsigned i = 0; i < (
sizeof(ErrorInfo)*8-1); ++
i) {
9145 if (ErrorInfo & Mask) {
9151 return Error(IDLoc, Msg);
9153 case Match_InvalidOperand: {
9154 SMLoc ErrorLoc = IDLoc;
9155 if (ErrorInfo != ~0ULL) {
9156 if (ErrorInfo >= Operands.
size())
9157 return Error(IDLoc,
"too few operands for instruction");
9159 ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
9160 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
9163 return Error(ErrorLoc,
"invalid operand for instruction");
9165 case Match_MnemonicFail:
9166 return Error(IDLoc,
"invalid instruction",
9167 ((ARMOperand &)*Operands[0]).getLocRange());
9168 case Match_RequiresNotITBlock:
9169 return Error(IDLoc,
"flag setting instruction only valid outside IT block");
9170 case Match_RequiresITBlock:
9171 return Error(IDLoc,
"instruction only valid inside IT block");
9172 case Match_RequiresV6:
9173 return Error(IDLoc,
"instruction variant requires ARMv6 or later");
9174 case Match_RequiresThumb2:
9175 return Error(IDLoc,
"instruction variant requires Thumb2");
9176 case Match_RequiresV8:
9177 return Error(IDLoc,
"instruction variant requires ARMv8 or later");
9178 case Match_RequiresFlagSetting:
9179 return Error(IDLoc,
"no flag-preserving variant of this instruction available");
9180 case Match_ImmRange0_15: {
9181 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
9182 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
9183 return Error(ErrorLoc,
"immediate operand must be in the range [0,15]");
9185 case Match_ImmRange0_239: {
9186 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
9187 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
9188 return Error(ErrorLoc,
"immediate operand must be in the range [0,239]");
9190 case Match_AlignedMemoryRequiresNone:
9191 case Match_DupAlignedMemoryRequiresNone:
9192 case Match_AlignedMemoryRequires16:
9193 case Match_DupAlignedMemoryRequires16:
9194 case Match_AlignedMemoryRequires32:
9195 case Match_DupAlignedMemoryRequires32:
9196 case Match_AlignedMemoryRequires64:
9197 case Match_DupAlignedMemoryRequires64:
9198 case Match_AlignedMemoryRequires64or128:
9199 case Match_DupAlignedMemoryRequires64or128:
9200 case Match_AlignedMemoryRequires64or128or256:
9202 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getAlignmentLoc();
9203 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
9204 switch (MatchResult) {
9207 case Match_AlignedMemoryRequiresNone:
9208 case Match_DupAlignedMemoryRequiresNone:
9209 return Error(ErrorLoc,
"alignment must be omitted");
9210 case Match_AlignedMemoryRequires16:
9211 case Match_DupAlignedMemoryRequires16:
9212 return Error(ErrorLoc,
"alignment must be 16 or omitted");
9213 case Match_AlignedMemoryRequires32:
9214 case Match_DupAlignedMemoryRequires32:
9215 return Error(ErrorLoc,
"alignment must be 32 or omitted");
9216 case Match_AlignedMemoryRequires64:
9217 case Match_DupAlignedMemoryRequires64:
9218 return Error(ErrorLoc,
"alignment must be 64 or omitted");
9219 case Match_AlignedMemoryRequires64or128:
9220 case Match_DupAlignedMemoryRequires64or128:
9221 return Error(ErrorLoc,
"alignment must be 64, 128 or omitted");
9222 case Match_AlignedMemoryRequires64or128or256:
9223 return Error(ErrorLoc,
"alignment must be 64, 128, 256 or omitted");
9232 bool ARMAsmParser::ParseDirective(
AsmToken DirectiveID) {
9234 getContext().getObjectFileInfo()->getObjectFileType();
9239 if (IDVal ==
".word")
9240 parseLiteralValues(4, DirectiveID.
getLoc());
9241 else if (IDVal ==
".short" || IDVal ==
".hword")
9242 parseLiteralValues(2, DirectiveID.
getLoc());
9243 else if (IDVal ==
".thumb")
9244 parseDirectiveThumb(DirectiveID.
getLoc());
9245 else if (IDVal ==
".arm")
9246 parseDirectiveARM(DirectiveID.
getLoc());
9247 else if (IDVal ==
".thumb_func")
9248 parseDirectiveThumbFunc(DirectiveID.
getLoc());
9249 else if (IDVal ==
".code")
9250 parseDirectiveCode(DirectiveID.
getLoc());
9251 else if (IDVal ==
".syntax")
9252 parseDirectiveSyntax(DirectiveID.
getLoc());
9253 else if (IDVal ==
".unreq")
9254 parseDirectiveUnreq(DirectiveID.
getLoc());
9255 else if (IDVal ==
".fnend")
9256 parseDirectiveFnEnd(DirectiveID.
getLoc());
9257 else if (IDVal ==
".cantunwind")
9258 parseDirectiveCantUnwind(DirectiveID.
getLoc());
9259 else if (IDVal ==
".personality")
9260 parseDirectivePersonality(DirectiveID.
getLoc());
9261 else if (IDVal ==
".handlerdata")
9262 parseDirectiveHandlerData(DirectiveID.
getLoc());
9263 else if (IDVal ==
".setfp")
9264 parseDirectiveSetFP(DirectiveID.
getLoc());
9265 else if (IDVal ==
".pad")
9266 parseDirectivePad(DirectiveID.
getLoc());
9267 else if (IDVal ==
".save")
9268 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
9269 else if (IDVal ==
".vsave")
9270 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
9271 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
9272 parseDirectiveLtorg(DirectiveID.
getLoc());
9273 else if (IDVal ==
".even")
9274 parseDirectiveEven(DirectiveID.
getLoc());
9275 else if (IDVal ==
".personalityindex")
9276 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
9277 else if (IDVal ==
".unwind_raw")
9278 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
9279 else if (IDVal ==
".movsp")
9280 parseDirectiveMovSP(DirectiveID.
getLoc());
9281 else if (IDVal ==
".arch_extension")
9282 parseDirectiveArchExtension(DirectiveID.
getLoc());
9283 else if (IDVal ==
".align")
9284 return parseDirectiveAlign(DirectiveID.
getLoc());
9285 else if (IDVal ==
".thumb_set")
9286 parseDirectiveThumbSet(DirectiveID.
getLoc());
9287 else if (!IsMachO && !IsCOFF) {
9288 if (IDVal ==
".arch")
9289 parseDirectiveArch(DirectiveID.
getLoc());
9290 else if (IDVal ==
".cpu")
9291 parseDirectiveCPU(DirectiveID.
getLoc());
9292 else if (IDVal ==
".eabi_attribute")
9293 parseDirectiveEabiAttr(DirectiveID.
getLoc());
9294 else if (IDVal ==
".fpu")
9295 parseDirectiveFPU(DirectiveID.
getLoc());
9296 else if (IDVal ==
".fnstart")
9297 parseDirectiveFnStart(DirectiveID.
getLoc());
9298 else if (IDVal ==
".inst")
9299 parseDirectiveInst(DirectiveID.
getLoc());
9300 else if (IDVal ==
".inst.n")
9301 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
9302 else if (IDVal ==
".inst.w")
9303 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
9304 else if (IDVal ==
".object_arch")
9305 parseDirectiveObjectArch(DirectiveID.
getLoc());
9306 else if (IDVal ==
".tlsdescseq")
9307 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
9319 bool ARMAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
9320 auto parseOne = [&]() ->
bool {
9322 if (getParser().parseExpression(Value))
9324 getParser().getStreamer().EmitValue(Value, Size, L);
9327 return (parseMany(parseOne));
9332 bool ARMAsmParser::parseDirectiveThumb(
SMLoc L) {
9334 check(!hasThumb(), L,
"target does not support Thumb mode"))
9340 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
9346 bool ARMAsmParser::parseDirectiveARM(
SMLoc L) {
9348 check(!hasARM(), L,
"target does not support ARM mode"))
9353 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
9360 flushPendingInstructions(getStreamer());
9361 if (NextSymbolIsThumb) {
9362 getParser().getStreamer().EmitThumbFunc(Symbol);
9363 NextSymbolIsThumb =
false;
9369 bool ARMAsmParser::parseDirectiveThumbFunc(
SMLoc L) {
9371 const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
9380 MCSymbol *
Func = getParser().getContext().getOrCreateSymbol(
9382 getParser().getStreamer().EmitThumbFunc(Func);
9385 "unexpected token in '.thumb_func' directive"))
9392 "unexpected token in '.thumb_func' directive"))
9395 NextSymbolIsThumb =
true;
9401 bool ARMAsmParser::parseDirectiveSyntax(
SMLoc L) {
9405 Error(L,
"unexpected token in .syntax directive");
9411 if (check(Mode ==
"divided" || Mode ==
"DIVIDED", L,
9412 "'.syntax divided' arm assembly not supported") ||
9413 check(Mode !=
"unified" && Mode !=
"UNIFIED", L,
9414 "unrecognized syntax mode in .syntax directive") ||
9425 bool ARMAsmParser::parseDirectiveCode(
SMLoc L) {
9429 return Error(L,
"unexpected token in .code directive");
9431 if (Val != 16 && Val != 32) {
9432 Error(L,
"invalid operand to .code directive");
9442 return Error(L,
"target does not support Thumb mode");
9446 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
9449 return Error(L,
"target does not support ARM mode");
9453 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
9465 SMLoc SRegLoc, ERegLoc;
9466 if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc,
9467 "register name expected") ||
9469 "unexpected input in .req directive."))
9472 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second !=
Reg)
9473 return Error(SRegLoc,
9474 "redefinition of '" + Name +
"' does not match original.");
9481 bool ARMAsmParser::parseDirectiveUnreq(
SMLoc L) {
9484 return Error(L,
"unexpected input in .unreq directive.");
9488 "unexpected input in '.unreq' directive"))
9496 void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc) {
9498 if (WasThumb && hasThumb()) {
9501 }
else if (!WasThumb && hasARM()) {
9511 Warning(Loc,
Twine(
"new target does not support ") +
9512 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
9513 (!WasThumb ?
"thumb" :
"arm") +
" mode");
9520 bool ARMAsmParser::parseDirectiveArch(
SMLoc L) {
9521 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
9524 if (ID == ARM::AK_INVALID)
9525 return Error(L,
"Unknown arch name");
9531 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9532 FixModeAfterArchChange(WasThumb, L);
9534 getTargetStreamer().emitArch(ID);
9541 bool ARMAsmParser::parseDirectiveEabiAttr(
SMLoc L) {
9550 Error(TagLoc,
"attribute name not recognised: " + Name);
9562 if (check(!CE, TagLoc,
"expected numeric constant"))
9572 bool IsStringValue =
false;
9574 int64_t IntegerValue = 0;
9575 bool IsIntegerValue =
false;
9578 IsStringValue =
true;
9580 IsStringValue =
true;
9581 IsIntegerValue =
true;
9582 }
else if (Tag < 32 || Tag % 2 == 0)
9583 IsIntegerValue =
true;
9584 else if (Tag % 2 == 1)
9585 IsStringValue =
true;
9589 if (IsIntegerValue) {
9597 return Error(ValueExprLoc,
"expected numeric constant");
9606 if (IsStringValue) {
9615 "unexpected token in '.eabi_attribute' directive"))
9618 if (IsIntegerValue && IsStringValue) {
9620 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
9621 }
else if (IsIntegerValue)
9622 getTargetStreamer().emitAttribute(Tag, IntegerValue);
9623 else if (IsStringValue)
9624 getTargetStreamer().emitTextAttribute(Tag, StringValue);
9630 bool ARMAsmParser::parseDirectiveCPU(
SMLoc L) {
9631 StringRef CPU = getParser().parseStringToEndOfStatement().
trim();
9636 if (!getSTI().isCPUStringValid(CPU))
9637 return Error(L,
"Unknown CPU name");
9642 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9643 FixModeAfterArchChange(WasThumb, L);
9649 bool ARMAsmParser::parseDirectiveFPU(
SMLoc L) {
9650 SMLoc FPUNameLoc = getTok().getLoc();
9651 StringRef FPU = getParser().parseStringToEndOfStatement().
trim();
9656 return Error(FPUNameLoc,
"Unknown FPU name");
9659 for (
auto Feature : Features)
9661 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9663 getTargetStreamer().emitFPU(ID);
9669 bool ARMAsmParser::parseDirectiveFnStart(
SMLoc L) {
9671 "unexpected token in '.fnstart' directive"))
9674 if (UC.hasFnStart()) {
9675 Error(L,
".fnstart starts before the end of previous one");
9676 UC.emitFnStartLocNotes();
9683 getTargetStreamer().emitFnStart();
9685 UC.recordFnStart(L);
9691 bool ARMAsmParser::parseDirectiveFnEnd(
SMLoc L) {
9693 "unexpected token in '.fnend' directive"))
9696 if (!UC.hasFnStart())
9697 return Error(L,
".fnstart must precede .fnend directive");
9700 getTargetStreamer().emitFnEnd();
9708 bool ARMAsmParser::parseDirectiveCantUnwind(
SMLoc L) {
9710 "unexpected token in '.cantunwind' directive"))
9713 UC.recordCantUnwind(L);
9715 if (check(!UC.hasFnStart(),
L,
".fnstart must precede .cantunwind directive"))
9718 if (UC.hasHandlerData()) {
9719 Error(L,
".cantunwind can't be used with .handlerdata directive");
9720 UC.emitHandlerDataLocNotes();
9723 if (UC.hasPersonality()) {
9724 Error(L,
".cantunwind can't be used with .personality directive");
9725 UC.emitPersonalityLocNotes();
9729 getTargetStreamer().emitCantUnwind();
9735 bool ARMAsmParser::parseDirectivePersonality(
SMLoc L) {
9737 bool HasExistingPersonality = UC.hasPersonality();
9741 return Error(L,
"unexpected input in .personality directive.");
9746 "unexpected token in '.personality' directive"))
9749 UC.recordPersonality(L);
9752 if (!UC.hasFnStart())
9753 return Error(L,
".fnstart must precede .personality directive");
9754 if (UC.cantUnwind()) {
9755 Error(L,
".personality can't be used with .cantunwind directive");
9756 UC.emitCantUnwindLocNotes();
9759 if (UC.hasHandlerData()) {
9760 Error(L,
".personality must precede .handlerdata directive");
9761 UC.emitHandlerDataLocNotes();
9764 if (HasExistingPersonality) {
9765 Error(L,
"multiple personality directives");
9766 UC.emitPersonalityLocNotes();
9770 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
9771 getTargetStreamer().emitPersonality(PR);
9777 bool ARMAsmParser::parseDirectiveHandlerData(
SMLoc L) {
9779 "unexpected token in '.handlerdata' directive"))
9782 UC.recordHandlerData(L);
9784 if (!UC.hasFnStart())
9785 return Error(L,
".fnstart must precede .personality directive");
9786 if (UC.cantUnwind()) {
9787 Error(L,
".handlerdata can't be used with .cantunwind directive");
9788 UC.emitCantUnwindLocNotes();
9792 getTargetStreamer().emitHandlerData();
9798 bool ARMAsmParser::parseDirectiveSetFP(
SMLoc L) {
9801 if (check(!UC.hasFnStart(),
L,
".fnstart must precede .setfp directive") ||
9802 check(UC.hasHandlerData(),
L,
9803 ".setfp must precede .handlerdata directive"))
9808 int FPReg = tryParseRegister();
9810 if (check(FPReg == -1, FPRegLoc,
"frame pointer register expected") ||
9816 int SPReg = tryParseRegister();
9817 if (check(SPReg == -1, SPRegLoc,
"stack pointer register expected") ||
9818 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
9819 "register should be either $sp or the latest fp register"))
9823 UC.saveFPReg(FPReg);
9833 const MCExpr *OffsetExpr;
9836 if (getParser().parseExpression(OffsetExpr, EndLoc))
9837 return Error(ExLoc,
"malformed setfp offset");
9839 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
9847 getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg),
9848 static_cast<unsigned>(SPReg), Offset);
9854 bool ARMAsmParser::parseDirectivePad(
SMLoc L) {
9857 if (!UC.hasFnStart())
9858 return Error(L,
".fnstart must precede .pad directive");
9859 if (UC.hasHandlerData())
9860 return Error(L,
".pad must precede .handlerdata directive");
9868 const MCExpr *OffsetExpr;
9871 if (getParser().parseExpression(OffsetExpr, EndLoc))
9872 return Error(ExLoc,
"malformed pad offset");
9875 return Error(ExLoc,
"pad offset must be an immediate");
9878 "unexpected token in '.pad' directive"))
9881 getTargetStreamer().emitPad(CE->
getValue());
9888 bool ARMAsmParser::parseDirectiveRegSave(
SMLoc L,
bool IsVector) {
9890 if (!UC.hasFnStart())
9891 return Error(L,
".fnstart must precede .save or .vsave directives");
9892 if (UC.hasHandlerData())
9893 return Error(L,
".save or .vsave must precede .handlerdata directive");
9899 if (parseRegisterList(Operands) ||
9902 ARMOperand &Op = (ARMOperand &)*Operands[0];
9903 if (!IsVector && !Op.isRegList())
9904 return Error(L,
".save expects GPR registers");
9905 if (IsVector && !Op.isDPRRegList())
9906 return Error(L,
".vsave expects DPR registers");
9908 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
9916 bool ARMAsmParser::parseDirectiveInst(
SMLoc Loc,
char Suffix) {
9927 return Error(Loc,
"cannot determine Thumb instruction size, "
9928 "use inst.n/inst.w instead");
9932 return Error(Loc,
"width suffixes are invalid in ARM mode");
9935 auto parseOne = [&]() ->
bool {
9937 if (getParser().parseExpression(Expr))
9939 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
9941 return Error(Loc,
"expected constant expression");
9947 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
9950 if (Value->
getValue() > 0xffffffff)
9952 " operand is too big");
9958 getTargetStreamer().emitInst(Value->
getValue(), Suffix);
9963 return Error(Loc,
"expected expression following directive");
9964 if (parseMany(parseOne))
9971 bool ARMAsmParser::parseDirectiveLtorg(
SMLoc L) {
9974 getTargetStreamer().emitCurrentConstantPool();
9978 bool ARMAsmParser::parseDirectiveEven(
SMLoc L) {
9985 getStreamer().InitSections(
false);
9986 Section = getStreamer().getCurrentSectionOnly();
9989 assert(Section &&
"must have section to emit alignment");
9991 getStreamer().EmitCodeAlignment(2);
9993 getStreamer().EmitValueToAlignment(2);
10000 bool ARMAsmParser::parseDirectivePersonalityIndex(
SMLoc L) {
10002 bool HasExistingPersonality = UC.hasPersonality();
10004 const MCExpr *IndexExpression;
10008 "unexpected token in '.personalityindex' directive")) {
10012 UC.recordPersonalityIndex(L);
10014 if (!UC.hasFnStart()) {
10015 return Error(L,
".fnstart must precede .personalityindex directive");
10017 if (UC.cantUnwind()) {
10018 Error(L,
".personalityindex cannot be used with .cantunwind");
10019 UC.emitCantUnwindLocNotes();
10022 if (UC.hasHandlerData()) {
10023 Error(L,
".personalityindex must precede .handlerdata directive");
10024 UC.emitHandlerDataLocNotes();
10027 if (HasExistingPersonality) {
10028 Error(L,
"multiple personality directives");
10029 UC.emitPersonalityLocNotes();
10035 return Error(IndexLoc,
"index must be a constant number");
10037 return Error(IndexLoc,
10038 "personality routine index should be in range [0-3]");
10040 getTargetStreamer().emitPersonalityIndex(CE->
getValue());
10046 bool ARMAsmParser::parseDirectiveUnwindRaw(
SMLoc L) {
10048 int64_t StackOffset;
10049 const MCExpr *OffsetExpr;
10050 SMLoc OffsetLoc = getLexer().getLoc();
10052 if (!UC.hasFnStart())
10053 return Error(L,
".fnstart must precede .unwind_raw directives");
10054 if (getParser().parseExpression(OffsetExpr))
10055 return Error(OffsetLoc,
"expected expression");
10059 return Error(OffsetLoc,
"offset must be a constant");
10068 auto parseOne = [&]() ->
bool {
10070 SMLoc OpcodeLoc = getLexer().getLoc();
10073 OpcodeLoc,
"expected opcode expression"))
10077 return Error(OpcodeLoc,
"opcode value must be a constant");
10078 const int64_t Opcode = OC->
getValue();
10079 if (Opcode & ~0xff)
10080 return Error(OpcodeLoc,
"invalid opcode");
10086 SMLoc OpcodeLoc = getLexer().getLoc();
10088 return Error(OpcodeLoc,
"expected opcode expression");
10089 if (parseMany(parseOne))
10092 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
10098 bool ARMAsmParser::parseDirectiveTLSDescSeq(
SMLoc L) {
10102 return TokError(
"expected variable after '.tlsdescseq' directive");
10110 "unexpected token in '.tlsdescseq' directive"))
10113 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
10119 bool ARMAsmParser::parseDirectiveMovSP(
SMLoc L) {
10121 if (!UC.hasFnStart())
10122 return Error(L,
".fnstart must precede .movsp directives");
10123 if (UC.getFPReg() != ARM::SP)
10124 return Error(L,
"unexpected .movsp directive");
10127 int SPReg = tryParseRegister();
10129 return Error(SPRegLoc,
"register expected");
10130 if (SPReg == ARM::SP || SPReg ==
ARM::PC)
10131 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
10133 int64_t Offset = 0;
10138 const MCExpr *OffsetExpr;
10142 return Error(OffsetLoc,
"malformed offset expression");
10146 return Error(OffsetLoc,
"offset must be an immediate constant");
10152 "unexpected token in '.movsp' directive"))
10155 getTargetStreamer().emitMovSP(SPReg, Offset);
10156 UC.saveFPReg(SPReg);
10163 bool ARMAsmParser::parseDirectiveObjectArch(
SMLoc L) {
10166 return Error(getLexer().getLoc(),
"unexpected token");
10174 if (ID == ARM::AK_INVALID)
10175 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
10179 getTargetStreamer().emitObjectArch(ID);
10185 bool ARMAsmParser::parseDirectiveAlign(
SMLoc L) {
10190 const MCSection *Section = getStreamer().getCurrentSectionOnly();
10191 assert(Section &&
"must have section to emit alignment");
10193 getStreamer().EmitCodeAlignment(4, 0);
10195 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
10203 bool ARMAsmParser::parseDirectiveThumbSet(
SMLoc L) {
10208 "expected identifier after '.thumb_set'") ||
10209 parseToken(
AsmToken::Comma,
"expected comma after name '" + Name +
"'"))
10215 Parser, Sym, Value))
10218 getTargetStreamer().emitThumbSet(Sym, Value);
10230 #define GET_REGISTER_MATCHER
10231 #define GET_SUBTARGET_FEATURE_NAME
10232 #define GET_MATCHER_IMPLEMENTATION
10233 #include "ARMGenAsmMatcher.inc"
10238 static const struct {
10245 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10246 {
ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
10248 {ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
10249 {
ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
10250 {
ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10251 {
ARM::AEK_SEC, Feature_HasV6K, {ARM::FeatureTrustZone} },
10253 {
ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
10254 {
ARM::AEK_FP16, Feature_HasV8_2a, {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
10266 bool ARMAsmParser::parseDirectiveArchExtension(
SMLoc L) {
10270 return Error(getLexer().getLoc(),
"expected architecture extension name");
10277 "unexpected token in '.arch_extension' directive"))
10280 bool EnableFeature =
true;
10282 EnableFeature =
false;
10287 return Error(ExtLoc,
"unknown architectural extension: " + Name);
10290 if (Extension.Kind != FeatureKind)
10293 if (Extension.Features.none())
10294 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
10296 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
10297 return Error(ExtLoc,
"architectural extension '" + Name +
10299 "allowed for the current base architecture");
10306 uint64_t Features =
10307 ComputeAvailableFeatures(STI.
ToggleFeature(ToggleFeatures));
10308 setAvailableFeatures(Features);
10312 return Error(ExtLoc,
"unknown architectural extension: " + Name);
10319 ARMOperand &Op =
static_cast<ARMOperand &
>(AsmOp);
10327 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
10329 return Match_Success;
10333 const MCExpr *SOExpr = Op.getImm();
10335 if (!SOExpr->evaluateAsAbsolute(Value))
10336 return Match_Success;
10337 assert((Value >= INT32_MIN && Value <= UINT32_MAX) &&
10338 "expression value must be representable in 32 bits");
10342 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
10343 return Match_Success;
10347 MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg()))
10348 return Match_Success;
10351 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Represents a range in source code.
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
const_iterator end(StringRef path)
Get end iterator over path.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
static bool isNEONi16splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
const char * getPointer() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
static MCOperand createExpr(const MCExpr *Val)
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
This class provides various memory handling functions that manipulate MemoryBlock instances...
bool isReturn() const
Return true if the instruction is a return.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name...
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
static const ARMMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Describe properties that are true of each instruction in the target description file.
static unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
Target specific streamer interface.
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
const FeatureBitset Features
iterator find(StringRef Key)
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
const_iterator begin(StringRef path)
Get begin iterator over path.
static const char * getShiftOpcStr(ShiftOpc Op)
setjmp/longjmp based exceptions
VariantKind getKind() const
getOpcode - Get the kind of this expression.
Target & getTheThumbLETarget()
static bool isThumb(const MCSubtargetInfo &STI)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
static bool instIsBreakpoint(const MCInst &Inst)
static unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
StringRef getArchName(unsigned ArchKind)
static MCOperand createReg(unsigned Reg)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, unsigned Reg, unsigned HiReg, bool &containsReg)
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Generic assembler lexer interface, for use by target specific assembly lexers.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isCall() const
Return true if the instruction is a call.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
Windows NT (Windows on ARM)
static unsigned getDRegFromQReg(unsigned QReg)
Target & getTheARMBETarget()
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
Context object for machine code objects.
static bool isNEONi32splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
static unsigned getFPReg(const MachineOperand &MO)
getFPReg - Return the X86::FPx register number for the specified operand.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
.code16 (X86) / .code 16 (ARM)
unsigned getReg() const
Returns the register number.
Target & getTheThumbBETarget()
static int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
static bool RequiresVFPRegListValidation(StringRef Inst, bool &AcceptSinglePrecisionOnly, bool &AcceptDoublePrecisionOnly)
bool isV8EligibleForIT(InstrType *Instr)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
static int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
int64_t getIntVal() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, unsigned Reg)
MCRegisterClass - Base class of TargetRegisterClass.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
iterator insert(iterator I, const MCOperand &Op)
Instances of this class represent a single low-level machine instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned short NumOperands
static const fltSemantics & IEEEsingle()
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
ValuesClass values(OptsTy...Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
const MCExpr * getExpr() const
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
A switch()-like statement whose cases are string literals.
initializer< Ty > init(const Ty &Val)
Streaming machine code generation interface.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
static unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unsigned const MachineRegisterInfo * MRI
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static const char * InstSyncBOptToString(unsigned val)
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
bool isOptionalDef() const
Set if this operand is a optional def.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static const struct @305 Extensions[]
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Interface to description of machine instruction set.
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
FeatureBitset ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, unsigned VariantID)
bool IsCPSRDead< MCInst >(MCInst *Instr)
virtual bool UseCodeAlign() const =0
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
iterator erase(const_iterator CI)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
Triple - Helper class for working with autoconf configuration names.
static unsigned getNextRegister(unsigned Reg)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
void setOpcode(unsigned Op)
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
static bool isDataTypeToken(StringRef Tok)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
LLVM_NODISCARD T pop_back_val()
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned getOpcode() const
Class for arbitrary precision integers.
static unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static const char * MemBOptToString(unsigned val, bool HasV8)
Base class for user error types.
static unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
iterator insert(iterator I, T &&Elt)
static const char * IFlagsToString(unsigned val)
static int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
.code32 (X86) / .code 32 (ARM)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static SMLoc getFromPointer(const char *Ptr)
int AttrTypeFromString(StringRef Tag)
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static unsigned encodeNEONi16splat(unsigned Value)
static CondCodes getOppositeCondition(CondCodes CC)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
void LLVMInitializeARMAsmParser()
Force static initialization.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
unsigned getNumOperands() const
static unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
unsigned parseArchExt(StringRef ArchExt)
MCSubtargetInfo - Generic base class for all target subtargets.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned parseArch(StringRef Arch)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
static unsigned getSORegOffset(unsigned Op)
unsigned parseFPU(StringRef FPU)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
const MCOperandInfo * OpInfo
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Represents a location in source code.
Target & getTheARMLETarget()
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Instances of this class represent operands of the MCInst class.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static MCOperand createImm(int64_t Val)
static float getFPImmFloat(unsigned Imm)
LLVM_NODISCARD std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
static ShiftOpc getSORegShOp(unsigned Op)
void setDefaultFeatures(StringRef CPU, StringRef FS)
Set the features to the default for the given CPU with an appended feature string.