66 Locs PersonalityIndexLocs;
73 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
74 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
75 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
76 bool hasPersonality()
const {
77 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
80 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
81 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
82 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
83 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
84 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
86 void saveFPReg(
int Reg) { FPReg =
Reg; }
87 int getFPReg()
const {
return FPReg; }
89 void emitFnStartLocNotes()
const {
90 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
92 Parser.Note(*FI,
".fnstart was specified here");
94 void emitCantUnwindLocNotes()
const {
95 for (Locs::const_iterator UI = CantUnwindLocs.begin(),
96 UE = CantUnwindLocs.end(); UI != UE; ++UI)
97 Parser.Note(*UI,
".cantunwind was specified here");
99 void emitHandlerDataLocNotes()
const {
100 for (Locs::const_iterator
HI = HandlerDataLocs.begin(),
101 HE = HandlerDataLocs.end();
HI != HE; ++
HI)
102 Parser.Note(*
HI,
".handlerdata was specified here");
104 void emitPersonalityLocNotes()
const {
105 for (Locs::const_iterator PI = PersonalityLocs.begin(),
106 PE = PersonalityLocs.end(),
107 PII = PersonalityIndexLocs.begin(),
108 PIE = PersonalityIndexLocs.end();
109 PI != PE || PII != PIE;) {
110 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
111 Parser.Note(*PI++,
".personality was specified here");
112 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
113 Parser.Note(*PII++,
".personalityindex was specified here");
116 "at the same location");
121 FnStartLocs = Locs();
122 CantUnwindLocs = Locs();
123 PersonalityLocs = Locs();
124 HandlerDataLocs = Locs();
125 PersonalityIndexLocs = Locs();
137 assert(getParser().getStreamer().getTargetStreamer() &&
138 "do not have a target streamer");
146 bool NextSymbolIsThumb;
162 unsigned CurPosition;
167 bool inITBlock() {
return ITState.CurPosition != ~0U; }
168 bool lastInITBlock() {
171 void forwardITPosition() {
172 if (!inITBlock())
return;
176 if (++ITState.CurPosition == 5 - TZ)
177 ITState.CurPosition = ~0U;
181 return getParser().Note(L, Msg,
Ranges);
185 return getParser().Warning(L, Msg,
Ranges);
189 return getParser().Error(L, Msg,
Ranges);
193 unsigned ListNo,
bool IsARPop =
false);
197 int tryParseRegister();
205 unsigned &ShiftAmount);
206 bool parseLiteralValues(
unsigned Size,
SMLoc L);
207 bool parseDirectiveThumb(
SMLoc L);
208 bool parseDirectiveARM(
SMLoc L);
209 bool parseDirectiveThumbFunc(
SMLoc L);
210 bool parseDirectiveCode(
SMLoc L);
211 bool parseDirectiveSyntax(
SMLoc L);
213 bool parseDirectiveUnreq(
SMLoc L);
214 bool parseDirectiveArch(
SMLoc L);
215 bool parseDirectiveEabiAttr(
SMLoc L);
216 bool parseDirectiveCPU(
SMLoc L);
217 bool parseDirectiveFPU(
SMLoc L);
218 bool parseDirectiveFnStart(
SMLoc L);
219 bool parseDirectiveFnEnd(
SMLoc L);
220 bool parseDirectiveCantUnwind(
SMLoc L);
221 bool parseDirectivePersonality(
SMLoc L);
222 bool parseDirectiveHandlerData(
SMLoc L);
223 bool parseDirectiveSetFP(
SMLoc L);
224 bool parseDirectivePad(
SMLoc L);
225 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
226 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
227 bool parseDirectiveLtorg(
SMLoc L);
228 bool parseDirectiveEven(
SMLoc L);
229 bool parseDirectivePersonalityIndex(
SMLoc L);
230 bool parseDirectiveUnwindRaw(
SMLoc L);
231 bool parseDirectiveTLSDescSeq(
SMLoc L);
232 bool parseDirectiveMovSP(
SMLoc L);
233 bool parseDirectiveObjectArch(
SMLoc L);
234 bool parseDirectiveArchExtension(
SMLoc L);
235 bool parseDirectiveAlign(
SMLoc L);
236 bool parseDirectiveThumbSet(
SMLoc L);
239 bool &CarrySetting,
unsigned &ProcessorIMod,
242 bool &CanAcceptCarrySet,
243 bool &CanAcceptPredicationCode);
245 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
bool CarrySetting,
249 return STI.getFeatureBits()[ARM::ModeThumb];
251 bool isThumbOne()
const {
252 return isThumb() && !STI.getFeatureBits()[ARM::FeatureThumb2];
254 bool isThumbTwo()
const {
255 return isThumb() && STI.getFeatureBits()[ARM::FeatureThumb2];
257 bool hasThumb()
const {
258 return STI.getFeatureBits()[ARM::HasV4TOps];
260 bool hasV6Ops()
const {
261 return STI.getFeatureBits()[ARM::HasV6Ops];
263 bool hasV6MOps()
const {
264 return STI.getFeatureBits()[ARM::HasV6MOps];
266 bool hasV7Ops()
const {
267 return STI.getFeatureBits()[ARM::HasV7Ops];
269 bool hasV8Ops()
const {
270 return STI.getFeatureBits()[ARM::HasV8Ops];
272 bool hasARM()
const {
273 return !STI.getFeatureBits()[ARM::FeatureNoARM];
275 bool hasThumb2DSP()
const {
276 return STI.getFeatureBits()[ARM::FeatureDSPThumb2];
278 bool hasD16()
const {
279 return STI.getFeatureBits()[ARM::FeatureD16];
281 bool hasV8_1aOps()
const {
282 return STI.getFeatureBits()[ARM::HasV8_1aOps];
286 uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
287 setAvailableFeatures(FB);
289 bool isMClass()
const {
290 return STI.getFeatureBits()[ARM::FeatureMClass];
296 #define GET_ASSEMBLER_HEADER
297 #include "ARMGenAsmMatcher.inc"
304 OperandMatchResultTy parseCoprocOptionOperand(
OperandVector &);
305 OperandMatchResultTy parseMemBarrierOptOperand(
OperandVector &);
306 OperandMatchResultTy parseInstSyncBarrierOptOperand(
OperandVector &);
307 OperandMatchResultTy parseProcIFlagsOperand(
OperandVector &);
313 return parsePKHImm(O,
"lsl", 0, 31);
316 return parsePKHImm(O,
"asr", 1, 32);
327 OperandMatchResultTy parseVectorLane(
VectorLaneTy &LaneKind,
unsigned &Index,
340 enum ARMMatchResultTy {
341 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
342 Match_RequiresNotITBlock,
344 Match_RequiresThumb2,
345 #define GET_OPERAND_DIAGNOSTIC_TYPES
346 #include "ARMGenAsmMatcher.inc"
352 : STI(STI), MII(MII), UC(Parser) {
356 MRI = getContext().getRegisterInfo();
359 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
362 ITState.CurPosition = ~0U;
364 NextSymbolIsThumb =
false;
368 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
371 bool ParseDirective(
AsmToken DirectiveID)
override;
374 unsigned Kind)
override;
375 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
377 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
380 bool MatchingInlineAsm)
override;
399 k_InstSyncBarrierOpt,
411 k_VectorListAllLanes,
418 k_BitfieldDescriptor,
422 SMLoc StartLoc, EndLoc, AlignmentLoc;
433 struct CoprocOptionOp {
471 struct VectorListOp {
478 struct VectorIndexOp {
492 unsigned OffsetRegNum;
497 unsigned isNegative : 1;
500 struct PostIdxRegOp {
507 struct ShifterImmOp {
512 struct RegShiftedRegOp {
519 struct RegShiftedImmOp {
542 struct CoprocOptionOp CoprocOption;
543 struct MBOptOp MBOpt;
544 struct ISBOptOp ISBOpt;
545 struct ITMaskOp ITMask;
547 struct MMaskOp MMask;
548 struct BankedRegOp BankedReg;
551 struct VectorListOp VectorList;
552 struct VectorIndexOp VectorIndex;
555 struct PostIdxRegOp PostIdxReg;
556 struct ShifterImmOp ShifterImm;
557 struct RegShiftedRegOp RegShiftedReg;
558 struct RegShiftedImmOp RegShiftedImm;
559 struct RotImmOp RotImm;
560 struct ModImmOp ModImm;
568 StartLoc = o.StartLoc;
585 case k_DPRRegisterList:
586 case k_SPRRegisterList:
587 Registers = o.Registers;
590 case k_VectorListAllLanes:
591 case k_VectorListIndexed:
592 VectorList = o.VectorList;
599 CoprocOption = o.CoprocOption;
604 case k_MemBarrierOpt:
607 case k_InstSyncBarrierOpt:
612 case k_PostIndexRegister:
613 PostIdxReg = o.PostIdxReg;
619 BankedReg = o.BankedReg;
624 case k_ShifterImmediate:
625 ShifterImm = o.ShifterImm;
627 case k_ShiftedRegister:
628 RegShiftedReg = o.RegShiftedReg;
630 case k_ShiftedImmediate:
631 RegShiftedImm = o.RegShiftedImm;
633 case k_RotateImmediate:
636 case k_ModifiedImmediate:
639 case k_BitfieldDescriptor:
643 VectorIndex = o.VectorIndex;
649 SMLoc getStartLoc()
const override {
return StartLoc; }
651 SMLoc getEndLoc()
const override {
return EndLoc; }
657 SMLoc getAlignmentLoc()
const {
658 assert(
Kind == k_Memory &&
"Invalid access!");
663 assert(
Kind == k_CondCode &&
"Invalid access!");
667 unsigned getCoproc()
const {
668 assert((
Kind == k_CoprocNum ||
Kind == k_CoprocReg) &&
"Invalid access!");
673 assert(
Kind == k_Token &&
"Invalid access!");
677 unsigned getReg()
const override {
678 assert((
Kind == k_Register ||
Kind == k_CCOut) &&
"Invalid access!");
683 assert((
Kind == k_RegisterList ||
Kind == k_DPRRegisterList ||
684 Kind == k_SPRRegisterList) &&
"Invalid access!");
688 const MCExpr *getImm()
const {
689 assert(isImm() &&
"Invalid access!");
693 unsigned getVectorIndex()
const {
694 assert(
Kind == k_VectorIndex &&
"Invalid access!");
695 return VectorIndex.Val;
699 assert(
Kind == k_MemBarrierOpt &&
"Invalid access!");
704 assert(
Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
709 assert(
Kind == k_ProcIFlags &&
"Invalid access!");
713 unsigned getMSRMask()
const {
714 assert(
Kind == k_MSRMask &&
"Invalid access!");
718 unsigned getBankedReg()
const {
719 assert(
Kind == k_BankedReg &&
"Invalid access!");
720 return BankedReg.Val;
723 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
724 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
725 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
726 bool isCondCode()
const {
return Kind == k_CondCode; }
727 bool isCCOut()
const {
return Kind == k_CCOut; }
728 bool isITMask()
const {
return Kind == k_ITCondMask; }
729 bool isITCondCode()
const {
return Kind == k_CondCode; }
730 bool isImm()
const override {
return Kind == k_Immediate; }
733 template<
unsigned w
idth,
unsigned scale>
734 bool isUnsignedOffset()
const {
735 if (!isImm())
return false;
736 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
737 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
738 int64_t Val =
CE->getValue();
740 int64_t
Max = Align * ((1LL << width) - 1);
741 return ((Val %
Align) == 0) && (Val >= 0) && (Val <=
Max);
747 template<
unsigned w
idth,
unsigned scale>
748 bool isSignedOffset()
const {
749 if (!isImm())
return false;
750 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
751 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
752 int64_t Val =
CE->getValue();
754 int64_t
Max = Align * ((1LL << (width-1)) - 1);
755 int64_t Min = -
Align * (1LL << (width-1));
756 return ((Val %
Align) == 0) && (Val >= Min) && (Val <=
Max);
765 bool isThumbMemPC()
const {
768 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
770 if (!CE)
return false;
774 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
775 if(
Memory.BaseRegNum != ARM::PC)
return false;
776 Val =
Memory.OffsetImm->getValue();
779 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
781 bool isFPImm()
const {
782 if (!isImm())
return false;
784 if (!CE)
return false;
788 bool isFBits16()
const {
789 if (!isImm())
return false;
791 if (!CE)
return false;
793 return Value >= 0 && Value <= 16;
795 bool isFBits32()
const {
796 if (!isImm())
return false;
798 if (!CE)
return false;
800 return Value >= 1 && Value <= 32;
802 bool isImm8s4()
const {
803 if (!isImm())
return false;
805 if (!CE)
return false;
807 return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
809 bool isImm0_1020s4()
const {
810 if (!isImm())
return false;
812 if (!CE)
return false;
814 return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
816 bool isImm0_508s4()
const {
817 if (!isImm())
return false;
819 if (!CE)
return false;
821 return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
823 bool isImm0_508s4Neg()
const {
824 if (!isImm())
return false;
826 if (!CE)
return false;
829 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
831 bool isImm0_239()
const {
832 if (!isImm())
return false;
834 if (!CE)
return false;
836 return Value >= 0 && Value < 240;
838 bool isImm0_255()
const {
839 if (!isImm())
return false;
841 if (!CE)
return false;
843 return Value >= 0 && Value < 256;
845 bool isImm0_4095()
const {
846 if (!isImm())
return false;
848 if (!CE)
return false;
850 return Value >= 0 && Value < 4096;
852 bool isImm0_4095Neg()
const {
853 if (!isImm())
return false;
855 if (!CE)
return false;
857 return Value > 0 && Value < 4096;
859 bool isImm0_1()
const {
860 if (!isImm())
return false;
862 if (!CE)
return false;
864 return Value >= 0 && Value < 2;
866 bool isImm0_3()
const {
867 if (!isImm())
return false;
869 if (!CE)
return false;
871 return Value >= 0 && Value < 4;
873 bool isImm0_7()
const {
874 if (!isImm())
return false;
876 if (!CE)
return false;
878 return Value >= 0 && Value < 8;
880 bool isImm0_15()
const {
881 if (!isImm())
return false;
883 if (!CE)
return false;
885 return Value >= 0 && Value < 16;
887 bool isImm0_31()
const {
888 if (!isImm())
return false;
890 if (!CE)
return false;
892 return Value >= 0 && Value < 32;
894 bool isImm0_63()
const {
895 if (!isImm())
return false;
897 if (!CE)
return false;
899 return Value >= 0 && Value < 64;
901 bool isImm8()
const {
902 if (!isImm())
return false;
904 if (!CE)
return false;
908 bool isImm16()
const {
909 if (!isImm())
return false;
911 if (!CE)
return false;
915 bool isImm32()
const {
916 if (!isImm())
return false;
918 if (!CE)
return false;
922 bool isShrImm8()
const {
923 if (!isImm())
return false;
925 if (!CE)
return false;
927 return Value > 0 && Value <= 8;
929 bool isShrImm16()
const {
930 if (!isImm())
return false;
932 if (!CE)
return false;
934 return Value > 0 && Value <= 16;
936 bool isShrImm32()
const {
937 if (!isImm())
return false;
939 if (!CE)
return false;
941 return Value > 0 && Value <= 32;
943 bool isShrImm64()
const {
944 if (!isImm())
return false;
946 if (!CE)
return false;
948 return Value > 0 && Value <= 64;
950 bool isImm1_7()
const {
951 if (!isImm())
return false;
953 if (!CE)
return false;
955 return Value > 0 && Value < 8;
957 bool isImm1_15()
const {
958 if (!isImm())
return false;
960 if (!CE)
return false;
962 return Value > 0 && Value < 16;
964 bool isImm1_31()
const {
965 if (!isImm())
return false;
967 if (!CE)
return false;
969 return Value > 0 && Value < 32;
971 bool isImm1_16()
const {
972 if (!isImm())
return false;
974 if (!CE)
return false;
976 return Value > 0 && Value < 17;
978 bool isImm1_32()
const {
979 if (!isImm())
return false;
981 if (!CE)
return false;
983 return Value > 0 && Value < 33;
985 bool isImm0_32()
const {
986 if (!isImm())
return false;
988 if (!CE)
return false;
990 return Value >= 0 && Value < 33;
992 bool isImm0_65535()
const {
993 if (!isImm())
return false;
995 if (!CE)
return false;
997 return Value >= 0 && Value < 65536;
999 bool isImm256_65535Expr()
const {
1000 if (!isImm())
return false;
1004 if (!CE)
return true;
1006 return Value >= 256 && Value < 65536;
1008 bool isImm0_65535Expr()
const {
1009 if (!isImm())
return false;
1013 if (!CE)
return true;
1015 return Value >= 0 && Value < 65536;
1017 bool isImm24bit()
const {
1018 if (!isImm())
return false;
1020 if (!CE)
return false;
1022 return Value >= 0 && Value <= 0xffffff;
1024 bool isImmThumbSR()
const {
1025 if (!isImm())
return false;
1027 if (!CE)
return false;
1029 return Value > 0 && Value < 33;
1031 bool isPKHLSLImm()
const {
1032 if (!isImm())
return false;
1034 if (!CE)
return false;
1036 return Value >= 0 && Value < 32;
1038 bool isPKHASRImm()
const {
1039 if (!isImm())
return false;
1041 if (!CE)
return false;
1043 return Value > 0 && Value <= 32;
1045 bool isAdrLabel()
const {
1048 if (isImm() && !isa<MCConstantExpr>(getImm()))
1052 if (!isImm())
return false;
1054 if (!CE)
return false;
1059 bool isT2SOImm()
const {
1060 if (!isImm())
return false;
1062 if (!CE)
return false;
1066 bool isT2SOImmNot()
const {
1067 if (!isImm())
return false;
1069 if (!CE)
return false;
1074 bool isT2SOImmNeg()
const {
1075 if (!isImm())
return false;
1077 if (!CE)
return false;
1083 bool isSetEndImm()
const {
1084 if (!isImm())
return false;
1086 if (!CE)
return false;
1088 return Value == 1 || Value == 0;
1090 bool isReg()
const override {
return Kind == k_Register; }
1091 bool isRegList()
const {
return Kind == k_RegisterList; }
1092 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1093 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1094 bool isToken()
const override {
return Kind == k_Token; }
1095 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1096 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1097 bool isMem()
const override {
return Kind == k_Memory; }
1098 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1099 bool isRegShiftedReg()
const {
return Kind == k_ShiftedRegister; }
1100 bool isRegShiftedImm()
const {
return Kind == k_ShiftedImmediate; }
1101 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1102 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1103 bool isModImmNot()
const {
1104 if (!isImm())
return false;
1106 if (!CE)
return false;
1110 bool isModImmNeg()
const {
1111 if (!isImm())
return false;
1113 if (!CE)
return false;
1118 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1119 bool isPostIdxRegShifted()
const {
return Kind == k_PostIndexRegister; }
1120 bool isPostIdxReg()
const {
1123 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1127 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1128 (alignOK ||
Memory.Alignment == Alignment);
1130 bool isMemPCRelImm12()
const {
1134 if (
Memory.BaseRegNum != ARM::PC)
1137 if (!
Memory.OffsetImm)
return true;
1138 int64_t Val =
Memory.OffsetImm->getValue();
1139 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
1141 bool isAlignedMemory()
const {
1142 return isMemNoOffset(
true);
1144 bool isAlignedMemoryNone()
const {
1145 return isMemNoOffset(
false, 0);
1147 bool isDupAlignedMemoryNone()
const {
1148 return isMemNoOffset(
false, 0);
1150 bool isAlignedMemory16()
const {
1151 if (isMemNoOffset(
false, 2))
1153 return isMemNoOffset(
false, 0);
1155 bool isDupAlignedMemory16()
const {
1156 if (isMemNoOffset(
false, 2))
1158 return isMemNoOffset(
false, 0);
1160 bool isAlignedMemory32()
const {
1161 if (isMemNoOffset(
false, 4))
1163 return isMemNoOffset(
false, 0);
1165 bool isDupAlignedMemory32()
const {
1166 if (isMemNoOffset(
false, 4))
1168 return isMemNoOffset(
false, 0);
1170 bool isAlignedMemory64()
const {
1171 if (isMemNoOffset(
false, 8))
1173 return isMemNoOffset(
false, 0);
1175 bool isDupAlignedMemory64()
const {
1176 if (isMemNoOffset(
false, 8))
1178 return isMemNoOffset(
false, 0);
1180 bool isAlignedMemory64or128()
const {
1181 if (isMemNoOffset(
false, 8))
1183 if (isMemNoOffset(
false, 16))
1185 return isMemNoOffset(
false, 0);
1187 bool isDupAlignedMemory64or128()
const {
1188 if (isMemNoOffset(
false, 8))
1190 if (isMemNoOffset(
false, 16))
1192 return isMemNoOffset(
false, 0);
1194 bool isAlignedMemory64or128or256()
const {
1195 if (isMemNoOffset(
false, 8))
1197 if (isMemNoOffset(
false, 16))
1199 if (isMemNoOffset(
false, 32))
1201 return isMemNoOffset(
false, 0);
1203 bool isAddrMode2()
const {
1204 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1206 if (
Memory.OffsetRegNum)
return true;
1208 if (!
Memory.OffsetImm)
return true;
1209 int64_t Val =
Memory.OffsetImm->getValue();
1210 return Val > -4096 && Val < 4096;
1212 bool isAM2OffsetImm()
const {
1213 if (!isImm())
return false;
1216 if (!CE)
return false;
1218 return (Val == INT32_MIN) || (Val > -4096 && Val < 4096);
1220 bool isAddrMode3()
const {
1224 if (isImm() && !isa<MCConstantExpr>(getImm()))
1226 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1230 if (
Memory.OffsetRegNum)
return true;
1232 if (!
Memory.OffsetImm)
return true;
1233 int64_t Val =
Memory.OffsetImm->getValue();
1236 return (Val > -256 && Val < 256) || Val == INT32_MIN;
1238 bool isAM3Offset()
const {
1239 if (
Kind != k_Immediate &&
Kind != k_PostIndexRegister)
1241 if (
Kind == k_PostIndexRegister)
1245 if (!CE)
return false;
1248 return (Val > -256 && Val < 256) || Val == INT32_MIN;
1250 bool isAddrMode5()
const {
1254 if (isImm() && !isa<MCConstantExpr>(getImm()))
1256 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1258 if (
Memory.OffsetRegNum)
return false;
1260 if (!
Memory.OffsetImm)
return true;
1261 int64_t Val =
Memory.OffsetImm->getValue();
1262 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1265 bool isMemTBB()
const {
1271 bool isMemTBH()
const {
1278 bool isMemRegOffset()
const {
1283 bool isT2MemRegOffset()
const {
1294 bool isMemThumbRR()
const {
1303 bool isMemThumbRIs4()
const {
1308 if (!
Memory.OffsetImm)
return true;
1309 int64_t Val =
Memory.OffsetImm->getValue();
1310 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1312 bool isMemThumbRIs2()
const {
1317 if (!
Memory.OffsetImm)
return true;
1318 int64_t Val =
Memory.OffsetImm->getValue();
1319 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1321 bool isMemThumbRIs1()
const {
1326 if (!
Memory.OffsetImm)
return true;
1327 int64_t Val =
Memory.OffsetImm->getValue();
1328 return Val >= 0 && Val <= 31;
1330 bool isMemThumbSPI()
const {
1335 if (!
Memory.OffsetImm)
return true;
1336 int64_t Val =
Memory.OffsetImm->getValue();
1337 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1339 bool isMemImm8s4Offset()
const {
1343 if (isImm() && !isa<MCConstantExpr>(getImm()))
1348 if (!
Memory.OffsetImm)
return true;
1349 int64_t Val =
Memory.OffsetImm->getValue();
1351 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN;
1353 bool isMemImm0_1020s4Offset()
const {
1357 if (!
Memory.OffsetImm)
return true;
1358 int64_t Val =
Memory.OffsetImm->getValue();
1359 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1361 bool isMemImm8Offset()
const {
1365 if (
Memory.BaseRegNum == ARM::PC)
return false;
1367 if (!
Memory.OffsetImm)
return true;
1368 int64_t Val =
Memory.OffsetImm->getValue();
1369 return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1371 bool isMemPosImm8Offset()
const {
1375 if (!
Memory.OffsetImm)
return true;
1376 int64_t Val =
Memory.OffsetImm->getValue();
1377 return Val >= 0 && Val < 256;
1379 bool isMemNegImm8Offset()
const {
1383 if (
Memory.BaseRegNum == ARM::PC)
return false;
1385 if (!
Memory.OffsetImm)
return false;
1386 int64_t Val =
Memory.OffsetImm->getValue();
1387 return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1389 bool isMemUImm12Offset()
const {
1393 if (!
Memory.OffsetImm)
return true;
1394 int64_t Val =
Memory.OffsetImm->getValue();
1395 return (Val >= 0 && Val < 4096);
1397 bool isMemImm12Offset()
const {
1401 if (isImm() && !isa<MCConstantExpr>(getImm()))
1407 if (!
Memory.OffsetImm)
return true;
1408 int64_t Val =
Memory.OffsetImm->getValue();
1409 return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
1411 bool isPostIdxImm8()
const {
1412 if (!isImm())
return false;
1414 if (!CE)
return false;
1416 return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1418 bool isPostIdxImm8s4()
const {
1419 if (!isImm())
return false;
1421 if (!CE)
return false;
1423 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
1427 bool isMSRMask()
const {
return Kind == k_MSRMask; }
1428 bool isBankedReg()
const {
return Kind == k_BankedReg; }
1429 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
1432 bool isSingleSpacedVectorList()
const {
1433 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
1435 bool isDoubleSpacedVectorList()
const {
1436 return Kind == k_VectorList && VectorList.isDoubleSpaced;
1438 bool isVecListOneD()
const {
1439 if (!isSingleSpacedVectorList())
return false;
1440 return VectorList.Count == 1;
1443 bool isVecListDPair()
const {
1444 if (!isSingleSpacedVectorList())
return false;
1445 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1449 bool isVecListThreeD()
const {
1450 if (!isSingleSpacedVectorList())
return false;
1451 return VectorList.Count == 3;
1454 bool isVecListFourD()
const {
1455 if (!isSingleSpacedVectorList())
return false;
1456 return VectorList.Count == 4;
1459 bool isVecListDPairSpaced()
const {
1460 if (
Kind != k_VectorList)
return false;
1461 if (isSingleSpacedVectorList())
return false;
1462 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1466 bool isVecListThreeQ()
const {
1467 if (!isDoubleSpacedVectorList())
return false;
1468 return VectorList.Count == 3;
1471 bool isVecListFourQ()
const {
1472 if (!isDoubleSpacedVectorList())
return false;
1473 return VectorList.Count == 4;
1476 bool isSingleSpacedVectorAllLanes()
const {
1477 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
1479 bool isDoubleSpacedVectorAllLanes()
const {
1480 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
1482 bool isVecListOneDAllLanes()
const {
1483 if (!isSingleSpacedVectorAllLanes())
return false;
1484 return VectorList.Count == 1;
1487 bool isVecListDPairAllLanes()
const {
1488 if (!isSingleSpacedVectorAllLanes())
return false;
1489 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1493 bool isVecListDPairSpacedAllLanes()
const {
1494 if (!isDoubleSpacedVectorAllLanes())
return false;
1495 return VectorList.Count == 2;
1498 bool isVecListThreeDAllLanes()
const {
1499 if (!isSingleSpacedVectorAllLanes())
return false;
1500 return VectorList.Count == 3;
1503 bool isVecListThreeQAllLanes()
const {
1504 if (!isDoubleSpacedVectorAllLanes())
return false;
1505 return VectorList.Count == 3;
1508 bool isVecListFourDAllLanes()
const {
1509 if (!isSingleSpacedVectorAllLanes())
return false;
1510 return VectorList.Count == 4;
1513 bool isVecListFourQAllLanes()
const {
1514 if (!isDoubleSpacedVectorAllLanes())
return false;
1515 return VectorList.Count == 4;
1518 bool isSingleSpacedVectorIndexed()
const {
1519 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
1521 bool isDoubleSpacedVectorIndexed()
const {
1522 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
1524 bool isVecListOneDByteIndexed()
const {
1525 if (!isSingleSpacedVectorIndexed())
return false;
1526 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
1529 bool isVecListOneDHWordIndexed()
const {
1530 if (!isSingleSpacedVectorIndexed())
return false;
1531 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1534 bool isVecListOneDWordIndexed()
const {
1535 if (!isSingleSpacedVectorIndexed())
return false;
1536 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1539 bool isVecListTwoDByteIndexed()
const {
1540 if (!isSingleSpacedVectorIndexed())
return false;
1541 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
1544 bool isVecListTwoDHWordIndexed()
const {
1545 if (!isSingleSpacedVectorIndexed())
return false;
1546 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1549 bool isVecListTwoQWordIndexed()
const {
1550 if (!isDoubleSpacedVectorIndexed())
return false;
1551 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1554 bool isVecListTwoQHWordIndexed()
const {
1555 if (!isDoubleSpacedVectorIndexed())
return false;
1556 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1559 bool isVecListTwoDWordIndexed()
const {
1560 if (!isSingleSpacedVectorIndexed())
return false;
1561 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1564 bool isVecListThreeDByteIndexed()
const {
1565 if (!isSingleSpacedVectorIndexed())
return false;
1566 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
1569 bool isVecListThreeDHWordIndexed()
const {
1570 if (!isSingleSpacedVectorIndexed())
return false;
1571 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1574 bool isVecListThreeQWordIndexed()
const {
1575 if (!isDoubleSpacedVectorIndexed())
return false;
1576 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1579 bool isVecListThreeQHWordIndexed()
const {
1580 if (!isDoubleSpacedVectorIndexed())
return false;
1581 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1584 bool isVecListThreeDWordIndexed()
const {
1585 if (!isSingleSpacedVectorIndexed())
return false;
1586 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1589 bool isVecListFourDByteIndexed()
const {
1590 if (!isSingleSpacedVectorIndexed())
return false;
1591 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1594 bool isVecListFourDHWordIndexed()
const {
1595 if (!isSingleSpacedVectorIndexed())
return false;
1596 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1599 bool isVecListFourQWordIndexed()
const {
1600 if (!isDoubleSpacedVectorIndexed())
return false;
1601 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1604 bool isVecListFourQHWordIndexed()
const {
1605 if (!isDoubleSpacedVectorIndexed())
return false;
1606 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1609 bool isVecListFourDWordIndexed()
const {
1610 if (!isSingleSpacedVectorIndexed())
return false;
1611 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1614 bool isVectorIndex8()
const {
1615 if (
Kind != k_VectorIndex)
return false;
1616 return VectorIndex.Val < 8;
1618 bool isVectorIndex16()
const {
1619 if (
Kind != k_VectorIndex)
return false;
1620 return VectorIndex.Val < 4;
1622 bool isVectorIndex32()
const {
1623 if (
Kind != k_VectorIndex)
return false;
1624 return VectorIndex.Val < 2;
1627 bool isNEONi8splat()
const {
1628 if (!isImm())
return false;
1631 if (!CE)
return false;
1635 return Value >= 0 && Value < 256;
1639 if (isNEONByteReplicate(2))
1645 if (!CE)
return false;
1650 bool isNEONi16splatNot()
const {
1655 if (!CE)
return false;
1661 if (isNEONByteReplicate(4))
1667 if (!CE)
return false;
1672 bool isNEONi32splatNot()
const {
1677 if (!CE)
return false;
1682 bool isNEONByteReplicate(
unsigned NumBytes)
const {
1693 unsigned char B = Value & 0xff;
1694 for (
unsigned i = 1; i < NumBytes; ++i) {
1696 if ((Value & 0xff) != B)
1701 bool isNEONi16ByteReplicate()
const {
return isNEONByteReplicate(2); }
1702 bool isNEONi32ByteReplicate()
const {
return isNEONByteReplicate(4); }
1703 bool isNEONi32vmov()
const {
1704 if (isNEONByteReplicate(4))
1716 return (Value >= 0 && Value < 256) ||
1717 (Value >= 0x0100 && Value <= 0xff00) ||
1718 (Value >= 0x010000 && Value <= 0xff0000) ||
1719 (Value >= 0x01000000 && Value <= 0xff000000) ||
1720 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1721 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1723 bool isNEONi32vmovNeg()
const {
1724 if (!isImm())
return false;
1727 if (!CE)
return false;
1732 return (Value >= 0 && Value < 256) ||
1733 (Value >= 0x0100 && Value <= 0xff00) ||
1734 (Value >= 0x010000 && Value <= 0xff0000) ||
1735 (Value >= 0x01000000 && Value <= 0xff000000) ||
1736 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1737 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1740 bool isNEONi64splat()
const {
1741 if (!isImm())
return false;
1744 if (!CE)
return false;
1747 for (
unsigned i = 0; i < 8; ++i)
1748 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff)
return false;
1756 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1762 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1763 assert(N == 2 &&
"Invalid number of operands!");
1765 unsigned RegNum = getCondCode() ==
ARMCC::AL ? 0: ARM::CPSR;
1769 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
1770 assert(N == 1 &&
"Invalid number of operands!");
1774 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
1775 assert(N == 1 &&
"Invalid number of operands!");
1779 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
1780 assert(N == 1 &&
"Invalid number of operands!");
1784 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
1785 assert(N == 1 &&
"Invalid number of operands!");
1789 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1790 assert(N == 1 &&
"Invalid number of operands!");
1794 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
1795 assert(N == 1 &&
"Invalid number of operands!");
1799 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1800 assert(N == 1 &&
"Invalid number of operands!");
1804 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
1805 assert(N == 3 &&
"Invalid number of operands!");
1806 assert(isRegShiftedReg() &&
1807 "addRegShiftedRegOperands() on non-RegShiftedReg!");
1814 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
1815 assert(N == 2 &&
"Invalid number of operands!");
1816 assert(isRegShiftedImm() &&
1817 "addRegShiftedImmOperands() on non-RegShiftedImm!");
1820 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
1825 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
1826 assert(N == 1 &&
"Invalid number of operands!");
1831 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
1832 assert(N == 1 &&
"Invalid number of operands!");
1835 I = RegList.
begin(), E = RegList.
end();
I != E; ++
I)
1839 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
1840 addRegListOperands(Inst, N);
1843 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
1844 addRegListOperands(Inst, N);
1847 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
1848 assert(N == 1 &&
"Invalid number of operands!");
1853 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
1854 assert(N == 1 &&
"Invalid number of operands!");
1858 return addImmOperands(Inst, N);
1863 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
1864 assert(N == 1 &&
"Invalid number of operands!");
1870 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
1871 assert(N == 1 &&
"Invalid number of operands!");
1877 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
1878 assert(N == 1 &&
"Invalid number of operands!");
1883 uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1884 (32 - (lsb + width)));
1888 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1889 assert(N == 1 &&
"Invalid number of operands!");
1890 addExpr(Inst, getImm());
1893 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
1894 assert(N == 1 &&
"Invalid number of operands!");
1899 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
1900 assert(N == 1 &&
"Invalid number of operands!");
1905 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1906 assert(N == 1 &&
"Invalid number of operands!");
1912 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
1913 assert(N == 1 &&
"Invalid number of operands!");
1920 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
1921 assert(N == 1 &&
"Invalid number of operands!");
1928 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
1929 assert(N == 1 &&
"Invalid number of operands!");
1936 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
1937 assert(N == 1 &&
"Invalid number of operands!");
1944 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
1945 assert(N == 1 &&
"Invalid number of operands!");
1952 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
1953 assert(N == 1 &&
"Invalid number of operands!");
1960 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
1961 assert(N == 1 &&
"Invalid number of operands!");
1969 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
1970 assert(N == 1 &&
"Invalid number of operands!");
1978 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
1979 assert(N == 1 &&
"Invalid number of operands!");
1986 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
1987 assert(N == 1 &&
"Invalid number of operands!");
1994 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
1995 assert(N == 1 &&
"Invalid number of operands!");
2002 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2003 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2009 assert(SR &&
"Unknown value type!");
2013 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2014 assert(N == 1 &&
"Invalid number of operands!");
2023 assert(SR &&
"Unknown value type!");
2028 assert(
isMem() &&
"Unknown value type!");
2029 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2033 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2034 assert(N == 1 &&
"Invalid number of operands!");
2038 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2039 assert(N == 1 &&
"Invalid number of operands!");
2043 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2044 assert(N == 1 &&
"Invalid number of operands!");
2048 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2049 assert(N == 1 &&
"Invalid number of operands!");
2050 int32_t Imm =
Memory.OffsetImm->getValue();
2054 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2055 assert(N == 1 &&
"Invalid number of operands!");
2056 assert(isImm() &&
"Not an immediate!");
2060 if (!isa<MCConstantExpr>(getImm())) {
2070 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2071 assert(N == 2 &&
"Invalid number of operands!");
2076 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2077 addAlignedMemoryOperands(Inst, N);
2080 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2081 addAlignedMemoryOperands(Inst, N);
2084 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2085 addAlignedMemoryOperands(Inst, N);
2088 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2089 addAlignedMemoryOperands(Inst, N);
2092 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2093 addAlignedMemoryOperands(Inst, N);
2096 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2097 addAlignedMemoryOperands(Inst, N);
2100 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2101 addAlignedMemoryOperands(Inst, N);
2104 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2105 addAlignedMemoryOperands(Inst, N);
2108 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2109 addAlignedMemoryOperands(Inst, N);
2112 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2113 addAlignedMemoryOperands(Inst, N);
2116 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2117 addAlignedMemoryOperands(Inst, N);
2120 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
2121 assert(N == 3 &&
"Invalid number of operands!");
2122 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2123 if (!
Memory.OffsetRegNum) {
2126 if (Val == INT32_MIN) Val = 0;
2127 if (Val < 0) Val = -Val;
2140 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
2141 assert(N == 2 &&
"Invalid number of operands!");
2143 assert(CE &&
"non-constant AM2OffsetImm operand!");
2147 if (Val == INT32_MIN) Val = 0;
2148 if (Val < 0) Val = -Val;
2154 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
2155 assert(N == 3 &&
"Invalid number of operands!");
2166 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2167 if (!
Memory.OffsetRegNum) {
2170 if (Val == INT32_MIN) Val = 0;
2171 if (Val < 0) Val = -Val;
2183 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2184 assert(N == 2 &&
"Invalid number of operands!");
2185 if (
Kind == k_PostIndexRegister) {
2198 if (Val == INT32_MIN) Val = 0;
2199 if (Val < 0) Val = -Val;
2205 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
2206 assert(N == 2 &&
"Invalid number of operands!");
2217 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2220 if (Val == INT32_MIN) Val = 0;
2221 if (Val < 0) Val = -Val;
2227 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2228 assert(N == 2 &&
"Invalid number of operands!");
2238 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2243 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2244 assert(N == 2 &&
"Invalid number of operands!");
2246 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2251 void addMemImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2252 assert(N == 2 &&
"Invalid number of operands!");
2253 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2258 void addMemPosImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2259 addMemImm8OffsetOperands(Inst, N);
2262 void addMemNegImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2263 addMemImm8OffsetOperands(Inst, N);
2266 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2267 assert(N == 2 &&
"Invalid number of operands!");
2270 addExpr(Inst, getImm());
2276 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2281 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2282 assert(N == 2 &&
"Invalid number of operands!");
2285 addExpr(Inst, getImm());
2291 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2296 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
2297 assert(N == 2 &&
"Invalid number of operands!");
2302 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
2303 assert(N == 2 &&
"Invalid number of operands!");
2308 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2309 assert(N == 3 &&
"Invalid number of operands!");
2318 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2319 assert(N == 3 &&
"Invalid number of operands!");
2325 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
2326 assert(N == 2 &&
"Invalid number of operands!");
2331 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
2332 assert(N == 2 &&
"Invalid number of operands!");
2333 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2338 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
2339 assert(N == 2 &&
"Invalid number of operands!");
2340 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 2) : 0;
2345 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
2346 assert(N == 2 &&
"Invalid number of operands!");
2347 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue()) : 0;
2352 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
2353 assert(N == 2 &&
"Invalid number of operands!");
2354 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2359 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
2360 assert(N == 1 &&
"Invalid number of operands!");
2362 assert(CE &&
"non-constant post-idx-imm8 operand!");
2364 bool isAdd = Imm >= 0;
2365 if (Imm == INT32_MIN) Imm = 0;
2366 Imm = (Imm < 0 ? -Imm : Imm) | (
int)isAdd << 8;
2370 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2371 assert(N == 1 &&
"Invalid number of operands!");
2373 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
2375 bool isAdd = Imm >= 0;
2376 if (Imm == INT32_MIN) Imm = 0;
2378 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (
int)isAdd << 8;
2382 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
2383 assert(N == 2 &&
"Invalid number of operands!");
2388 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
2389 assert(N == 2 &&
"Invalid number of operands!");
2395 PostIdxReg.ShiftTy);
2399 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
2400 assert(N == 1 &&
"Invalid number of operands!");
2404 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
2405 assert(N == 1 &&
"Invalid number of operands!");
2409 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
2410 assert(N == 1 &&
"Invalid number of operands!");
2414 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
2415 assert(N == 1 &&
"Invalid number of operands!");
2419 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
2420 assert(N == 2 &&
"Invalid number of operands!");
2425 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
2426 assert(N == 1 &&
"Invalid number of operands!");
2430 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
2431 assert(N == 1 &&
"Invalid number of operands!");
2435 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
2436 assert(N == 1 &&
"Invalid number of operands!");
2440 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
2441 assert(N == 1 &&
"Invalid number of operands!");
2448 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
2449 assert(N == 1 &&
"Invalid number of operands!");
2457 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2458 assert(N == 1 &&
"Invalid number of operands!");
2466 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
2467 assert(N == 1 &&
"Invalid number of operands!");
2475 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2476 assert(N == 1 &&
"Invalid number of operands!");
2484 void addNEONinvByteReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2485 assert(N == 1 &&
"Invalid number of operands!");
2489 assert((Inst.
getOpcode() == ARM::VMOVv8i8 ||
2491 "All vmvn instructions that wants to replicate non-zero byte "
2492 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
2493 unsigned B = ((~Value) & 0xff);
2497 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
2498 assert(N == 1 &&
"Invalid number of operands!");
2502 if (Value >= 256 && Value <= 0xffff)
2503 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
2504 else if (Value > 0xffff && Value <= 0xffffff)
2505 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
2506 else if (Value > 0xffffff)
2507 Value = (Value >> 24) | 0x600;
2511 void addNEONvmovByteReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2512 assert(N == 1 &&
"Invalid number of operands!");
2516 assert((Inst.
getOpcode() == ARM::VMOVv8i8 ||
2518 "All instructions that wants to replicate non-zero byte "
2519 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
2520 unsigned B = Value & 0xff;
2524 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
2525 assert(N == 1 &&
"Invalid number of operands!");
2529 if (Value >= 256 && Value <= 0xffff)
2530 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
2531 else if (Value > 0xffff && Value <= 0xffffff)
2532 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
2533 else if (Value > 0xffffff)
2534 Value = (Value >> 24) | 0x600;
2538 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
2539 assert(N == 1 &&
"Invalid number of operands!");
2544 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
2545 Imm |= (Value & 1) << i;
2552 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S) {
2553 auto Op = make_unique<ARMOperand>(k_ITCondMask);
2554 Op->ITMask.Mask = Mask;
2562 auto Op = make_unique<ARMOperand>(k_CondCode);
2569 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S) {
2570 auto Op = make_unique<ARMOperand>(k_CoprocNum);
2571 Op->Cop.Val = CopVal;
2577 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S) {
2578 auto Op = make_unique<ARMOperand>(k_CoprocReg);
2579 Op->Cop.Val = CopVal;
2585 static std::unique_ptr<ARMOperand> CreateCoprocOption(
unsigned Val,
SMLoc S,
2587 auto Op = make_unique<ARMOperand>(k_CoprocOption);
2594 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S) {
2595 auto Op = make_unique<ARMOperand>(k_CCOut);
2596 Op->Reg.RegNum = RegNum;
2602 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S) {
2603 auto Op = make_unique<ARMOperand>(k_Token);
2604 Op->Tok.Data = Str.
data();
2605 Op->Tok.Length = Str.
size();
2611 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
2613 auto Op = make_unique<ARMOperand>(k_Register);
2614 Op->Reg.RegNum = RegNum;
2620 static std::unique_ptr<ARMOperand>
2622 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
2624 auto Op = make_unique<ARMOperand>(k_ShiftedRegister);
2625 Op->RegShiftedReg.ShiftTy = ShTy;
2626 Op->RegShiftedReg.SrcReg = SrcReg;
2627 Op->RegShiftedReg.ShiftReg = ShiftReg;
2628 Op->RegShiftedReg.ShiftImm = ShiftImm;
2634 static std::unique_ptr<ARMOperand>
2637 auto Op = make_unique<ARMOperand>(k_ShiftedImmediate);
2638 Op->RegShiftedImm.ShiftTy = ShTy;
2639 Op->RegShiftedImm.SrcReg = SrcReg;
2640 Op->RegShiftedImm.ShiftImm = ShiftImm;
2646 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
2648 auto Op = make_unique<ARMOperand>(k_ShifterImmediate);
2649 Op->ShifterImm.isASR = isASR;
2650 Op->ShifterImm.Imm = Imm;
2656 static std::unique_ptr<ARMOperand> CreateRotImm(
unsigned Imm,
SMLoc S,
2658 auto Op = make_unique<ARMOperand>(k_RotateImmediate);
2659 Op->RotImm.Imm = Imm;
2665 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
2667 auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
2668 Op->ModImm.Bits =
Bits;
2669 Op->ModImm.Rot = Rot;
2675 static std::unique_ptr<ARMOperand>
2676 CreateBitfield(
unsigned LSB,
unsigned Width,
SMLoc S,
SMLoc E) {
2677 auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
2678 Op->Bitfield.LSB = LSB;
2679 Op->Bitfield.Width = Width;
2685 static std::unique_ptr<ARMOperand>
2688 assert (Regs.size() > 0 &&
"RegList contains no registers?");
2689 KindTy
Kind = k_RegisterList;
2691 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Regs.front().second))
2692 Kind = k_DPRRegisterList;
2693 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2695 Kind = k_SPRRegisterList;
2700 auto Op = make_unique<ARMOperand>(
Kind);
2702 I = Regs.begin(), E = Regs.end();
I != E; ++
I)
2703 Op->Registers.push_back(
I->second);
2704 Op->StartLoc = StartLoc;
2705 Op->EndLoc = EndLoc;
2709 static std::unique_ptr<ARMOperand> CreateVectorList(
unsigned RegNum,
2711 bool isDoubleSpaced,
2713 auto Op = make_unique<ARMOperand>(k_VectorList);
2714 Op->VectorList.RegNum = RegNum;
2715 Op->VectorList.Count = Count;
2716 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2722 static std::unique_ptr<ARMOperand>
2723 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
2725 auto Op = make_unique<ARMOperand>(k_VectorListAllLanes);
2726 Op->VectorList.RegNum = RegNum;
2727 Op->VectorList.Count = Count;
2728 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2734 static std::unique_ptr<ARMOperand>
2735 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
2737 auto Op = make_unique<ARMOperand>(k_VectorListIndexed);
2738 Op->VectorList.RegNum = RegNum;
2739 Op->VectorList.Count = Count;
2740 Op->VectorList.LaneIndex = Index;
2741 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2747 static std::unique_ptr<ARMOperand>
2749 auto Op = make_unique<ARMOperand>(k_VectorIndex);
2750 Op->VectorIndex.Val = Idx;
2756 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
2758 auto Op = make_unique<ARMOperand>(k_Immediate);
2765 static std::unique_ptr<ARMOperand>
2768 unsigned ShiftImm,
unsigned Alignment,
bool isNegative,
SMLoc S,
2770 auto Op = make_unique<ARMOperand>(k_Memory);
2771 Op->Memory.BaseRegNum = BaseRegNum;
2772 Op->Memory.OffsetImm = OffsetImm;
2773 Op->Memory.OffsetRegNum = OffsetRegNum;
2774 Op->Memory.ShiftType = ShiftType;
2775 Op->Memory.ShiftImm = ShiftImm;
2776 Op->Memory.Alignment = Alignment;
2777 Op->Memory.isNegative = isNegative;
2780 Op->AlignmentLoc = AlignmentLoc;
2784 static std::unique_ptr<ARMOperand>
2787 auto Op = make_unique<ARMOperand>(k_PostIndexRegister);
2788 Op->PostIdxReg.RegNum = RegNum;
2789 Op->PostIdxReg.isAdd = isAdd;
2790 Op->PostIdxReg.ShiftTy = ShiftTy;
2791 Op->PostIdxReg.ShiftImm = ShiftImm;
2797 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt,
2799 auto Op = make_unique<ARMOperand>(k_MemBarrierOpt);
2800 Op->MBOpt.Val = Opt;
2806 static std::unique_ptr<ARMOperand>
2808 auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt);
2809 Op->ISBOpt.Val = Opt;
2817 auto Op = make_unique<ARMOperand>(k_ProcIFlags);
2824 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S) {
2825 auto Op = make_unique<ARMOperand>(k_MSRMask);
2826 Op->MMask.Val = MMask;
2832 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S) {
2833 auto Op = make_unique<ARMOperand>(k_BankedReg);
2834 Op->BankedReg.Val =
Reg;
2849 OS <<
"<ccout " <<
getReg() <<
">";
2851 case k_ITCondMask: {
2852 static const char *
const MaskStr[] = {
2853 "()",
"(t)",
"(e)",
"(tt)",
"(et)",
"(te)",
"(ee)",
"(ttt)",
"(ett)",
2854 "(tet)",
"(eet)",
"(tte)",
"(ete)",
"(tee)",
"(eee)"
2856 assert((ITMask.Mask & 0xf) == ITMask.Mask);
2857 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
2861 OS <<
"<coprocessor number: " << getCoproc() <<
">";
2864 OS <<
"<coprocessor register: " << getCoproc() <<
">";
2866 case k_CoprocOption:
2867 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
2870 OS <<
"<mask: " << getMSRMask() <<
">";
2873 OS <<
"<banked reg: " << getBankedReg() <<
">";
2878 case k_MemBarrierOpt:
2879 OS <<
"<ARM_MB::" <<
MemBOptToString(getMemBarrierOpt(),
false) <<
">";
2881 case k_InstSyncBarrierOpt:
2886 <<
" base:" <<
Memory.BaseRegNum;
2889 case k_PostIndexRegister:
2890 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
2891 << PostIdxReg.RegNum;
2894 << PostIdxReg.ShiftImm;
2897 case k_ProcIFlags: {
2898 OS <<
"<ARM_PROC::";
2899 unsigned IFlags = getProcIFlags();
2900 for (
int i=2; i >= 0; --i)
2901 if (IFlags & (1 << i))
2907 OS <<
"<register " <<
getReg() <<
">";
2909 case k_ShifterImmediate:
2910 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
2911 <<
" #" << ShifterImm.Imm <<
">";
2913 case k_ShiftedRegister:
2914 OS <<
"<so_reg_reg "
2915 << RegShiftedReg.SrcReg <<
" "
2917 <<
" " << RegShiftedReg.ShiftReg <<
">";
2919 case k_ShiftedImmediate:
2920 OS <<
"<so_reg_imm "
2921 << RegShiftedImm.SrcReg <<
" "
2923 <<
" #" << RegShiftedImm.ShiftImm <<
">";
2925 case k_RotateImmediate:
2926 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
2928 case k_ModifiedImmediate:
2929 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
2930 << ModImm.Rot <<
")>";
2932 case k_BitfieldDescriptor:
2933 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
2934 <<
", width: " <<
Bitfield.Width <<
">";
2936 case k_RegisterList:
2937 case k_DPRRegisterList:
2938 case k_SPRRegisterList: {
2939 OS <<
"<register_list ";
2943 I = RegList.
begin(), E = RegList.
end();
I != E; ) {
2945 if (++I < E) OS <<
", ";
2952 OS <<
"<vector_list " << VectorList.Count <<
" * "
2953 << VectorList.RegNum <<
">";
2955 case k_VectorListAllLanes:
2956 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
2957 << VectorList.RegNum <<
">";
2959 case k_VectorListIndexed:
2960 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
2961 << VectorList.Count <<
" * " << VectorList.RegNum <<
">";
2967 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2979 bool ARMAsmParser::ParseRegister(
unsigned &RegNo,
2981 const AsmToken &Tok = getParser().getTok();
2984 RegNo = tryParseRegister();
2986 return (RegNo == (
unsigned)-1);
2993 int ARMAsmParser::tryParseRegister() {
3002 .Case(
"r13", ARM::SP)
3003 .
Case(
"r14", ARM::LR)
3004 .
Case(
"r15", ARM::PC)
3005 .
Case(
"ip", ARM::R12)
3007 .
Case(
"a1", ARM::R0)
3008 .
Case(
"a2", ARM::R1)
3010 .
Case(
"a4", ARM::R3)
3012 .
Case(
"v2", ARM::R5)
3014 .
Case(
"v4", ARM::R7)
3015 .
Case(
"v5", ARM::R8)
3016 .
Case(
"v6", ARM::R9)
3017 .
Case(
"v7", ARM::R10)
3018 .
Case(
"v8", ARM::R11)
3019 .
Case(
"sb", ARM::R9)
3020 .
Case(
"sl", ARM::R10)
3021 .
Case(
"fp", ARM::R11)
3030 if (Entry == RegisterReqs.
end())
3033 return Entry->getValue();
3037 if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
3075 std::unique_ptr<ARMOperand> PrevOp(
3077 if (!PrevOp->isReg())
3078 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
3079 int SrcReg = PrevOp->getReg();
3095 const MCExpr *ShiftExpr =
nullptr;
3096 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
3097 Error(ImmLoc,
"invalid immediate shift value");
3103 Error(ImmLoc,
"invalid immediate shift value");
3113 Error(ImmLoc,
"immediate shift value out of range");
3123 ShiftReg = tryParseRegister();
3124 if (ShiftReg == -1) {
3125 Error(L,
"expected immediate or register in shift operand");
3130 "expected immediate or register in shift operand");
3136 Operands.
push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
3140 Operands.
push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
3153 bool ARMAsmParser::tryParseRegisterWithWriteBack(
OperandVector &Operands) {
3156 int RegNo = tryParseRegister();
3179 if (getParser().parseExpression(ImmVal))
3183 return TokError(
"immediate value expected for vector index");
3211 if (Name.
size() < 2 || Name[0] != CoprocOp)
3215 switch (Name.
size()) {
3238 case '0':
return 10;
3239 case '1':
return 11;
3240 case '2':
return 12;
3241 case '3':
return 13;
3242 case '4':
return 14;
3243 case '5':
return 15;
3249 ARMAsmParser::OperandMatchResultTy
3255 return MatchOperand_NoMatch;
3276 return MatchOperand_NoMatch;
3281 return MatchOperand_Success;
3287 ARMAsmParser::OperandMatchResultTy
3288 ARMAsmParser::parseCoprocNumOperand(
OperandVector &Operands) {
3293 return MatchOperand_NoMatch;
3297 return MatchOperand_NoMatch;
3299 if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
3300 return MatchOperand_NoMatch;
3303 Operands.
push_back(ARMOperand::CreateCoprocNum(Num, S));
3304 return MatchOperand_Success;
3310 ARMAsmParser::OperandMatchResultTy
3311 ARMAsmParser::parseCoprocRegOperand(
OperandVector &Operands) {
3316 return MatchOperand_NoMatch;
3320 return MatchOperand_NoMatch;
3323 Operands.
push_back(ARMOperand::CreateCoprocReg(Reg, S));
3324 return MatchOperand_Success;
3329 ARMAsmParser::OperandMatchResultTy
3330 ARMAsmParser::parseCoprocOptionOperand(
OperandVector &Operands) {
3336 return MatchOperand_NoMatch;
3341 if (getParser().parseExpression(Expr)) {
3342 Error(Loc,
"illegal expression");
3343 return MatchOperand_ParseFail;
3347 Error(Loc,
"coprocessor option must be an immediate in range [0, 255]");
3348 return MatchOperand_ParseFail;
3354 return MatchOperand_ParseFail;
3358 Operands.
push_back(ARMOperand::CreateCoprocOption(Val, S, E));
3359 return MatchOperand_Success;
3369 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3373 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
3376 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
3377 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
3378 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
3379 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
3380 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
3388 case ARM::Q0:
return ARM::D0;
3389 case ARM::Q1:
return ARM::D2;
3390 case ARM::Q2:
return ARM::D4;
3391 case ARM::Q3:
return ARM::D6;
3392 case ARM::Q4:
return ARM::D8;
3393 case ARM::Q5:
return ARM::D10;
3394 case ARM::Q6:
return ARM::D12;
3395 case ARM::Q7:
return ARM::D14;
3396 case ARM::Q8:
return ARM::D16;
3397 case ARM::Q9:
return ARM::D18;
3398 case ARM::Q10:
return ARM::D20;
3399 case ARM::Q11:
return ARM::D22;
3400 case ARM::Q12:
return ARM::D24;
3401 case ARM::Q13:
return ARM::D26;
3402 case ARM::Q14:
return ARM::D28;
3403 case ARM::Q15:
return ARM::D30;
3408 bool ARMAsmParser::parseRegisterList(
OperandVector &Operands) {
3411 "Token is not a Left Curly Brace");
3418 int Reg = tryParseRegister();
3420 return Error(RegLoc,
"register expected");
3428 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3430 EReg = MRI->getEncodingValue(Reg);
3431 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3435 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3436 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
3437 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg))
3438 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
3439 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(Reg))
3440 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
3442 return Error(RegLoc,
"invalid register in register list");
3445 EReg = MRI->getEncodingValue(Reg);
3446 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3456 int EndReg = tryParseRegister();
3458 return Error(AfterMinusLoc,
"register expected");
3460 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
3468 return Error(AfterMinusLoc,
"invalid register in register list");
3470 if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
3471 return Error(AfterMinusLoc,
"bad range in register list");
3474 while (Reg != EndReg) {
3476 EReg = MRI->getEncodingValue(Reg);
3477 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3485 Reg = tryParseRegister();
3487 return Error(RegLoc,
"register expected");
3489 bool isQReg =
false;
3490 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3496 return Error(RegLoc,
"invalid register in register list");
3498 if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
3499 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3500 Warning(RegLoc,
"register list not in ascending order");
3502 return Error(RegLoc,
"register list not in ascending order");
3504 if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
3505 Warning(RegLoc,
"duplicated register (" + RegTok.
getString() +
3506 ") in register list");
3510 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
3512 return Error(RegLoc,
"non-contiguous register range");
3513 EReg = MRI->getEncodingValue(Reg);
3514 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3516 EReg = MRI->getEncodingValue(++Reg);
3517 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3527 Operands.
push_back(ARMOperand::CreateRegList(Registers, S, E));
3539 ARMAsmParser::OperandMatchResultTy ARMAsmParser::
3547 LaneKind = AllLanes;
3550 return MatchOperand_Success;
3560 if (getParser().parseExpression(LaneIndex)) {
3561 Error(Loc,
"illegal expression");
3562 return MatchOperand_ParseFail;
3566 Error(Loc,
"lane index must be empty or an integer");
3567 return MatchOperand_ParseFail;
3571 return MatchOperand_ParseFail;
3578 if (Val < 0 || Val > 7) {
3580 return MatchOperand_ParseFail;
3583 LaneKind = IndexedLane;
3584 return MatchOperand_Success;
3587 return MatchOperand_Success;
3591 ARMAsmParser::OperandMatchResultTy
3602 int Reg = tryParseRegister();
3604 return MatchOperand_NoMatch;
3605 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg)) {
3606 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
3607 if (Res != MatchOperand_Success)
3611 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 1,
false, S, E));
3614 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1,
false,
3618 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
3623 return MatchOperand_Success;
3625 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3627 OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
3628 if (Res != MatchOperand_Success)
3632 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3633 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3634 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 2,
false, S, E));
3637 Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3638 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3639 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2,
false,
3643 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
3648 return MatchOperand_Success;
3650 Error(S,
"vector register expected");
3651 return MatchOperand_ParseFail;
3655 return MatchOperand_NoMatch;
3660 int Reg = tryParseRegister();
3662 Error(RegLoc,
"register expected");
3663 return MatchOperand_ParseFail;
3667 unsigned FirstReg =
Reg;
3670 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3679 if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success)
3680 return MatchOperand_ParseFail;
3687 else if (Spacing == 2) {
3689 "sequential registers in double spaced list");
3690 return MatchOperand_ParseFail;
3694 int EndReg = tryParseRegister();
3696 Error(AfterMinusLoc,
"register expected");
3697 return MatchOperand_ParseFail;
3700 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
3707 if (!ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(EndReg)) {
3708 Error(AfterMinusLoc,
"invalid register in register list");
3709 return MatchOperand_ParseFail;
3713 Error(AfterMinusLoc,
"bad range in register list");
3714 return MatchOperand_ParseFail;
3718 unsigned NextLaneIndex;
3719 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
3720 MatchOperand_Success)
3721 return MatchOperand_ParseFail;
3722 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3723 Error(AfterMinusLoc,
"mismatched lane index in register list");
3724 return MatchOperand_ParseFail;
3728 Count += EndReg -
Reg;
3735 Reg = tryParseRegister();
3737 Error(RegLoc,
"register expected");
3738 return MatchOperand_ParseFail;
3746 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3749 else if (Spacing == 2) {
3751 "invalid register in double-spaced list (must be 'D' register')");
3752 return MatchOperand_ParseFail;
3755 if (Reg != OldReg + 1) {
3756 Error(RegLoc,
"non-contiguous register range");
3757 return MatchOperand_ParseFail;
3763 unsigned NextLaneIndex;
3765 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
3766 MatchOperand_Success)
3767 return MatchOperand_ParseFail;
3768 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3769 Error(LaneLoc,
"mismatched lane index in register list");
3770 return MatchOperand_ParseFail;
3778 Spacing = 1 + (Reg == OldReg + 2);
3781 if (Reg != OldReg + Spacing) {
3782 Error(RegLoc,
"non-contiguous register range");
3783 return MatchOperand_ParseFail;
3788 unsigned NextLaneIndex;
3790 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success)
3791 return MatchOperand_ParseFail;
3792 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
3793 Error(EndLoc,
"mismatched lane index in register list");
3794 return MatchOperand_ParseFail;
3800 return MatchOperand_ParseFail;
3811 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
3812 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3813 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3816 Operands.
push_back(ARMOperand::CreateVectorList(FirstReg, Count,
3817 (Spacing == 2), S, E));
3824 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
3825 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3826 FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3828 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
3833 Operands.
push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
3839 return MatchOperand_Success;
3843 ARMAsmParser::OperandMatchResultTy
3844 ARMAsmParser::parseMemBarrierOptOperand(
OperandVector &Operands) {
3878 return MatchOperand_NoMatch;
3888 const MCExpr *MemBarrierID;
3889 if (getParser().parseExpression(MemBarrierID)) {
3890 Error(Loc,
"illegal expression");
3891 return MatchOperand_ParseFail;
3896 Error(Loc,
"constant expression expected");
3897 return MatchOperand_ParseFail;
3902 Error(Loc,
"immediate value out of range");
3903 return MatchOperand_ParseFail;
3908 return MatchOperand_ParseFail;
3911 return MatchOperand_Success;
3915 ARMAsmParser::OperandMatchResultTy
3916 ARMAsmParser::parseInstSyncBarrierOptOperand(
OperandVector &Operands) {
3928 return MatchOperand_NoMatch;
3938 const MCExpr *ISBarrierID;
3939 if (getParser().parseExpression(ISBarrierID)) {
3940 Error(Loc,
"illegal expression");
3941 return MatchOperand_ParseFail;
3946 Error(Loc,
"constant expression expected");
3947 return MatchOperand_ParseFail;
3952 Error(Loc,
"immediate value out of range");
3953 return MatchOperand_ParseFail;
3958 return MatchOperand_ParseFail;
3960 Operands.
push_back(ARMOperand::CreateInstSyncBarrierOpt(
3962 return MatchOperand_Success;
3967 ARMAsmParser::OperandMatchResultTy
3968 ARMAsmParser::parseProcIFlagsOperand(
OperandVector &Operands) {
3973 return MatchOperand_NoMatch;
3978 unsigned IFlags = 0;
3979 if (IFlagsStr !=
"none") {
3980 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
3989 if (Flag == ~0U || (IFlags & Flag))
3990 return MatchOperand_NoMatch;
3998 return MatchOperand_Success;
4002 ARMAsmParser::OperandMatchResultTy
4003 ARMAsmParser::parseMSRMaskOperand(
OperandVector &Operands) {
4008 return MatchOperand_NoMatch;
4025 .Case(
"apsr", 0x800)
4026 .
Case(
"apsr_nzcvq", 0x800)
4027 .
Case(
"apsr_g", 0x400)
4028 .
Case(
"apsr_nzcvqg", 0xc00)
4029 .
Case(
"iapsr", 0x801)
4030 .
Case(
"iapsr_nzcvq", 0x801)
4031 .
Case(
"iapsr_g", 0x401)
4032 .
Case(
"iapsr_nzcvqg", 0xc01)
4033 .
Case(
"eapsr", 0x802)
4034 .
Case(
"eapsr_nzcvq", 0x802)
4035 .
Case(
"eapsr_g", 0x402)
4036 .
Case(
"eapsr_nzcvqg", 0xc02)
4037 .
Case(
"xpsr", 0x803)
4038 .
Case(
"xpsr_nzcvq", 0x803)
4039 .
Case(
"xpsr_g", 0x403)
4040 .
Case(
"xpsr_nzcvqg", 0xc03)
4041 .
Case(
"ipsr", 0x805)
4042 .
Case(
"epsr", 0x806)
4043 .
Case(
"iepsr", 0x807)
4046 .
Case(
"primask", 0x810)
4047 .
Case(
"basepri", 0x811)
4048 .
Case(
"basepri_max", 0x812)
4049 .
Case(
"faultmask", 0x813)
4050 .
Case(
"control", 0x814)
4053 if (FlagsVal == ~0U)
4054 return MatchOperand_NoMatch;
4056 if (!hasThumb2DSP() && (FlagsVal & 0x400))
4059 return MatchOperand_NoMatch;
4061 if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
4063 return MatchOperand_NoMatch;
4066 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
4067 return MatchOperand_Success;
4071 size_t Start = 0, Next = Mask.
find(
'_');
4073 std::string SpecReg = Mask.
slice(Start, Next).
lower();
4075 Flags = Mask.
slice(Next+1, Mask.
size());
4080 unsigned FlagsVal = 0;
4082 if (SpecReg ==
"apsr") {
4086 .
Case(
"nzcvqg", 0xc)
4089 if (FlagsVal == ~0U) {
4091 return MatchOperand_NoMatch;
4095 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
4097 if (Flags ==
"all" || Flags ==
"")
4099 for (
int i = 0, e = Flags.
size(); i != e; ++i) {
4109 if (FlagsVal == ~0U || (FlagsVal & Flag))
4110 return MatchOperand_NoMatch;
4114 return MatchOperand_NoMatch;
4125 if (SpecReg ==
"spsr")
4129 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
4130 return MatchOperand_Success;
4135 ARMAsmParser::OperandMatchResultTy
4136 ARMAsmParser::parseBankedRegOperand(
OperandVector &Operands) {
4141 return MatchOperand_NoMatch;
4147 .Case(
"r8_usr", 0x00)
4148 .
Case(
"r9_usr", 0x01)
4149 .
Case(
"r10_usr", 0x02)
4150 .
Case(
"r11_usr", 0x03)
4151 .
Case(
"r12_usr", 0x04)
4152 .
Case(
"sp_usr", 0x05)
4153 .
Case(
"lr_usr", 0x06)
4154 .
Case(
"r8_fiq", 0x08)
4155 .
Case(
"r9_fiq", 0x09)
4156 .
Case(
"r10_fiq", 0x0a)
4157 .
Case(
"r11_fiq", 0x0b)
4158 .
Case(
"r12_fiq", 0x0c)
4159 .
Case(
"sp_fiq", 0x0d)
4160 .
Case(
"lr_fiq", 0x0e)
4161 .
Case(
"lr_irq", 0x10)
4162 .
Case(
"sp_irq", 0x11)
4163 .
Case(
"lr_svc", 0x12)
4164 .
Case(
"sp_svc", 0x13)
4165 .
Case(
"lr_abt", 0x14)
4166 .
Case(
"sp_abt", 0x15)
4167 .
Case(
"lr_und", 0x16)
4168 .
Case(
"sp_und", 0x17)
4169 .
Case(
"lr_mon", 0x1c)
4170 .
Case(
"sp_mon", 0x1d)
4171 .
Case(
"elr_hyp", 0x1e)
4172 .
Case(
"sp_hyp", 0x1f)
4173 .
Case(
"spsr_fiq", 0x2e)
4174 .
Case(
"spsr_irq", 0x30)
4175 .
Case(
"spsr_svc", 0x32)
4176 .
Case(
"spsr_abt", 0x34)
4177 .
Case(
"spsr_und", 0x36)
4178 .
Case(
"spsr_mon", 0x3c)
4179 .
Case(
"spsr_hyp", 0x3e)
4182 if (Encoding == ~0U)
4183 return MatchOperand_NoMatch;
4186 Operands.
push_back(ARMOperand::CreateBankedReg(Encoding, S));
4187 return MatchOperand_Success;
4190 ARMAsmParser::OperandMatchResultTy
4197 return MatchOperand_ParseFail;
4200 std::string LowerOp = Op.
lower();
4201 std::string UpperOp = Op.
upper();
4202 if (ShiftName != LowerOp && ShiftName != UpperOp) {
4204 return MatchOperand_ParseFail;
4212 return MatchOperand_ParseFail;
4216 const MCExpr *ShiftAmount;
4219 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4220 Error(Loc,
"illegal expression");
4221 return MatchOperand_ParseFail;
4225 Error(Loc,
"constant expression expected");
4226 return MatchOperand_ParseFail;
4229 if (Val < Low || Val > High) {
4230 Error(Loc,
"immediate value out of range");
4231 return MatchOperand_ParseFail;
4234 Operands.
push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
4236 return MatchOperand_Success;
4239 ARMAsmParser::OperandMatchResultTy
4245 Error(S,
"'be' or 'le' operand expected");
4246 return MatchOperand_ParseFail;
4255 Error(S,
"'be' or 'le' operand expected");
4256 return MatchOperand_ParseFail;
4261 return MatchOperand_Success;
4269 ARMAsmParser::OperandMatchResultTy
4275 Error(S,
"shift operator 'asr' or 'lsl' expected");
4276 return MatchOperand_ParseFail;
4280 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
4282 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
4285 Error(S,
"shift operator 'asr' or 'lsl' expected");
4286 return MatchOperand_ParseFail;
4294 return MatchOperand_ParseFail;
4299 const MCExpr *ShiftAmount;
4301 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4302 Error(ExLoc,
"malformed shift expression");
4303 return MatchOperand_ParseFail;
4307 Error(ExLoc,
"shift amount must be an immediate");
4308 return MatchOperand_ParseFail;
4314 if (Val < 1 || Val > 32) {
4315 Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
4316 return MatchOperand_ParseFail;
4320 Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
4321 return MatchOperand_ParseFail;
4323 if (Val == 32) Val = 0;
4326 if (Val < 0 || Val > 31) {
4327 Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
4328 return MatchOperand_ParseFail;
4332 Operands.
push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
4334 return MatchOperand_Success;
4340 ARMAsmParser::OperandMatchResultTy
4346 return MatchOperand_NoMatch;
4348 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
4349 return MatchOperand_NoMatch;
4356 return MatchOperand_ParseFail;
4361 const MCExpr *ShiftAmount;
4363 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4364 Error(ExLoc,
"malformed rotate expression");
4365 return MatchOperand_ParseFail;
4369 Error(ExLoc,
"rotate amount must be an immediate");
4370 return MatchOperand_ParseFail;
4377 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
4378 Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
4379 return MatchOperand_ParseFail;
4382 Operands.
push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
4384 return MatchOperand_Success;
4387 ARMAsmParser::OperandMatchResultTy
4406 return MatchOperand_NoMatch;
4413 return MatchOperand_NoMatch;
4422 if (getParser().parseExpression(Imm1Exp, Ex1)) {
4423 Error(Sx1,
"malformed expression");
4424 return MatchOperand_ParseFail;
4435 Operands.
push_back(ARMOperand::CreateModImm((Enc & 0xFF),
4438 return MatchOperand_Success;
4448 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4449 return MatchOperand_Success;
4454 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4455 return MatchOperand_Success;
4460 Error(Sx1,
"expected modified immediate operand: #[0, 255], #even[0-30]");
4461 return MatchOperand_ParseFail;
4465 Error(Sx1,
"immediate operand must a number in the range [0, 255]");
4466 return MatchOperand_ParseFail;
4482 if (getParser().parseExpression(Imm2Exp, Ex2)) {
4483 Error(Sx2,
"malformed expression");
4484 return MatchOperand_ParseFail;
4491 if (!(Imm2 & ~0x1E)) {
4493 Operands.
push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
4494 return MatchOperand_Success;
4496 Error(Sx2,
"immediate operand must an even number in the range [0, 30]");
4497 return MatchOperand_ParseFail;
4499 Error(Sx2,
"constant expression expected");
4500 return MatchOperand_ParseFail;
4504 ARMAsmParser::OperandMatchResultTy
4512 return MatchOperand_ParseFail;
4518 if (getParser().parseExpression(LSBExpr)) {
4519 Error(E,
"malformed immediate expression");
4520 return MatchOperand_ParseFail;
4524 Error(E,
"'lsb' operand must be an immediate");
4525 return MatchOperand_ParseFail;
4530 if (LSB < 0 || LSB > 31) {
4531 Error(E,
"'lsb' operand must be in the range [0,31]");
4532 return MatchOperand_ParseFail;
4539 return MatchOperand_ParseFail;
4545 return MatchOperand_ParseFail;
4551 if (getParser().parseExpression(WidthExpr, EndLoc)) {
4552 Error(E,
"malformed immediate expression");
4553 return MatchOperand_ParseFail;
4557 Error(E,
"'width' operand must be an immediate");
4558 return MatchOperand_ParseFail;
4563 if (Width < 1 || Width > 32 - LSB) {
4564 Error(E,
"'width' operand must be in the range [1,32-lsb]");
4565 return MatchOperand_ParseFail;
4568 Operands.
push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
4570 return MatchOperand_Success;
4573 ARMAsmParser::OperandMatchResultTy
4586 bool haveEaten =
false;
4598 int Reg = tryParseRegister();
4601 return MatchOperand_NoMatch;
4603 return MatchOperand_ParseFail;
4607 unsigned ShiftImm = 0;
4610 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
4611 return MatchOperand_ParseFail;
4617 Operands.
push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
4620 return MatchOperand_Success;
4623 ARMAsmParser::OperandMatchResultTy
4649 if (getParser().parseExpression(Offset, E))
4650 return MatchOperand_ParseFail;
4653 Error(S,
"constant expression expected");
4654 return MatchOperand_ParseFail;
4658 if (isNegative && Val == 0)
4664 return MatchOperand_Success;
4668 bool haveEaten =
false;
4680 int Reg = tryParseRegister();
4683 return MatchOperand_NoMatch;
4685 return MatchOperand_ParseFail;
4691 return MatchOperand_Success;
4697 void ARMAsmParser::cvtThumbMultiply(
MCInst &Inst,
4699 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
4700 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
4704 if (Operands.
size() == 6 &&
4705 ((ARMOperand &)*Operands[4]).getReg() ==
4706 ((ARMOperand &)*Operands[3]).getReg())
4708 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
4710 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
4713 void ARMAsmParser::cvtThumbBranches(
MCInst &Inst,
4715 int CondOp = -1, ImmOp = -1;
4718 case ARM::tBcc: CondOp = 1; ImmOp = 2;
break;
4721 case ARM::t2Bcc: CondOp = 1; ImmOp = 3;
break;
4731 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
4732 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
4737 unsigned Cond =
static_cast<ARMOperand &
>(*Operands[CondOp]).getCondCode();
4754 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
4755 if (!op.isSignedOffset<11, 1>() && isThumbTwo())
4761 ARMOperand &op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
4762 if (!op.isSignedOffset<8, 1>() && isThumbTwo())
4767 ((ARMOperand &)*Operands[ImmOp]).addImmOperands(Inst, 1);
4768 ((ARMOperand &)*Operands[CondOp]).addCondCodeOperands(Inst, 2);
4777 "Token is not a Left Bracket");
4782 int BaseRegNum = tryParseRegister();
4783 if (BaseRegNum == -1)
4784 return Error(BaseRegTok.
getLoc(),
"register expected");
4790 return Error(Tok.getLoc(),
"malformed memory operand");
4793 E = Tok.getEndLoc();
4796 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
4811 "Lost colon or comma in memory operand?!");
4820 SMLoc AlignmentLoc = Tok.getLoc();
4823 if (getParser().parseExpression(Expr))
4831 return Error (E,
"constant expression expected");
4837 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4838 case 16: Align = 2;
break;
4839 case 32: Align = 4;
break;
4840 case 64: Align = 8;
break;
4841 case 128: Align = 16;
break;
4842 case 256: Align = 32;
break;
4853 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
4855 false, S, E, AlignmentLoc));
4879 if (getParser().parseExpression(Offset))
4887 return Error (E,
"constant expression expected");
4891 if (isNegative && Val == 0)
4902 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
4917 bool isNegative =
false;
4927 int OffsetRegNum = tryParseRegister();
4928 if (OffsetRegNum == -1)
4929 return Error(E,
"register expected");
4933 unsigned ShiftImm = 0;
4936 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
4946 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, OffsetRegNum,
4947 ShiftType, ShiftImm, 0, isNegative,
4972 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
4973 ShiftName ==
"asl" || ShiftName ==
"ASL")
4975 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
4977 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
4979 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
4981 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
4984 return Error(Loc,
"illegal shift operator");
4999 if (getParser().parseExpression(Expr))
5006 return Error(Loc,
"shift amount must be an immediate");
5011 return Error(Loc,
"immediate shift value out of range");
5025 ARMAsmParser::OperandMatchResultTy
5041 return MatchOperand_NoMatch;
5053 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*Operands[2]);
5054 bool isVmovf = TyOp.isToken() &&
5055 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64");
5056 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*Operands[0]);
5057 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
5058 Mnemonic.getToken() ==
"fconsts");
5059 if (!(isVmovf || isFconst))
5060 return MatchOperand_NoMatch;
5065 bool isNegative =
false;
5074 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5076 IntVal ^= (uint64_t)isNegative << 31;
5078 Operands.
push_back(ARMOperand::CreateImm(
5081 return MatchOperand_Success;
5088 if (Val > 255 || Val < 0) {
5089 Error(Loc,
"encoded floating point value out of range");
5090 return MatchOperand_ParseFail;
5093 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
5095 Operands.
push_back(ARMOperand::CreateImm(
5098 return MatchOperand_Success;
5101 Error(Loc,
"invalid floating point immediate");
5102 return MatchOperand_ParseFail;
5113 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
5114 if (ResTy == MatchOperand_Success)
5119 if (ResTy == MatchOperand_ParseFail)
5122 switch (getLexer().getKind()) {
5130 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
5132 if (!tryParseRegisterWithWriteBack(Operands))
5134 int Res = tryParseShiftRegister(Operands);
5140 if (Mnemonic ==
"vmrs" &&
5144 Operands.
push_back(ARMOperand::CreateToken(
"APSR_nzcv", S));
5160 if (getParser().parseExpression(IdVal))
5163 Operands.
push_back(ARMOperand::CreateImm(IdVal, S, E));
5167 return parseMemory(Operands);
5169 return parseRegisterList(Operands);
5179 if (getParser().parseExpression(ImmVal))
5184 if (isNegative && Val == 0)
5188 Operands.
push_back(ARMOperand::CreateImm(ImmVal, S, E));
5208 if (parsePrefix(RefKind))
5211 const MCExpr *SubExprVal;
5212 if (getParser().parseExpression(SubExprVal))
5218 Operands.
push_back(ARMOperand::CreateImm(ExprVal, S, E));
5222 if (Mnemonic !=
"ldr")
5226 const MCExpr *SubExprVal;
5227 if (getParser().parseExpression(SubExprVal))
5231 const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal);
5232 Operands.
push_back(ARMOperand::CreateImm(CPLoc, S, E));
5262 static const struct PrefixEntry {
5263 const char *Spelling;
5265 uint8_t SupportedFormats;
5266 } PrefixEntries[] = {
5275 [&IDVal](
const PrefixEntry &PE) {
5276 return PE.Spelling == IDVal;
5283 uint8_t CurrentFormat;
5284 switch (getContext().getObjectFileInfo()->getObjectFileType()) {
5286 CurrentFormat = MACHO;
5289 CurrentFormat = ELF;
5292 CurrentFormat = COFF;
5296 if (~
Prefix->SupportedFormats & CurrentFormat) {
5298 "cannot represent relocation in the current file format");
5302 RefKind =
Prefix->VariantKind;
5320 unsigned &PredicationCode,
5322 unsigned &ProcessorIMod,
5325 CarrySetting =
false;
5331 if ((Mnemonic ==
"movs" &&
isThumb()) ||
5332 Mnemonic ==
"teq" || Mnemonic ==
"vceq" || Mnemonic ==
"svc" ||
5333 Mnemonic ==
"mls" || Mnemonic ==
"smmls" || Mnemonic ==
"vcls" ||
5334 Mnemonic ==
"vmls" || Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" ||
5335 Mnemonic ==
"vcge" || Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" ||
5336 Mnemonic ==
"vaclt" || Mnemonic ==
"vacle" || Mnemonic ==
"hlt" ||
5337 Mnemonic ==
"vcgt" || Mnemonic ==
"vcle" || Mnemonic ==
"smlal" ||
5338 Mnemonic ==
"umaal" || Mnemonic ==
"umlal" || Mnemonic ==
"vabal" ||
5339 Mnemonic ==
"vmlal" || Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" ||
5340 Mnemonic ==
"fmuls" || Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" ||
5341 Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" ||
5342 Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" ||
5343 Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
5349 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
5350 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
5351 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
5352 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs") {
5373 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
5374 PredicationCode = CC;
5381 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" ||
5382 Mnemonic ==
"mrs" || Mnemonic ==
"smmls" || Mnemonic ==
"vabs" ||
5383 Mnemonic ==
"vcls" || Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" ||
5384 Mnemonic ==
"vnmls" || Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" ||
5385 Mnemonic ==
"vrsqrts" || Mnemonic ==
"srs" || Mnemonic ==
"flds" ||
5386 Mnemonic ==
"fmrs" || Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" ||
5387 Mnemonic ==
"fsts" || Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" ||
5388 Mnemonic ==
"fmuls" || Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" ||
5389 Mnemonic ==
"vfms" || Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" ||
5390 (Mnemonic ==
"movs" &&
isThumb()))) {
5391 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
5392 CarrySetting =
true;
5405 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
5406 ProcessorIMod =
IMod;
5412 ITMask = Mnemonic.
slice(2, Mnemonic.
size());
5413 Mnemonic = Mnemonic.
slice(0, 2);
5424 bool &CanAcceptCarrySet,
5425 bool &CanAcceptPredicationCode) {
5427 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5428 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
5429 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
5430 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
5431 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
5432 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
5433 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
5435 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
5436 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
5438 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
5439 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
5440 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
5442 Mnemonic.
startswith(
"vsel") || Mnemonic ==
"vmaxnm" ||
5443 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
5444 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
5445 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
5446 Mnemonic.
startswith(
"aes") || Mnemonic ==
"hvc" || Mnemonic ==
"setpan" ||
5450 CanAcceptPredicationCode =
false;
5453 CanAcceptPredicationCode =
5454 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
5455 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
5456 Mnemonic !=
"dmb" && Mnemonic !=
"dsb" && Mnemonic !=
"isb" &&
5457 Mnemonic !=
"pld" && Mnemonic !=
"pli" && Mnemonic !=
"pldw" &&
5458 Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" && Mnemonic !=
"stc2" &&
5459 Mnemonic !=
"stc2l" && !Mnemonic.
startswith(
"rfe") &&
5461 }
else if (isThumbOne()) {
5463 CanAcceptPredicationCode = Mnemonic !=
"movs";
5465 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
5467 CanAcceptPredicationCode =
true;
5474 void ARMAsmParser::tryConvertingToTwoOperandForm(
StringRef Mnemonic,
5477 if (Operands.
size() != 6)
5480 const auto &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
5481 auto &Op4 =
static_cast<ARMOperand &
>(*Operands[4]);
5482 if (!Op3.isReg() || !Op4.isReg())
5485 auto Op3Reg = Op3.getReg();
5486 auto Op4Reg = Op4.getReg();
5492 auto &Op5 =
static_cast<ARMOperand &
>(*Operands[5]);
5494 if (Mnemonic !=
"add")
5496 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
5497 (Op5.isReg() && Op5.getReg() == ARM::PC);
5498 if (!TryTransform) {
5499 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
5500 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
5501 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
5502 Op5.isImm() && !Op5.isImm0_508s4());
5506 }
else if (!isThumbOne())
5509 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
5510 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5511 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
5512 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
5518 bool Transform = Op3Reg == Op4Reg;
5523 const ARMOperand *LastOp = &Op5;
5525 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
5526 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
5527 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
5528 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
5539 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
5545 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
5556 bool ARMAsmParser::shouldOmitCCOutOperand(
StringRef Mnemonic,
5569 if (Mnemonic ==
"mov" && Operands.
size() > 4 && !
isThumb() &&
5570 !
static_cast<ARMOperand &
>(*Operands[4]).isModImm() &&
5571 static_cast<ARMOperand &
>(*Operands[4]).isImm0_65535Expr() &&
5572 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5577 if (
isThumb() && Mnemonic ==
"add" && Operands.
size() == 5 &&
5578 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5579 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5580 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5586 if (((
isThumb() && Mnemonic ==
"add") ||
5587 (isThumbTwo() && Mnemonic ==
"sub")) &&
5588 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5589 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5590 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::SP &&
5591 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5592 ((Mnemonic ==
"add" &&
static_cast<ARMOperand &
>(*Operands[5]).
isReg()) ||
5593 static_cast<ARMOperand &>(*Operands[5]).isImm0_1020s4()))
5600 if (isThumbTwo() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5601 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5602 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5603 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
5611 static_cast<ARMOperand &
>(*Operands[5]).isImm0_7())
5615 if (static_cast<ARMOperand &>(*Operands[4]).getReg() != ARM::PC &&
5616 static_cast<ARMOperand &
>(*Operands[5]).isT2SOImm())
5627 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 6 &&
5628 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5629 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5630 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5631 static_cast<ARMOperand &
>(*Operands[5]).
isReg() &&
5639 !inITBlock() || (
static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5640 static_cast<ARMOperand &
>(*Operands[5]).
getReg() &&
5641 static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5642 static_cast<ARMOperand &
>(*Operands[4]).
getReg())))
5647 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 5 &&
5648 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5649 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5650 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5666 if (
isThumb() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5667 (Operands.
size() == 5 || Operands.
size() == 6) &&
5668 static_cast<ARMOperand &>(*Operands[3]).isReg() &&
5669 static_cast<ARMOperand &
>(*Operands[3]).
getReg() == ARM::SP &&
5670 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5671 (
static_cast<ARMOperand &
>(*Operands[4]).isImm() ||
5672 (Operands.
size() == 6 &&
5673 static_cast<ARMOperand &
>(*Operands[5]).isImm())))
5679 bool ARMAsmParser::shouldOmitPredicateOperand(
StringRef Mnemonic,
5682 unsigned RegIdx = 3;
5683 if ((Mnemonic ==
"vrintz" || Mnemonic ==
"vrintx" || Mnemonic ==
"vrintr") &&
5684 static_cast<ARMOperand &>(*Operands[2]).
getToken() ==
".f32") {
5685 if (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
5686 static_cast<ARMOperand &>(*Operands[3]).
getToken() ==
".f32")
5689 if (static_cast<ARMOperand &>(*Operands[RegIdx]).
isReg() &&
5690 (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
5691 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg()) ||
5692 ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
5693 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg())))
5700 return Tok ==
".8" || Tok ==
".16" || Tok ==
".32" || Tok ==
".64" ||
5701 Tok ==
".i8" || Tok ==
".i16" || Tok ==
".i32" || Tok ==
".i64" ||
5702 Tok ==
".u8" || Tok ==
".u16" || Tok ==
".u32" || Tok ==
".u64" ||
5703 Tok ==
".s8" || Tok ==
".s16" || Tok ==
".s32" || Tok ==
".s64" ||
5704 Tok ==
".p8" || Tok ==
".p16" || Tok ==
".f32" || Tok ==
".f64" ||
5705 Tok ==
".f" || Tok ==
".d";
5715 unsigned VariantID);
5718 bool &AcceptSinglePrecisionOnly,
5719 bool &AcceptDoublePrecisionOnly) {
5720 if (Inst.
size() < 7)
5725 if (AddressingMode ==
"ia" || AddressingMode ==
"db" ||
5726 AddressingMode ==
"ea" || AddressingMode ==
"fd") {
5727 AcceptSinglePrecisionOnly = Inst[6] ==
's';
5728 AcceptDoublePrecisionOnly = Inst[6] ==
'd' || Inst[6] ==
'x';
5741 bool RequireVFPRegisterListCheck;
5742 bool AcceptSinglePrecisionOnly;
5743 bool AcceptDoublePrecisionOnly;
5744 RequireVFPRegisterListCheck =
5746 AcceptDoublePrecisionOnly);
5753 uint64_t AvailableFeatures = getAvailableFeatures();
5754 unsigned AssemblerDialect = getParser().getAssemblerDialect();
5760 parseDirectiveReq(Name, NameLoc);
5767 size_t Start = 0, Next = Name.
find(
'.');
5771 unsigned PredicationCode;
5772 unsigned ProcessorIMod;
5775 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
5776 ProcessorIMod, ITMask);
5779 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
5781 return Error(NameLoc,
"conditional execution not supported in Thumb1");
5784 Operands.
push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
5791 if (Mnemonic ==
"it") {
5793 if (ITMask.
size() > 3) {
5795 return Error(Loc,
"too many conditions on IT instruction");
5798 for (
unsigned i = ITMask.
size(); i != 0; --i) {
5799 char pos = ITMask[i - 1];
5800 if (pos !=
't' && pos !=
'e') {
5802 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
5805 if (ITMask[i - 1] ==
't')
5808 Operands.
push_back(ARMOperand::CreateITMask(Mask, Loc));
5821 bool CanAcceptCarrySet, CanAcceptPredicationCode;
5822 getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode);
5826 if (!CanAcceptCarrySet && CarrySetting) {
5828 return Error(NameLoc,
"instruction '" + Mnemonic +
5829 "' can not set flags, but 's' suffix specified");
5833 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
5835 return Error(NameLoc,
"instruction '" + Mnemonic +
5836 "' is not predicable, but condition code specified");
5840 if (CanAcceptCarrySet) {
5842 Operands.
push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
5847 if (CanAcceptPredicationCode) {
5850 Operands.
push_back(ARMOperand::CreateCondCode(
5855 if (ProcessorIMod) {
5856 Operands.
push_back(ARMOperand::CreateImm(
5859 }
else if (Mnemonic ==
"cps" && isMClass()) {
5860 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
5866 Next = Name.
find(
'.', Start + 1);
5876 if (ExtraToken ==
".n" && !
isThumb()) {
5879 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
5886 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
5888 Operands.
push_back(ARMOperand::CreateToken(ExtraToken, Loc));
5895 if (parseOperand(Operands, Mnemonic)) {
5904 if (parseOperand(Operands, Mnemonic)) {
5912 SMLoc Loc = getLexer().getLoc();
5914 return Error(Loc,
"unexpected token in argument list");
5919 if (RequireVFPRegisterListCheck) {
5920 ARMOperand &Op =
static_cast<ARMOperand &
>(*Operands.
back());
5921 if (AcceptSinglePrecisionOnly && !Op.isSPRRegList())
5922 return Error(Op.getStartLoc(),
5923 "VFP/Neon single precision register expected");
5924 if (AcceptDoublePrecisionOnly && !Op.isDPRRegList())
5925 return Error(Op.getStartLoc(),
5926 "VFP/Neon double precision register expected");
5929 tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
5938 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands))
5944 if (shouldOmitPredicateOperand(Mnemonic, Operands))
5952 if (!
isThumb() && Mnemonic ==
"blx" && Operands.
size() == 3 &&
5953 static_cast<ARMOperand &
>(*Operands[2]).isImm())
5963 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
5964 Mnemonic ==
"stlexd")) {
5965 bool isLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
5966 unsigned Idx = isLoad ? 2 : 3;
5967 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*Operands[Idx]);
5968 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[Idx + 1]);
5972 if (Op1.isReg() && Op2.isReg() && MRC.
contains(Op1.getReg()) &&
5974 unsigned Reg1 = Op1.getReg();
5975 unsigned Reg2 = Op2.getReg();
5976 unsigned Rt = MRI->getEncodingValue(Reg1);
5977 unsigned Rt2 = MRI->getEncodingValue(Reg2);
5980 if (Rt + 1 != Rt2 || (Rt & 1)) {
5981 Error(Op2.getStartLoc(), isLoad
5982 ?
"destination operands must be sequential"
5983 :
"source operands must be sequential");
5986 unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
5987 &(MRI->getRegClass(ARM::GPRPairRegClassID)));
5989 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
5995 if ((Mnemonic ==
"ldrd" || Mnemonic ==
"strd")) {
5996 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[2]);
5997 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
5999 assert(Op2.isReg() &&
"expected register argument");
6001 unsigned SuperReg = MRI->getMatchingSuperReg(
6002 Op2.getReg(), ARM::gsub_0, &MRI->getRegClass(ARM::GPRPairRegClassID));
6004 assert(SuperReg &&
"expected register pair");
6006 unsigned PairedReg = MRI->getSubReg(SuperReg, ARM::gsub_1);
6009 Operands.
begin() + 3,
6010 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc()));
6019 if (isThumbTwo() && Mnemonic ==
"sub" && Operands.
size() == 6 &&
6020 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
6021 static_cast<ARMOperand &
>(*Operands[3]).
getReg() == ARM::PC &&
6022 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
6023 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::LR &&
6024 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
6025 Operands.
front() = ARMOperand::CreateToken(Name, NameLoc);
6037 unsigned Reg,
unsigned HiReg,
6039 containsReg =
false;
6065 return Inst.
getOpcode() == ARM::tBKPT ||
6072 bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
6074 unsigned ListNo,
bool IsARPop) {
6075 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6076 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6082 if (!IsARPop && ListContainsSP)
6083 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6084 "SP may not be in the register list");
6085 else if (ListContainsPC && ListContainsLR)
6086 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6087 "PC and LR may not be in the register list simultaneously");
6088 else if (inITBlock() && !lastInITBlock() && ListContainsPC)
6089 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6090 "instruction must be outside of IT block or the last "
6091 "instruction in an IT block");
6095 bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
6098 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6099 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6104 if (ListContainsSP && ListContainsPC)
6105 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6106 "SP and PC may not be in the register list");
6107 else if (ListContainsSP)
6108 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6109 "SP may not be in the register list");
6110 else if (ListContainsPC)
6111 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6112 "PC may not be in the register list");
6117 bool ARMAsmParser::validateInstruction(
MCInst &Inst,
6120 SMLoc Loc = Operands[0]->getStartLoc();
6127 if (ITState.FirstCond)
6128 ITState.FirstCond =
false;
6130 Bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
6133 return Error(Loc,
"instructions in IT block must be predicable");
6135 unsigned ITCond = Bit ? ITState.Cond :
6137 if (Cond != ITCond) {
6140 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
6141 if (static_cast<ARMOperand &>(*Operands[
I]).isCondCode())
6142 CondLoc = Operands[I]->getStartLoc();
6143 return Error(CondLoc,
"incorrect condition in IT block; got '" +
6145 "', but expected '" +
6153 return Error(Loc,
"predicated instructions must be in IT block");
6155 const unsigned Opcode = Inst.
getOpcode();
6159 case ARM::LDRD_POST: {
6163 if (RtReg == ARM::LR)
6164 return Error(Operands[3]->getStartLoc(),
6167 const unsigned Rt = MRI->getEncodingValue(RtReg);
6170 return Error(Operands[3]->getStartLoc(),
6171 "Rt must be even-numbered");
6176 return Error(Operands[3]->getStartLoc(),
6177 "destination operands must be sequential");
6179 if (Opcode == ARM::LDRD_PRE || Opcode == ARM::LDRD_POST) {
6183 if (Rn == Rt || Rn == Rt2)
6184 return Error(Operands[3]->getStartLoc(),
6185 "base register needs to be different from destination "
6192 case ARM::t2LDRD_PRE:
6193 case ARM::t2LDRD_POST: {
6198 return Error(Operands[3]->getStartLoc(),
6199 "destination operands can't be identical");
6205 if (RmReg == ARM::SP && !hasV8Ops())
6206 return Error(Operands[2]->getStartLoc(),
6207 "r13 (SP) is an unpredictable operand to BXJ");
6215 return Error(Operands[3]->getStartLoc(),
6216 "source operands must be sequential");
6220 case ARM::STRD_POST: {
6225 return Error(Operands[3]->getStartLoc(),
6226 "source operands must be sequential");
6229 case ARM::STR_PRE_IMM:
6230 case ARM::STR_PRE_REG:
6231 case ARM::STR_POST_IMM:
6232 case ARM::STR_POST_REG:
6234 case ARM::STRH_POST:
6235 case ARM::STRB_PRE_IMM:
6236 case ARM::STRB_PRE_REG:
6237 case ARM::STRB_POST_IMM:
6238 case ARM::STRB_POST_REG: {
6244 return Error(Operands[3]->getStartLoc(),
6245 "source register and base register can't be identical");
6248 case ARM::LDR_PRE_IMM:
6249 case ARM::LDR_PRE_REG:
6250 case ARM::LDR_POST_IMM:
6251 case ARM::LDR_POST_REG:
6253 case ARM::LDRH_POST:
6254 case ARM::LDRSH_PRE:
6255 case ARM::LDRSH_POST:
6256 case ARM::LDRB_PRE_IMM:
6257 case ARM::LDRB_PRE_REG:
6258 case ARM::LDRB_POST_IMM:
6259 case ARM::LDRB_POST_REG:
6260 case ARM::LDRSB_PRE:
6261 case ARM::LDRSB_POST: {
6267 return Error(Operands[3]->getStartLoc(),
6268 "destination register and base register can't be identical");
6276 if (Widthm1 >= 32 - LSB)
6277 return Error(Operands[5]->getStartLoc(),
6278 "bitfield width must be in range [1,32-lsb]");
6290 bool HasWritebackToken =
6291 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
6292 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
6293 bool ListContainsBase;
6295 return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
6296 "registers must be in range r0-r7");
6298 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
6299 return Error(Operands[2]->getStartLoc(),
6300 "writeback operator '!' expected");
6303 if (ListContainsBase && HasWritebackToken)
6304 return Error(Operands[3]->getStartLoc(),
6305 "writeback operator '!' not allowed when base register "
6306 "in register list");
6308 if (validatetLDMRegList(Inst, Operands, 3))
6312 case ARM::LDMIA_UPD:
6313 case ARM::LDMDB_UPD:
6314 case ARM::LDMIB_UPD:
6315 case ARM::LDMDA_UPD:
6321 return Error(Operands.
back()->getStartLoc(),
6322 "writeback register not allowed in register list");
6326 if (validatetLDMRegList(Inst, Operands, 3))
6331 if (validatetSTMRegList(Inst, Operands, 3))
6334 case ARM::t2LDMIA_UPD:
6335 case ARM::t2LDMDB_UPD:
6336 case ARM::t2STMIA_UPD:
6337 case ARM::t2STMDB_UPD: {
6339 return Error(Operands.
back()->getStartLoc(),
6340 "writeback register not allowed in register list");
6342 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
6343 if (validatetLDMRegList(Inst, Operands, 3))
6346 if (validatetSTMRegList(Inst, Operands, 3))
6351 case ARM::sysLDMIA_UPD:
6352 case ARM::sysLDMDA_UPD:
6353 case ARM::sysLDMDB_UPD:
6354 case ARM::sysLDMIB_UPD:
6356 return Error(Operands[4]->getStartLoc(),
6357 "writeback register only allowed on system LDM "
6358 "if PC in register-list");
6360 case ARM::sysSTMIA_UPD:
6361 case ARM::sysSTMDA_UPD:
6362 case ARM::sysSTMDB_UPD:
6363 case ARM::sysSTMIB_UPD:
6364 return Error(Operands[2]->getStartLoc(),
6365 "system STM cannot have writeback register");
6375 if (Operands.
size() == 6 && (((ARMOperand &)*Operands[3]).getReg() !=
6376 ((ARMOperand &)*Operands[5]).getReg()) &&
6377 (((ARMOperand &)*Operands[3]).getReg() !=
6378 ((ARMOperand &)*Operands[4]).getReg())) {
6379 return Error(Operands[3]->getStartLoc(),
6380 "destination register must match source register");
6388 bool ListContainsBase;
6391 return Error(Operands[2]->getStartLoc(),
6392 "registers must be in range r0-r7 or pc");
6393 if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
6398 bool ListContainsBase;
6401 return Error(Operands[2]->getStartLoc(),
6402 "registers must be in range r0-r7 or lr");
6403 if (validatetSTMRegList(Inst, Operands, 2))
6407 case ARM::tSTMIA_UPD: {
6408 bool ListContainsBase, InvalidLowList;
6410 0, ListContainsBase);
6411 if (InvalidLowList && !isThumbTwo())
6412 return Error(Operands[4]->getStartLoc(),
6413 "registers must be in range r0-r7");
6417 if (InvalidLowList && ListContainsBase)
6418 return Error(Operands[4]->getStartLoc(),
6419 "writeback operator '!' not allowed when base register "
6420 "in register list");
6422 if (validatetSTMRegList(Inst, Operands, 4))
6426 case ARM::tADDrSP: {
6429 if (!isThumbTwo() &&
6431 return Error(Operands[4]->getStartLoc(),
6432 "source register must be the same as destination");
6438 if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>())
6439 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6442 int op = (Operands[2]->isImm()) ? 2 : 3;
6443 if (!static_cast<ARMOperand &>(*Operands[op]).isSignedOffset<24, 1>())
6444 return Error(Operands[op]->getStartLoc(),
"branch target out of range");
6449 if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<8, 1>())
6450 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6453 int Op = (Operands[2]->isImm()) ? 2 : 3;
6454 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
6455 return Error(Operands[Op]->getStartLoc(),
"branch target out of range");
6460 case ARM::t2MOVTi16:
6468 int i = (Operands[3]->isImm()) ? 3 : 4;
6469 ARMOperand &Op =
static_cast<ARMOperand &
>(*Operands[i]);
6479 "immediate expression for mov requires :lower16: or :upper16");
6491 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6492 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6493 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6494 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6495 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6496 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6497 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
6498 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
6499 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
6502 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6503 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6504 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6505 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6506 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6508 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6509 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6510 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6511 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6512 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6514 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
6515 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
6516 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
6517 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
6518 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
6521 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6522 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6523 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6524 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
6525 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6526 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6527 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6528 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6529 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
6530 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6531 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
6532 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
6533 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
6534 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
6535 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
6538 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6539 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6540 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6541 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6542 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6543 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6544 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6545 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6546 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6547 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6548 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6549 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6550 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
6551 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
6552 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
6553 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
6554 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
6555 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
6558 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6559 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6560 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6561 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
6562 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6563 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6564 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6565 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6566 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
6567 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6568 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
6569 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
6570 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
6571 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
6572 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
6575 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6576 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6577 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6578 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6579 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6580 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
6581 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6582 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6583 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6584 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6585 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6586 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
6587 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
6588 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
6589 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
6590 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
6591 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
6592 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
6600 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
6601 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
6602 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
6603 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
6604 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
6605 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
6606 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
6607 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
6608 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
6611 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
6612 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
6613 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
6614 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
6615 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
6616 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
6617 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
6618 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
6619 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
6620 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
6621 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
6622 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
6623 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
6624 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
6625 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
6628 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
6629 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
6630 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
6631 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
6632 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
6633 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
6634 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
6635 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
6636 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
6637 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
6638 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
6639 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
6640 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
6641 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
6642 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
6643 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
6644 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
6645 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
6648 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
6649 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
6650 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
6651 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
6652 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
6653 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
6654 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
6655 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
6656 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
6657 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
6658 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
6659 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
6660 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
6661 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
6662 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
6665 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
6666 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
6667 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
6668 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
6669 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
6670 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
6671 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
6672 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
6673 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
6674 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
6675 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
6676 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
6677 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
6678 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
6679 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
6680 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
6681 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
6682 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
6685 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
6686 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
6687 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
6688 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
6689 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
6690 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
6691 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
6692 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
6693 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
6694 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
6695 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
6696 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
6697 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
6698 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
6699 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
6702 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
6703 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
6704 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
6705 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
6706 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
6707 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
6708 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
6709 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
6710 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
6711 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
6712 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
6713 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
6714 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
6715 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
6716 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
6717 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
6718 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
6719 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
6722 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
6723 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
6724 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
6725 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
6726 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
6727 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
6728 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
6729 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
6730 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
6731 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
6732 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
6733 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
6734 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
6735 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
6736 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
6737 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
6738 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
6739 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
6748 case ARM::LDRT_POST:
6749 case ARM::LDRBT_POST: {
6750 const unsigned Opcode =
6751 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
6752 : ARM::LDRBT_POST_IMM;
6766 case ARM::STRT_POST:
6767 case ARM::STRBT_POST: {
6768 const unsigned Opcode =
6769 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
6770 : ARM::STRBT_POST_IMM;
6802 MCSymbol *Dot = getContext().createTempSymbol();
6821 case ARM::t2LDRpcrel:
6825 !(
static_cast<ARMOperand &
>(*Operands[2]).isToken() &&
6826 static_cast<ARMOperand &
>(*Operands[2]).
getToken() ==
".w"))
6831 case ARM::t2LDRBpcrel:
6834 case ARM::t2LDRHpcrel:
6837 case ARM::t2LDRSBpcrel:
6840 case ARM::t2LDRSHpcrel:
6844 case ARM::VST1LNdWB_register_Asm_8:
6845 case ARM::VST1LNdWB_register_Asm_16:
6846 case ARM::VST1LNdWB_register_Asm_32: {
6864 case ARM::VST2LNdWB_register_Asm_8:
6865 case ARM::VST2LNdWB_register_Asm_16:
6866 case ARM::VST2LNdWB_register_Asm_32:
6867 case ARM::VST2LNqWB_register_Asm_16:
6868 case ARM::VST2LNqWB_register_Asm_32: {
6888 case ARM::VST3LNdWB_register_Asm_8:
6889 case ARM::VST3LNdWB_register_Asm_16:
6890 case ARM::VST3LNdWB_register_Asm_32:
6891 case ARM::VST3LNqWB_register_Asm_16:
6892 case ARM::VST3LNqWB_register_Asm_32: {
6914 case ARM::VST4LNdWB_register_Asm_8:
6915 case ARM::VST4LNdWB_register_Asm_16:
6916 case ARM::VST4LNdWB_register_Asm_32:
6917 case ARM::VST4LNqWB_register_Asm_16:
6918 case ARM::VST4LNqWB_register_Asm_32: {
6942 case ARM::VST1LNdWB_fixed_Asm_8:
6943 case ARM::VST1LNdWB_fixed_Asm_16:
6944 case ARM::VST1LNdWB_fixed_Asm_32: {
6962 case ARM::VST2LNdWB_fixed_Asm_8:
6963 case ARM::VST2LNdWB_fixed_Asm_16:
6964 case ARM::VST2LNdWB_fixed_Asm_32:
6965 case ARM::VST2LNqWB_fixed_Asm_16:
6966 case ARM::VST2LNqWB_fixed_Asm_32: {
6986 case ARM::VST3LNdWB_fixed_Asm_8:
6987 case ARM::VST3LNdWB_fixed_Asm_16:
6988 case ARM::VST3LNdWB_fixed_Asm_32:
6989 case ARM::VST3LNqWB_fixed_Asm_16:
6990 case ARM::VST3LNqWB_fixed_Asm_32: {
7012 case ARM::VST4LNdWB_fixed_Asm_8:
7013 case ARM::VST4LNdWB_fixed_Asm_16:
7014 case ARM::VST4LNdWB_fixed_Asm_32:
7015 case ARM::VST4LNqWB_fixed_Asm_16:
7016 case ARM::VST4LNqWB_fixed_Asm_32: {
7040 case ARM::VST1LNdAsm_8:
7041 case ARM::VST1LNdAsm_16:
7042 case ARM::VST1LNdAsm_32: {
7058 case ARM::VST2LNdAsm_8:
7059 case ARM::VST2LNdAsm_16:
7060 case ARM::VST2LNdAsm_32:
7061 case ARM::VST2LNqAsm_16:
7062 case ARM::VST2LNqAsm_32: {
7080 case ARM::VST3LNdAsm_8:
7081 case ARM::VST3LNdAsm_16:
7082 case ARM::VST3LNdAsm_32:
7083 case ARM::VST3LNqAsm_16:
7084 case ARM::VST3LNqAsm_32: {
7104 case ARM::VST4LNdAsm_8:
7105 case ARM::VST4LNdAsm_16:
7106 case ARM::VST4LNdAsm_32:
7107 case ARM::VST4LNqAsm_16:
7108 case ARM::VST4LNqAsm_32: {
7131 case ARM::VLD1LNdWB_register_Asm_8:
7132 case ARM::VLD1LNdWB_register_Asm_16:
7133 case ARM::VLD1LNdWB_register_Asm_32: {
7152 case ARM::VLD2LNdWB_register_Asm_8:
7153 case ARM::VLD2LNdWB_register_Asm_16:
7154 case ARM::VLD2LNdWB_register_Asm_32:
7155 case ARM::VLD2LNqWB_register_Asm_16:
7156 case ARM::VLD2LNqWB_register_Asm_32: {
7179 case ARM::VLD3LNdWB_register_Asm_8:
7180 case ARM::VLD3LNdWB_register_Asm_16:
7181 case ARM::VLD3LNdWB_register_Asm_32:
7182 case ARM::VLD3LNqWB_register_Asm_16:
7183 case ARM::VLD3LNqWB_register_Asm_32: {
7210 case ARM::VLD4LNdWB_register_Asm_8:
7211 case ARM::VLD4LNdWB_register_Asm_16:
7212 case ARM::VLD4LNdWB_register_Asm_32:
7213 case ARM::VLD4LNqWB_register_Asm_16:
7214 case ARM::VLD4LNqWB_register_Asm_32: {
7245 case ARM::VLD1LNdWB_fixed_Asm_8:
7246 case ARM::VLD1LNdWB_fixed_Asm_16:
7247 case ARM::VLD1LNdWB_fixed_Asm_32: {
7266 case ARM::VLD2LNdWB_fixed_Asm_8:
7267 case ARM::VLD2LNdWB_fixed_Asm_16:
7268 case ARM::VLD2LNdWB_fixed_Asm_32:
7269 case ARM::VLD2LNqWB_fixed_Asm_16:
7270 case ARM::VLD2LNqWB_fixed_Asm_32: {
7293 case ARM::VLD3LNdWB_fixed_Asm_8:
7294 case ARM::VLD3LNdWB_fixed_Asm_16:
7295 case ARM::VLD3LNdWB_fixed_Asm_32:
7296 case ARM::VLD3LNqWB_fixed_Asm_16:
7297 case ARM::VLD3LNqWB_fixed_Asm_32: {
7324 case ARM::VLD4LNdWB_fixed_Asm_8:
7325 case ARM::VLD4LNdWB_fixed_Asm_16:
7326 case ARM::VLD4LNdWB_fixed_Asm_32:
7327 case ARM::VLD4LNqWB_fixed_Asm_16:
7328 case ARM::VLD4LNqWB_fixed_Asm_32: {
7359 case ARM::VLD1LNdAsm_8:
7360 case ARM::VLD1LNdAsm_16:
7361 case ARM::VLD1LNdAsm_32: {
7378 case ARM::VLD2LNdAsm_8:
7379 case ARM::VLD2LNdAsm_16:
7380 case ARM::VLD2LNdAsm_32:
7381 case ARM::VLD2LNqAsm_16:
7382 case ARM::VLD2LNqAsm_32: {
7403 case ARM::VLD3LNdAsm_8:
7404 case ARM::VLD3LNdAsm_16:
7405 case ARM::VLD3LNdAsm_32:
7406 case ARM::VLD3LNqAsm_16:
7407 case ARM::VLD3LNqAsm_32: {
7432 case ARM::VLD4LNdAsm_8:
7433 case ARM::VLD4LNdAsm_16:
7434 case ARM::VLD4LNdAsm_32:
7435 case ARM::VLD4LNqAsm_16:
7436 case ARM::VLD4LNqAsm_32: {
7466 case ARM::VLD3DUPdAsm_8:
7467 case ARM::VLD3DUPdAsm_16:
7468 case ARM::VLD3DUPdAsm_32:
7469 case ARM::VLD3DUPqAsm_8:
7470 case ARM::VLD3DUPqAsm_16:
7471 case ARM::VLD3DUPqAsm_32: {
7488 case ARM::VLD3DUPdWB_fixed_Asm_8:
7489 case ARM::VLD3DUPdWB_fixed_Asm_16:
7490 case ARM::VLD3DUPdWB_fixed_Asm_32:
7491 case ARM::VLD3DUPqWB_fixed_Asm_8:
7492 case ARM::VLD3DUPqWB_fixed_Asm_16:
7493 case ARM::VLD3DUPqWB_fixed_Asm_32: {
7512 case ARM::VLD3DUPdWB_register_Asm_8:
7513 case ARM::VLD3DUPdWB_register_Asm_16:
7514 case ARM::VLD3DUPdWB_register_Asm_32:
7515 case ARM::VLD3DUPqWB_register_Asm_8:
7516 case ARM::VLD3DUPqWB_register_Asm_16:
7517 case ARM::VLD3DUPqWB_register_Asm_32: {
7537 case ARM::VLD3dAsm_8:
7538 case ARM::VLD3dAsm_16:
7539 case ARM::VLD3dAsm_32:
7540 case ARM::VLD3qAsm_8:
7541 case ARM::VLD3qAsm_16:
7542 case ARM::VLD3qAsm_32: {
7559 case ARM::VLD3dWB_fixed_Asm_8:
7560 case ARM::VLD3dWB_fixed_Asm_16:
7561 case ARM::VLD3dWB_fixed_Asm_32:
7562 case ARM::VLD3qWB_fixed_Asm_8:
7563 case ARM::VLD3qWB_fixed_Asm_16:
7564 case ARM::VLD3qWB_fixed_Asm_32: {
7583 case ARM::VLD3dWB_register_Asm_8:
7584 case ARM::VLD3dWB_register_Asm_16:
7585 case ARM::VLD3dWB_register_Asm_32:
7586 case ARM::VLD3qWB_register_Asm_8:
7587 case ARM::VLD3qWB_register_Asm_16:
7588 case ARM::VLD3qWB_register_Asm_32: {
7608 case ARM::VLD4DUPdAsm_8:
7609 case ARM::VLD4DUPdAsm_16:
7610 case ARM::VLD4DUPdAsm_32:
7611 case ARM::VLD4DUPqAsm_8:
7612 case ARM::VLD4DUPqAsm_16:
7613 case ARM::VLD4DUPqAsm_32: {
7632 case ARM::VLD4DUPdWB_fixed_Asm_8:
7633 case ARM::VLD4DUPdWB_fixed_Asm_16:
7634 case ARM::VLD4DUPdWB_fixed_Asm_32:
7635 case ARM::VLD4DUPqWB_fixed_Asm_8:
7636 case ARM::VLD4DUPqWB_fixed_Asm_16:
7637 case ARM::VLD4DUPqWB_fixed_Asm_32: {
7658 case ARM::VLD4DUPdWB_register_Asm_8:
7659 case ARM::VLD4DUPdWB_register_Asm_16:
7660 case ARM::VLD4DUPdWB_register_Asm_32:
7661 case ARM::VLD4DUPqWB_register_Asm_8:
7662 case ARM::VLD4DUPqWB_register_Asm_16:
7663 case ARM::VLD4DUPqWB_register_Asm_32: {
7685 case ARM::VLD4dAsm_8:
7686 case ARM::VLD4dAsm_16:
7687 case ARM::VLD4dAsm_32:
7688 case ARM::VLD4qAsm_8:
7689 case ARM::VLD4qAsm_16:
7690 case ARM::VLD4qAsm_32: {
7709 case ARM::VLD4dWB_fixed_Asm_8:
7710 case ARM::VLD4dWB_fixed_Asm_16:
7711 case ARM::VLD4dWB_fixed_Asm_32:
7712 case ARM::VLD4qWB_fixed_Asm_8:
7713 case ARM::VLD4qWB_fixed_Asm_16:
7714 case ARM::VLD4qWB_fixed_Asm_32: {
7735 case ARM::VLD4dWB_register_Asm_8:
7736 case ARM::VLD4dWB_register_Asm_16:
7737 case ARM::VLD4dWB_register_Asm_32:
7738 case ARM::VLD4qWB_register_Asm_8:
7739 case ARM::VLD4qWB_register_Asm_16:
7740 case ARM::VLD4qWB_register_Asm_32: {
7762 case ARM::VST3dAsm_8:
7763 case ARM::VST3dAsm_16:
7764 case ARM::VST3dAsm_32:
7765 case ARM::VST3qAsm_8:
7766 case ARM::VST3qAsm_16:
7767 case ARM::VST3qAsm_32: {
7784 case ARM::VST3dWB_fixed_Asm_8:
7785 case ARM::VST3dWB_fixed_Asm_16:
7786 case ARM::VST3dWB_fixed_Asm_32:
7787 case ARM::VST3qWB_fixed_Asm_8:
7788 case ARM::VST3qWB_fixed_Asm_16:
7789 case ARM::VST3qWB_fixed_Asm_32: {
7808 case ARM::VST3dWB_register_Asm_8:
7809 case ARM::VST3dWB_register_Asm_16:
7810 case ARM::VST3dWB_register_Asm_32:
7811 case ARM::VST3qWB_register_Asm_8:
7812 case ARM::VST3qWB_register_Asm_16:
7813 case ARM::VST3qWB_register_Asm_32: {
7833 case ARM::VST4dAsm_8:
7834 case ARM::VST4dAsm_16:
7835 case ARM::VST4dAsm_32:
7836 case ARM::VST4qAsm_8:
7837 case ARM::VST4qAsm_16:
7838 case ARM::VST4qAsm_32: {
7857 case ARM::VST4dWB_fixed_Asm_8:
7858 case ARM::VST4dWB_fixed_Asm_16:
7859 case ARM::VST4dWB_fixed_Asm_32:
7860 case ARM::VST4qWB_fixed_Asm_8:
7861 case ARM::VST4qWB_fixed_Asm_16:
7862 case ARM::VST4qWB_fixed_Asm_32: {
7883 case ARM::VST4dWB_register_Asm_8:
7884 case ARM::VST4dWB_register_Asm_16:
7885 case ARM::VST4dWB_register_Asm_32:
7886 case ARM::VST4qWB_register_Asm_8:
7887 case ARM::VST4qWB_register_Asm_16:
7888 case ARM::VST4qWB_register_Asm_32: {
7912 case ARM::t2ASRri: {
7916 !(static_cast<ARMOperand &>(*Operands[3]).isToken() &&
7917 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
".w")) {
7921 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
7922 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
7923 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
7942 case ARM::t2MOVSsr: {
7946 bool isNarrow =
false;
7951 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr))
7957 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
7958 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
7959 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
7960 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
7966 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
7973 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
7978 case ARM::t2MOVSsi: {
7982 bool isNarrow =
false;
7985 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi))
7991 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
7992 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
7993 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
7994 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
7995 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
7998 if (Amount == 32) Amount = 0;
8003 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8005 if (newOpc != ARM::t2RRX)
8011 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8055 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
8064 if (Opc == ARM::MOVsi)
8085 case ARM::t2LDMIA_UPD: {
8101 case ARM::t2STMDB_UPD: {
8117 case ARM::LDMIA_UPD:
8120 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"pop" &&
8135 case ARM::STMDB_UPD:
8138 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"push" &&
8151 case ARM::t2ADDri12:
8154 if (static_cast<ARMOperand &>(*Operands[0]).getToken() !=
"add" ||
8160 case ARM::t2SUBri12:
8163 if (static_cast<ARMOperand &>(*Operands[0]).
getToken() !=
"sub" ||
8190 case ARM::t2SUBri: {
8197 (
unsigned)Inst.getOperand(2).getImm() > 255 ||
8198 ((!inITBlock() && Inst.getOperand(5).
getReg() != ARM::CPSR) ||
8199 (inITBlock() && Inst.getOperand(5).
getReg() != 0)) ||
8200 (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
8201 static_cast<ARMOperand &>(*Operands[3]).
getToken() == ".w"))
8204 TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
8205 ARM::tADDi8 : ARM::tSUBi8);
8206 TmpInst.addOperand(Inst.getOperand(0));
8207 TmpInst.addOperand(Inst.getOperand(5));
8208 TmpInst.addOperand(Inst.getOperand(0));
8209 TmpInst.addOperand(Inst.getOperand(2));
8210 TmpInst.addOperand(Inst.getOperand(3));
8211 TmpInst.addOperand(Inst.getOperand(4));
8215 case ARM::t2ADDrr: {
8230 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
8231 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
".w"))
8243 case ARM::tADDrSP: {
8287 bool hasWritebackToken =
8288 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
8289 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
8290 bool listContainsBase;
8292 (!listContainsBase && !hasWritebackToken) ||
8293 (listContainsBase && hasWritebackToken)) {
8295 assert (isThumbTwo());
8296 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
8299 if (hasWritebackToken)
8306 case ARM::tSTMIA_UPD: {
8311 bool listContainsBase;
8314 assert (isThumbTwo());
8321 bool listContainsBase;
8327 assert (isThumbTwo());
8335 bool listContainsBase;
8338 assert (isThumbTwo());
8353 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8354 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8375 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8376 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8398 (!
static_cast<ARMOperand &
>(*Operands[2]).isToken() ||
8399 static_cast<ARMOperand &
>(*Operands[2]).
getToken() !=
".w")) {
8403 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
8404 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
8405 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
8406 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
8450 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
8451 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
8452 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
8453 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
8454 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
8455 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
8481 unsigned Mask = MO.
getImm();
8482 unsigned OrigMask = Mask;
8485 assert(Mask && TZ <= 3 &&
"illegal IT mask value!");
8486 Mask ^= (0xE << TZ) & 0xF;
8492 assert(!inITBlock() &&
"nested IT blocks?!");
8494 ITState.Mask = OrigMask;
8495 ITState.CurPosition = 0;
8496 ITState.FirstCond =
true;
8512 (!
static_cast<ARMOperand &
>(*Operands[3]).isToken() ||
8513 !
static_cast<ARMOperand &
>(*Operands[3]).
getToken().equals_lower(
8518 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
8519 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
8520 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
8521 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
8522 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
8523 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
8552 (!
static_cast<ARMOperand &
>(*Operands[3]).isToken() ||
8553 !
static_cast<ARMOperand &
>(*Operands[3]).
getToken().equals_lower(
8558 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
8559 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
8560 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
8561 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
8585 unsigned ARMAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
8592 "optionally flag setting instruction missing optional def operand");
8594 "operand count mismatch!");
8603 return Match_MnemonicFail;
8608 return Match_RequiresITBlock;
8611 return Match_RequiresNotITBlock;
8615 else if (Opc == ARM::tADDhirr && isThumbOne() && !hasV6MOps() &&
8618 return Match_RequiresThumb2;
8620 else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
8623 return Match_RequiresV6;
8624 return Match_Success;
8634 bool ARMAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
8637 bool MatchingInlineAsm) {
8639 unsigned MatchResult;
8641 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
8643 switch (MatchResult) {
8647 if (validateInstruction(Inst, Operands)) {
8650 forwardITPosition();
8655 bool wasInITBlock = inITBlock();
8665 if (wasInITBlock && hasV8Ops() &&
isThumb() &&
8667 Warning(IDLoc,
"deprecated instruction in IT block");
8674 forwardITPosition();
8684 case Match_MissingFeature: {
8685 assert(ErrorInfo &&
"Unknown missing feature!");
8688 std::string Msg =
"instruction requires:";
8690 for (
unsigned i = 0; i < (
sizeof(ErrorInfo)*8-1); ++i) {
8691 if (ErrorInfo & Mask) {
8697 return Error(IDLoc, Msg);
8699 case Match_InvalidOperand: {
8700 SMLoc ErrorLoc = IDLoc;
8701 if (ErrorInfo != ~0ULL) {
8702 if (ErrorInfo >= Operands.
size())
8703 return Error(IDLoc,
"too few operands for instruction");
8705 ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
8706 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
8709 return Error(ErrorLoc,
"invalid operand for instruction");
8711 case Match_MnemonicFail:
8712 return Error(IDLoc,
"invalid instruction",
8713 ((ARMOperand &)*Operands[0]).getLocRange());
8714 case Match_RequiresNotITBlock:
8715 return Error(IDLoc,
"flag setting instruction only valid outside IT block");
8716 case Match_RequiresITBlock:
8717 return Error(IDLoc,
"instruction only valid inside IT block");
8718 case Match_RequiresV6:
8719 return Error(IDLoc,
"instruction variant requires ARMv6 or later");
8720 case Match_RequiresThumb2:
8721 return Error(IDLoc,
"instruction variant requires Thumb2");
8722 case Match_ImmRange0_15: {
8723 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
8724 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
8725 return Error(ErrorLoc,
"immediate operand must be in the range [0,15]");
8727 case Match_ImmRange0_239: {
8728 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getStartLoc();
8729 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
8730 return Error(ErrorLoc,
"immediate operand must be in the range [0,239]");
8732 case Match_AlignedMemoryRequiresNone:
8733 case Match_DupAlignedMemoryRequiresNone:
8734 case Match_AlignedMemoryRequires16:
8735 case Match_DupAlignedMemoryRequires16:
8736 case Match_AlignedMemoryRequires32:
8737 case Match_DupAlignedMemoryRequires32:
8738 case Match_AlignedMemoryRequires64:
8739 case Match_DupAlignedMemoryRequires64:
8740 case Match_AlignedMemoryRequires64or128:
8741 case Match_DupAlignedMemoryRequires64or128:
8742 case Match_AlignedMemoryRequires64or128or256:
8744 SMLoc ErrorLoc = ((ARMOperand &)*Operands[ErrorInfo]).getAlignmentLoc();
8745 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
8746 switch (MatchResult) {
8749 case Match_AlignedMemoryRequiresNone:
8750 case Match_DupAlignedMemoryRequiresNone:
8751 return Error(ErrorLoc,
"alignment must be omitted");
8752 case Match_AlignedMemoryRequires16:
8753 case Match_DupAlignedMemoryRequires16:
8754 return Error(ErrorLoc,
"alignment must be 16 or omitted");
8755 case Match_AlignedMemoryRequires32:
8756 case Match_DupAlignedMemoryRequires32:
8757 return Error(ErrorLoc,
"alignment must be 32 or omitted");
8758 case Match_AlignedMemoryRequires64:
8759 case Match_DupAlignedMemoryRequires64:
8760 return Error(ErrorLoc,
"alignment must be 64 or omitted");
8761 case Match_AlignedMemoryRequires64or128:
8762 case Match_DupAlignedMemoryRequires64or128:
8763 return Error(ErrorLoc,
"alignment must be 64, 128 or omitted");
8764 case Match_AlignedMemoryRequires64or128or256:
8765 return Error(ErrorLoc,
"alignment must be 64, 128, 256 or omitted");
8774 bool ARMAsmParser::ParseDirective(
AsmToken DirectiveID) {
8776 getContext().getObjectFileInfo()->getObjectFileType();
8781 if (IDVal ==
".word")
8782 return parseLiteralValues(4, DirectiveID.
getLoc());
8783 else if (IDVal ==
".short" || IDVal ==
".hword")
8784 return parseLiteralValues(2, DirectiveID.
getLoc());
8785 else if (IDVal ==
".thumb")
8786 return parseDirectiveThumb(DirectiveID.
getLoc());
8787 else if (IDVal ==
".arm")
8788 return parseDirectiveARM(DirectiveID.
getLoc());
8789 else if (IDVal ==
".thumb_func")
8790 return parseDirectiveThumbFunc(DirectiveID.
getLoc());
8791 else if (IDVal ==
".code")
8792 return parseDirectiveCode(DirectiveID.
getLoc());
8793 else if (IDVal ==
".syntax")
8794 return parseDirectiveSyntax(DirectiveID.
getLoc());
8795 else if (IDVal ==
".unreq")
8796 return parseDirectiveUnreq(DirectiveID.
getLoc());
8797 else if (IDVal ==
".fnend")
8798 return parseDirectiveFnEnd(DirectiveID.
getLoc());
8799 else if (IDVal ==
".cantunwind")
8800 return parseDirectiveCantUnwind(DirectiveID.
getLoc());
8801 else if (IDVal ==
".personality")
8802 return parseDirectivePersonality(DirectiveID.
getLoc());
8803 else if (IDVal ==
".handlerdata")
8804 return parseDirectiveHandlerData(DirectiveID.
getLoc());
8805 else if (IDVal ==
".setfp")
8806 return parseDirectiveSetFP(DirectiveID.
getLoc());
8807 else if (IDVal ==
".pad")
8808 return parseDirectivePad(DirectiveID.
getLoc());
8809 else if (IDVal ==
".save")
8810 return parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
8811 else if (IDVal ==
".vsave")
8812 return parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
8813 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
8814 return parseDirectiveLtorg(DirectiveID.
getLoc());
8815 else if (IDVal ==
".even")
8816 return parseDirectiveEven(DirectiveID.
getLoc());
8817 else if (IDVal ==
".personalityindex")
8818 return parseDirectivePersonalityIndex(DirectiveID.
getLoc());
8819 else if (IDVal ==
".unwind_raw")
8820 return parseDirectiveUnwindRaw(DirectiveID.
getLoc());
8821 else if (IDVal ==
".movsp")
8822 return parseDirectiveMovSP(DirectiveID.
getLoc());
8823 else if (IDVal ==
".arch_extension")
8824 return parseDirectiveArchExtension(DirectiveID.
getLoc());
8825 else if (IDVal ==
".align")
8826 return parseDirectiveAlign(DirectiveID.
getLoc());
8827 else if (IDVal ==
".thumb_set")
8828 return parseDirectiveThumbSet(DirectiveID.
getLoc());
8830 if (!IsMachO && !IsCOFF) {
8831 if (IDVal ==
".arch")
8832 return parseDirectiveArch(DirectiveID.
getLoc());
8833 else if (IDVal ==
".cpu")
8834 return parseDirectiveCPU(DirectiveID.
getLoc());
8835 else if (IDVal ==
".eabi_attribute")
8836 return parseDirectiveEabiAttr(DirectiveID.
getLoc());
8837 else if (IDVal ==
".fpu")
8838 return parseDirectiveFPU(DirectiveID.
getLoc());
8839 else if (IDVal ==
".fnstart")
8840 return parseDirectiveFnStart(DirectiveID.
getLoc());
8841 else if (IDVal ==
".inst")
8842 return parseDirectiveInst(DirectiveID.
getLoc());
8843 else if (IDVal ==
".inst.n")
8844 return parseDirectiveInst(DirectiveID.
getLoc(),
'n');
8845 else if (IDVal ==
".inst.w")
8846 return parseDirectiveInst(DirectiveID.
getLoc(),
'w');
8847 else if (IDVal ==
".object_arch")
8848 return parseDirectiveObjectArch(DirectiveID.
getLoc());
8849 else if (IDVal ==
".tlsdescseq")
8850 return parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
8860 bool ARMAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
8865 if (getParser().parseExpression(Value)) {
8870 getParser().getStreamer().EmitValue(Value, Size);
8877 Error(L,
"unexpected token in directive");
8890 bool ARMAsmParser::parseDirectiveThumb(
SMLoc L) {
8893 Error(L,
"unexpected token in directive");
8899 Error(L,
"target does not support Thumb mode");
8906 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
8912 bool ARMAsmParser::parseDirectiveARM(
SMLoc L) {
8915 Error(L,
"unexpected token in directive");
8921 Error(L,
"target does not support ARM mode");
8928 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
8933 if (NextSymbolIsThumb) {
8934 getParser().getStreamer().EmitThumbFunc(Symbol);
8935 NextSymbolIsThumb =
false;
8941 bool ARMAsmParser::parseDirectiveThumbFunc(
SMLoc L) {
8943 const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
8952 Error(L,
"unexpected token in .thumb_func directive");
8957 getParser().getContext().getOrCreateSymbol(Tok.
getIdentifier());
8958 getParser().getStreamer().EmitThumbFunc(Func);
8970 NextSymbolIsThumb =
true;
8976 bool ARMAsmParser::parseDirectiveSyntax(
SMLoc L) {
8980 Error(L,
"unexpected token in .syntax directive");
8985 if (Mode ==
"unified" || Mode ==
"UNIFIED") {
8987 }
else if (Mode ==
"divided" || Mode ==
"DIVIDED") {
8988 Error(L,
"'.syntax divided' arm asssembly not supported");
8991 Error(L,
"unrecognized syntax mode in .syntax directive");
9008 bool ARMAsmParser::parseDirectiveCode(
SMLoc L) {
9012 Error(L,
"unexpected token in .code directive");
9016 if (Val != 16 && Val != 32) {
9017 Error(L,
"invalid operand to .code directive");
9030 Error(L,
"target does not support Thumb mode");
9036 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
9039 Error(L,
"target does not support ARM mode");
9045 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
9057 SMLoc SRegLoc, ERegLoc;
9058 if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
9060 Error(SRegLoc,
"register name expected");
9073 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second !=
Reg) {
9074 Error(SRegLoc,
"redefinition of '" + Name +
"' does not match original.");
9083 bool ARMAsmParser::parseDirectiveUnreq(
SMLoc L) {
9087 Error(L,
"unexpected input in .unreq directive.");
9097 bool ARMAsmParser::parseDirectiveArch(
SMLoc L) {
9098 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
9103 Error(L,
"Unknown arch name");
9107 getTargetStreamer().emitArch(ID);
9114 bool ARMAsmParser::parseDirectiveEabiAttr(
SMLoc L) {
9123 Error(TagLoc,
"attribute name not recognised: " + Name);
9139 Error(TagLoc,
"expected numeric constant");
9155 bool IsStringValue =
false;
9157 int64_t IntegerValue = 0;
9158 bool IsIntegerValue =
false;
9161 IsStringValue =
true;
9163 IsStringValue =
true;
9164 IsIntegerValue =
true;
9165 }
else if (Tag < 32 || Tag % 2 == 0)
9166 IsIntegerValue =
true;
9167 else if (Tag % 2 == 1)
9168 IsStringValue =
true;
9172 if (IsIntegerValue) {
9182 Error(ValueExprLoc,
"expected numeric constant");
9192 IsStringValue =
false;
9202 if (IsStringValue) {
9213 if (IsIntegerValue && IsStringValue) {
9215 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
9216 }
else if (IsIntegerValue)
9217 getTargetStreamer().emitAttribute(Tag, IntegerValue);
9218 else if (IsStringValue)
9219 getTargetStreamer().emitTextAttribute(Tag, StringValue);
9225 bool ARMAsmParser::parseDirectiveCPU(
SMLoc L) {
9226 StringRef CPU = getParser().parseStringToEndOfStatement().
trim();
9231 if (!STI.isCPUStringValid(CPU)) {
9232 Error(L,
"Unknown CPU name");
9236 STI.setDefaultFeatures(CPU);
9237 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
9243 bool ARMAsmParser::parseDirectiveFPU(
SMLoc L) {
9244 SMLoc FPUNameLoc = getTok().getLoc();
9245 StringRef FPU = getParser().parseStringToEndOfStatement().
trim();
9248 std::vector<const char *>
Features;
9250 Error(FPUNameLoc,
"Unknown FPU name");
9254 for (
auto Feature : Features)
9255 STI.ApplyFeatureFlag(Feature);
9256 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
9258 getTargetStreamer().emitFPU(ID);
9264 bool ARMAsmParser::parseDirectiveFnStart(
SMLoc L) {
9265 if (UC.hasFnStart()) {
9266 Error(L,
".fnstart starts before the end of previous one");
9267 UC.emitFnStartLocNotes();
9274 getTargetStreamer().emitFnStart();
9276 UC.recordFnStart(L);
9282 bool ARMAsmParser::parseDirectiveFnEnd(
SMLoc L) {
9284 if (!UC.hasFnStart()) {
9285 Error(L,
".fnstart must precede .fnend directive");
9290 getTargetStreamer().emitFnEnd();
9298 bool ARMAsmParser::parseDirectiveCantUnwind(
SMLoc L) {
9299 UC.recordCantUnwind(L);
9302 if (!UC.hasFnStart()) {
9303 Error(L,
".fnstart must precede .cantunwind directive");
9306 if (UC.hasHandlerData()) {
9307 Error(L,
".cantunwind can't be used with .handlerdata directive");
9308 UC.emitHandlerDataLocNotes();
9311 if (UC.hasPersonality()) {
9312 Error(L,
".cantunwind can't be used with .personality directive");
9313 UC.emitPersonalityLocNotes();
9317 getTargetStreamer().emitCantUnwind();
9323 bool ARMAsmParser::parseDirectivePersonality(
SMLoc L) {
9325 bool HasExistingPersonality = UC.hasPersonality();
9327 UC.recordPersonality(L);
9330 if (!UC.hasFnStart()) {
9331 Error(L,
".fnstart must precede .personality directive");
9334 if (UC.cantUnwind()) {
9335 Error(L,
".personality can't be used with .cantunwind directive");
9336 UC.emitCantUnwindLocNotes();
9339 if (UC.hasHandlerData()) {
9340 Error(L,
".personality must precede .handlerdata directive");
9341 UC.emitHandlerDataLocNotes();
9344 if (HasExistingPersonality) {
9346 Error(L,
"multiple personality directives");
9347 UC.emitPersonalityLocNotes();
9354 Error(L,
"unexpected input in .personality directive.");
9360 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
9361 getTargetStreamer().emitPersonality(PR);
9367 bool ARMAsmParser::parseDirectiveHandlerData(
SMLoc L) {
9368 UC.recordHandlerData(L);
9371 if (!UC.hasFnStart()) {
9372 Error(L,
".fnstart must precede .personality directive");
9375 if (UC.cantUnwind()) {
9376 Error(L,
".handlerdata can't be used with .cantunwind directive");
9377 UC.emitCantUnwindLocNotes();
9381 getTargetStreamer().emitHandlerData();
9387 bool ARMAsmParser::parseDirectiveSetFP(
SMLoc L) {
9390 if (!UC.hasFnStart()) {
9391 Error(L,
".fnstart must precede .setfp directive");
9394 if (UC.hasHandlerData()) {
9395 Error(L,
".setfp must precede .handlerdata directive");
9401 int FPReg = tryParseRegister();
9403 Error(FPRegLoc,
"frame pointer register expected");
9416 int SPReg = tryParseRegister();
9418 Error(SPRegLoc,
"stack pointer register expected");
9422 if (SPReg != ARM::SP && SPReg != UC.getFPReg()) {
9423 Error(SPRegLoc,
"register should be either $sp or the latest fp register");
9428 UC.saveFPReg(FPReg);
9442 const MCExpr *OffsetExpr;
9445 if (getParser().parseExpression(OffsetExpr, EndLoc)) {
9446 Error(ExLoc,
"malformed setfp offset");
9451 Error(ExLoc,
"setfp offset must be an immediate");
9458 getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg),
9459 static_cast<unsigned>(SPReg), Offset);
9465 bool ARMAsmParser::parseDirectivePad(
SMLoc L) {
9468 if (!UC.hasFnStart()) {
9469 Error(L,
".fnstart must precede .pad directive");
9472 if (UC.hasHandlerData()) {
9473 Error(L,
".pad must precede .handlerdata directive");
9485 const MCExpr *OffsetExpr;
9488 if (getParser().parseExpression(OffsetExpr, EndLoc)) {
9489 Error(ExLoc,
"malformed pad offset");
9494 Error(ExLoc,
"pad offset must be an immediate");
9498 getTargetStreamer().emitPad(CE->
getValue());
9505 bool ARMAsmParser::parseDirectiveRegSave(
SMLoc L,
bool IsVector) {
9507 if (!UC.hasFnStart()) {
9508 Error(L,
".fnstart must precede .save or .vsave directives");
9511 if (UC.hasHandlerData()) {
9512 Error(L,
".save or .vsave must precede .handlerdata directive");
9520 if (parseRegisterList(Operands))
9522 ARMOperand &Op = (ARMOperand &)*Operands[0];
9523 if (!IsVector && !Op.isRegList()) {
9524 Error(L,
".save expects GPR registers");
9527 if (IsVector && !Op.isDPRRegList()) {
9528 Error(L,
".vsave expects DPR registers");
9532 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
9540 bool ARMAsmParser::parseDirectiveInst(
SMLoc Loc,
char Suffix) {
9554 Error(Loc,
"cannot determine Thumb instruction size, "
9555 "use inst.n/inst.w instead");
9561 Error(Loc,
"width suffixes are invalid in ARM mode");
9569 Error(Loc,
"expected expression following directive");
9576 if (getParser().parseExpression(Expr)) {
9577 Error(Loc,
"expected expression");
9581 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
9583 Error(Loc,
"expected constant expression");
9590 Error(Loc,
"inst.n operand is too big, use inst.w instead");
9595 if (Value->
getValue() > 0xffffffff) {
9597 StringRef(Suffix ?
"inst.w" :
"inst") +
" operand is too big");
9605 getTargetStreamer().emitInst(Value->
getValue(), Suffix);
9611 Error(Loc,
"unexpected token in directive");
9624 bool ARMAsmParser::parseDirectiveLtorg(
SMLoc L) {
9625 getTargetStreamer().emitCurrentConstantPool();
9629 bool ARMAsmParser::parseDirectiveEven(
SMLoc L) {
9633 TokError(
"unexpected token in directive");
9638 getStreamer().InitSections(
false);
9639 Section = getStreamer().getCurrentSection().first;
9642 assert(Section &&
"must have section to emit alignment");
9644 getStreamer().EmitCodeAlignment(2);
9646 getStreamer().EmitValueToAlignment(2);
9653 bool ARMAsmParser::parseDirectivePersonalityIndex(
SMLoc L) {
9655 bool HasExistingPersonality = UC.hasPersonality();
9657 UC.recordPersonalityIndex(L);
9659 if (!UC.hasFnStart()) {
9661 Error(L,
".fnstart must precede .personalityindex directive");
9664 if (UC.cantUnwind()) {
9666 Error(L,
".personalityindex cannot be used with .cantunwind");
9667 UC.emitCantUnwindLocNotes();
9670 if (UC.hasHandlerData()) {
9672 Error(L,
".personalityindex must precede .handlerdata directive");
9673 UC.emitHandlerDataLocNotes();
9676 if (HasExistingPersonality) {
9678 Error(L,
"multiple personality directives");
9679 UC.emitPersonalityLocNotes();
9683 const MCExpr *IndexExpression;
9693 Error(IndexLoc,
"index must be a constant number");
9699 Error(IndexLoc,
"personality routine index should be in range [0-3]");
9703 getTargetStreamer().emitPersonalityIndex(CE->
getValue());
9709 bool ARMAsmParser::parseDirectiveUnwindRaw(
SMLoc L) {
9711 if (!UC.hasFnStart()) {
9713 Error(L,
".fnstart must precede .unwind_raw directives");
9717 int64_t StackOffset;
9719 const MCExpr *OffsetExpr;
9720 SMLoc OffsetLoc = getLexer().getLoc();
9722 getParser().parseExpression(OffsetExpr)) {
9723 Error(OffsetLoc,
"expected expression");
9730 Error(OffsetLoc,
"offset must be a constant");
9738 Error(getLexer().getLoc(),
"expected comma");
9748 SMLoc OpcodeLoc = getLexer().getLoc();
9750 Error(OpcodeLoc,
"expected opcode expression");
9757 Error(OpcodeLoc,
"opcode value must be a constant");
9762 const int64_t Opcode = OC->
getValue();
9763 if (Opcode & ~0xff) {
9764 Error(OpcodeLoc,
"invalid opcode");
9775 Error(getLexer().getLoc(),
"unexpected token in directive");
9783 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
9791 bool ARMAsmParser::parseDirectiveTLSDescSeq(
SMLoc L) {
9795 TokError(
"expected variable after '.tlsdescseq' directive");
9811 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
9817 bool ARMAsmParser::parseDirectiveMovSP(
SMLoc L) {
9819 if (!UC.hasFnStart()) {
9821 Error(L,
".fnstart must precede .movsp directives");
9824 if (UC.getFPReg() != ARM::SP) {
9826 Error(L,
"unexpected .movsp directive");
9831 int SPReg = tryParseRegister();
9834 Error(SPRegLoc,
"register expected");
9838 if (SPReg == ARM::SP || SPReg == ARM::PC) {
9840 Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
9855 const MCExpr *OffsetExpr;
9859 Error(OffsetLoc,
"malformed offset expression");
9866 Error(OffsetLoc,
"offset must be an immediate constant");
9873 getTargetStreamer().emitMovSP(SPReg, Offset);
9874 UC.saveFPReg(SPReg);
9881 bool ARMAsmParser::parseDirectiveObjectArch(
SMLoc L) {
9884 Error(getLexer().getLoc(),
"unexpected token");
9896 Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
9901 getTargetStreamer().emitObjectArch(ID);
9904 Error(getLexer().getLoc(),
"unexpected token");
9913 bool ARMAsmParser::parseDirectiveAlign(
SMLoc L) {
9920 if (getStreamer().getCurrentSection().first->UseCodeAlign())
9921 getStreamer().EmitCodeAlignment(4, 0);
9923 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
9930 bool ARMAsmParser::parseDirectiveThumbSet(
SMLoc L) {
9935 TokError(
"expected identifier after '.thumb_set'");
9941 TokError(
"expected comma after name '" + Name +
"'");
9950 Parser, Sym, Value))
9953 getTargetStreamer().emitThumbSet(Sym, Value);
9965 #define GET_REGISTER_MATCHER
9966 #define GET_SUBTARGET_FEATURE_NAME
9967 #define GET_MATCHER_IMPLEMENTATION
9968 #include "ARMGenAsmMatcher.inc"
9973 static const struct {
9980 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
9981 {
ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
9983 {ARM::FeatureHWDiv, ARM::FeatureHWDivARM} },
9984 {
ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
9985 {
ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
9987 {
ARM::AEK_SEC, Feature_HasV7, {ARM::FeatureTrustZone} },
9989 {
ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
10000 bool ARMAsmParser::parseDirectiveArchExtension(
SMLoc L) {
10004 Error(getLexer().getLoc(),
"unexpected token");
10013 bool EnableFeature =
true;
10015 EnableFeature =
false;
10020 Error(ExtLoc,
"unknown architectural extension: " + Name);
10023 if (Extension.Kind != FeatureKind)
10026 if (Extension.Features.none())
10029 if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck) {
10030 Error(ExtLoc,
"architectural extension '" + Name +
"' is not "
10031 "allowed for the current base architecture");
10036 ? (~STI.getFeatureBits() & Extension.Features)
10037 : ( STI.getFeatureBits() & Extension.Features);
10039 uint64_t Features =
10040 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
10041 setAvailableFeatures(Features);
10045 Error(ExtLoc,
"unknown architectural extension: " + Name);
10054 ARMOperand &Op =
static_cast<ARMOperand &
>(AsmOp);
10062 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
10064 return Match_Success;
10068 const MCExpr *SOExpr = Op.getImm();
10070 if (!SOExpr->evaluateAsAbsolute(Value))
10071 return Match_Success;
10072 assert((Value >= INT32_MIN && Value <= UINT32_MAX) &&
10073 "expression value must be representable in 32 bits");
10078 MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg()))
10079 return Match_Success;
10082 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
Represents a range in source code.
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.
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)
virtual const AsmToken peekTok(bool ShouldSkipSpace=true)=0
Look ahead at the next token to be lexed.
const char * getPointer() const
size_t size() const
size - Get the string size.
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.
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...
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 unsigned parseArch(StringRef Arch)
static unsigned parseArchExt(StringRef ArchExt)
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
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.
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Target specific streamer interface.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
const FeatureBitset Features
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
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.
StringSwitch & Case(const char(&S)[N], const T &Value)
static bool isThumb(const MCSubtargetInfo &STI)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
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 MCOperand createReg(unsigned Reg)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, unsigned Reg, unsigned HiReg, bool &containsReg)
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 ...
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static unsigned MatchRegisterName(StringRef Name)
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
static unsigned parseFPU(StringRef FPU)
static bool getFPUFeatures(unsigned FPUKind, std::vector< const char * > &Features)
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
Windows NT (Windows on ARM)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static unsigned getDRegFromQReg(unsigned QReg)
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.
static unsigned getFPReg(const MachineOperand &MO)
getFPReg - Return the X86::FPx register number for the specified operand.
static const struct @241 Extensions[]
.code16 (X86) / .code 16 (ARM)
unsigned getReg() const
Returns the register number.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, const SmallVectorImpl< BasicBlock * > &ExitBlocks, PredIteratorCache &PredCache, LoopInfo *LI)
Given an instruction in the loop, check to see if it has any uses that are outside the current loop...
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)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
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
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 bool containsReg(ArrayRef< unsigned > RegUnits, unsigned RegUnit)
Convenient wrapper for checking membership in RegisterOperands.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
unsigned short NumOperands
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...
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
const MCExpr * getExpr() const
A switch()-like statement whose cases are string literals.
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.
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...
static const char * InstSyncBOptToString(unsigned val)
StringRef trim(StringRef Chars=" \t\n\v\f\r") const
Return string with consecutive characters in Chars starting from the left and right removed...
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.
Interface to description of machine instruction set.
StringRef getStringContents() const
Get the contents of a string token (without quotes).
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
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(iterator I)
static unsigned getNextRegister(unsigned Reg)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
void setOpcode(unsigned Op)
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
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...
std::string upper() const
Convert the given ASCII string to uppercase.
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)
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
R Default(const T &Value) const
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 getReg(const void *D, unsigned RC, unsigned RegNo)
static const char * MemBOptToString(unsigned val, bool HasV8)
static unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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)
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...
static const fltSemantics IEEEsingle
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
void LLVMInitializeARMAsmParser()
Force static initialization.
unsigned getNumOperands() const
static unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
MCSubtargetInfo - Generic base class for all target subtargets.
static bool isMem(const MachineInstr *MI, unsigned Op)
static const char * getSubtargetFeatureName(uint64_t Val)
const ARM::ArchExtKind Kind
LLVM Value Representation.
static unsigned getSORegOffset(unsigned Op)
const MCOperandInfo * OpInfo
This class implements an extremely fast bulk output stream that can only output to a stream...
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")
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Represents a location in source code.
bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static float getFPImmFloat(unsigned Imm)
std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
static ShiftOpc getSORegShOp(unsigned Op)
bool empty() const
empty - Check if the string is empty.