68 #define DEBUG_TYPE "asm-parser" 77 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
78 cl::desc(
"Allow conditional instructions outdside of an IT block"),
80 "Accept in both ISAs, emit implicit ITs in Thumb"),
82 "Warn in ARM, reject in Thumb"),
84 "Accept in ARM, reject in Thumb"),
85 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
86 "Warn in ARM, emit implicit ITs in Thumb")));
88 static cl::opt<bool> AddBuildAttributes(
"arm-add-build-attributes",
100 Locs PersonalityIndexLocs;
101 Locs HandlerDataLocs;
105 UnwindContext(
MCAsmParser &
P) : Parser(P), FPReg(ARM::SP) {}
107 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
108 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
109 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
111 bool hasPersonality()
const {
112 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
115 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
116 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
117 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
118 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
119 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
121 void saveFPReg(
int Reg) { FPReg =
Reg; }
122 int getFPReg()
const {
return FPReg; }
124 void emitFnStartLocNotes()
const {
125 for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
127 Parser.
Note(*FI,
".fnstart was specified here");
130 void emitCantUnwindLocNotes()
const {
131 for (Locs::const_iterator UI = CantUnwindLocs.begin(),
132 UE = CantUnwindLocs.end(); UI != UE; ++UI)
133 Parser.
Note(*UI,
".cantunwind was specified here");
136 void emitHandlerDataLocNotes()
const {
137 for (Locs::const_iterator
HI = HandlerDataLocs.begin(),
138 HE = HandlerDataLocs.end();
HI != HE; ++
HI)
139 Parser.
Note(*
HI,
".handlerdata was specified here");
142 void emitPersonalityLocNotes()
const {
143 for (Locs::const_iterator PI = PersonalityLocs.begin(),
144 PE = PersonalityLocs.end(),
145 PII = PersonalityIndexLocs.begin(),
146 PIE = PersonalityIndexLocs.end();
147 PI != PE || PII != PIE;) {
148 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
149 Parser.
Note(*PI++,
".personality was specified here");
150 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
151 Parser.
Note(*PII++,
".personalityindex was specified here");
154 "at the same location");
159 FnStartLocs = Locs();
160 CantUnwindLocs = Locs();
161 PersonalityLocs = Locs();
162 HandlerDataLocs = Locs();
163 PersonalityIndexLocs = Locs();
173 assert(getParser().getStreamer().getTargetStreamer() &&
174 "do not have a target streamer");
182 bool NextSymbolIsThumb;
184 bool useImplicitITThumb()
const {
185 return ImplicitItMode == ImplicitItModeTy::Always ||
186 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
189 bool useImplicitITARM()
const {
190 return ImplicitItMode == ImplicitItModeTy::Always ||
191 ImplicitItMode == ImplicitItModeTy::ARMOnly;
206 unsigned CurPosition;
221 void flushPendingInstructions(
MCStreamer &Out)
override {
222 if (!inImplicitITBlock()) {
228 unsigned Mask = getITMaskEncoding();
237 for (
const MCInst &Inst : PendingConditionalInsts) {
240 PendingConditionalInsts.clear();
244 ITState.CurPosition = ~0U;
247 bool inITBlock() {
return ITState.CurPosition != ~0U; }
248 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
249 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
251 bool lastInITBlock() {
255 void forwardITPosition() {
256 if (!inITBlock())
return;
261 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
262 ITState.CurPosition = ~0U;
266 void rewindImplicitITPosition() {
267 assert(inImplicitITBlock());
268 assert(ITState.CurPosition > 1);
269 ITState.CurPosition--;
271 unsigned NewMask = 0;
272 NewMask |= ITState.Mask & (0xC << TZ);
273 NewMask |= 0x2 << TZ;
274 ITState.Mask = NewMask;
279 void discardImplicitITBlock() {
280 assert(inImplicitITBlock());
281 assert(ITState.CurPosition == 1);
282 ITState.CurPosition = ~0U;
286 unsigned getDRegFromQReg(
unsigned QReg)
const {
287 return MRI->
getSubReg(QReg, ARM::dsub_0);
291 unsigned getITMaskEncoding() {
293 unsigned Mask = ITState.Mask;
295 if ((ITState.Cond & 1) == 0) {
296 assert(Mask && TZ <= 3 &&
"illegal IT mask value!");
297 Mask ^= (0xE << TZ) & 0xF;
305 if (ITState.CurPosition == 1)
308 MaskBit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
315 void invertCurrentITCondition() {
316 if (ITState.CurPosition == 1) {
319 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
324 bool isITBlockFull() {
325 return inITBlock() && (ITState.Mask & 1);
331 assert(inImplicitITBlock());
333 assert(Cond == ITState.Cond ||
336 unsigned NewMask = 0;
338 NewMask |= ITState.Mask & (0xE << TZ);
340 NewMask |= (Cond == ITState.Cond) << TZ;
342 NewMask |= 1 << (TZ - 1);
343 ITState.Mask = NewMask;
347 void startImplicitITBlock() {
351 ITState.CurPosition = 1;
352 ITState.IsExplicit =
false;
362 ITState.CurPosition = 0;
363 ITState.IsExplicit =
true;
367 return getParser().Note(L, Msg, Range);
371 return getParser().Warning(L, Msg, Range);
375 return getParser().Error(L, Msg, Range);
379 unsigned ListNo,
bool IsARPop =
false);
383 int tryParseRegister();
391 unsigned &ShiftAmount);
392 bool parseLiteralValues(
unsigned Size,
SMLoc L);
393 bool parseDirectiveThumb(
SMLoc L);
394 bool parseDirectiveARM(
SMLoc L);
395 bool parseDirectiveThumbFunc(
SMLoc L);
396 bool parseDirectiveCode(
SMLoc L);
397 bool parseDirectiveSyntax(
SMLoc L);
399 bool parseDirectiveUnreq(
SMLoc L);
400 bool parseDirectiveArch(
SMLoc L);
401 bool parseDirectiveEabiAttr(
SMLoc L);
402 bool parseDirectiveCPU(
SMLoc L);
403 bool parseDirectiveFPU(
SMLoc L);
404 bool parseDirectiveFnStart(
SMLoc L);
405 bool parseDirectiveFnEnd(
SMLoc L);
406 bool parseDirectiveCantUnwind(
SMLoc L);
407 bool parseDirectivePersonality(
SMLoc L);
408 bool parseDirectiveHandlerData(
SMLoc L);
409 bool parseDirectiveSetFP(
SMLoc L);
410 bool parseDirectivePad(
SMLoc L);
411 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
412 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
413 bool parseDirectiveLtorg(
SMLoc L);
414 bool parseDirectiveEven(
SMLoc L);
415 bool parseDirectivePersonalityIndex(
SMLoc L);
416 bool parseDirectiveUnwindRaw(
SMLoc L);
417 bool parseDirectiveTLSDescSeq(
SMLoc L);
418 bool parseDirectiveMovSP(
SMLoc L);
419 bool parseDirectiveObjectArch(
SMLoc L);
420 bool parseDirectiveArchExtension(
SMLoc L);
421 bool parseDirectiveAlign(
SMLoc L);
422 bool parseDirectiveThumbSet(
SMLoc L);
425 bool &CarrySetting,
unsigned &ProcessorIMod,
428 bool &CanAcceptCarrySet,
429 bool &CanAcceptPredicationCode);
431 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
bool CarrySetting,
435 return getSTI().getFeatureBits()[ARM::ModeThumb];
438 bool isThumbOne()
const {
439 return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2];
442 bool isThumbTwo()
const {
443 return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2];
446 bool hasThumb()
const {
447 return getSTI().getFeatureBits()[ARM::HasV4TOps];
450 bool hasThumb2()
const {
451 return getSTI().getFeatureBits()[ARM::FeatureThumb2];
454 bool hasV6Ops()
const {
455 return getSTI().getFeatureBits()[ARM::HasV6Ops];
458 bool hasV6T2Ops()
const {
459 return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
462 bool hasV6MOps()
const {
463 return getSTI().getFeatureBits()[ARM::HasV6MOps];
466 bool hasV7Ops()
const {
467 return getSTI().getFeatureBits()[ARM::HasV7Ops];
470 bool hasV8Ops()
const {
471 return getSTI().getFeatureBits()[ARM::HasV8Ops];
474 bool hasV8MBaseline()
const {
475 return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
478 bool hasV8MMainline()
const {
479 return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps];
482 bool has8MSecExt()
const {
483 return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
486 bool hasARM()
const {
487 return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
490 bool hasDSP()
const {
491 return getSTI().getFeatureBits()[ARM::FeatureDSP];
494 bool hasD16()
const {
495 return getSTI().getFeatureBits()[ARM::FeatureD16];
498 bool hasV8_1aOps()
const {
499 return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
502 bool hasRAS()
const {
503 return getSTI().getFeatureBits()[ARM::FeatureRAS];
508 uint64_t FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
509 setAvailableFeatures(FB);
512 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
514 bool isMClass()
const {
515 return getSTI().getFeatureBits()[ARM::FeatureMClass];
521 #define GET_ASSEMBLER_HEADER 522 #include "ARMGenAsmMatcher.inc" 539 return parsePKHImm(O,
"lsl", 0, 31);
542 return parsePKHImm(O,
"asr", 1, 32);
564 bool isITBlockTerminator(
MCInst &Inst)
const;
567 bool Load,
bool ARMMode,
bool Writeback);
570 enum ARMMatchResultTy {
571 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
572 Match_RequiresNotITBlock,
574 Match_RequiresThumb2,
576 Match_RequiresFlagSetting,
577 #define GET_OPERAND_DIAGNOSTIC_TYPES 578 #include "ARMGenAsmMatcher.inc" 588 MRI = getContext().getRegisterInfo();
591 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
594 if (AddBuildAttributes)
595 getTargetStreamer().emitTargetAttributes(STI);
598 ITState.CurPosition = ~0U;
600 NextSymbolIsThumb =
false;
604 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
607 bool ParseDirective(
AsmToken DirectiveID)
override;
610 unsigned Kind)
override;
611 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
613 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
616 bool MatchingInlineAsm)
override;
619 bool MatchingInlineAsm,
bool &EmitInITBlock,
622 struct NearMissMessage {
627 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
637 void onLabelParsed(
MCSymbol *Symbol)
override;
652 k_InstSyncBarrierOpt,
653 k_TraceSyncBarrierOpt,
665 k_VectorListAllLanes,
672 k_ConstantPoolImmediate,
673 k_BitfieldDescriptor,
677 SMLoc StartLoc, EndLoc, AlignmentLoc;
688 struct CoprocOptionOp {
730 struct VectorListOp {
737 struct VectorIndexOp {
751 unsigned OffsetRegNum;
756 unsigned isNegative : 1;
759 struct PostIdxRegOp {
766 struct ShifterImmOp {
771 struct RegShiftedRegOp {
778 struct RegShiftedImmOp {
801 struct CoprocOptionOp CoprocOption;
802 struct MBOptOp MBOpt;
803 struct ISBOptOp ISBOpt;
804 struct TSBOptOp TSBOpt;
805 struct ITMaskOp ITMask;
806 struct IFlagsOp IFlags;
807 struct MMaskOp MMask;
808 struct BankedRegOp BankedReg;
811 struct VectorListOp VectorList;
812 struct VectorIndexOp VectorIndex;
814 struct MemoryOp Memory;
815 struct PostIdxRegOp PostIdxReg;
816 struct ShifterImmOp ShifterImm;
817 struct RegShiftedRegOp RegShiftedReg;
818 struct RegShiftedImmOp RegShiftedImm;
819 struct RotImmOp RotImm;
820 struct ModImmOp ModImm;
821 struct BitfieldOp Bitfield;
828 SMLoc getStartLoc()
const override {
return StartLoc; }
831 SMLoc getEndLoc()
const override {
return EndLoc; }
838 SMLoc getAlignmentLoc()
const {
839 assert(Kind == k_Memory &&
"Invalid access!");
844 assert(Kind == k_CondCode &&
"Invalid access!");
848 unsigned getCoproc()
const {
849 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
854 assert(Kind == k_Token &&
"Invalid access!");
858 unsigned getReg()
const override {
859 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
864 assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
865 Kind == k_SPRRegisterList) &&
"Invalid access!");
869 const MCExpr *getImm()
const {
870 assert(isImm() &&
"Invalid access!");
874 const MCExpr *getConstantPoolImm()
const {
875 assert(isConstantPoolImm() &&
"Invalid access!");
879 unsigned getVectorIndex()
const {
880 assert(Kind == k_VectorIndex &&
"Invalid access!");
881 return VectorIndex.Val;
885 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
890 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
895 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
900 assert(Kind == k_ProcIFlags &&
"Invalid access!");
904 unsigned getMSRMask()
const {
905 assert(Kind == k_MSRMask &&
"Invalid access!");
909 unsigned getBankedReg()
const {
910 assert(Kind == k_BankedReg &&
"Invalid access!");
911 return BankedReg.Val;
914 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
915 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
916 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
917 bool isCondCode()
const {
return Kind == k_CondCode; }
918 bool isCCOut()
const {
return Kind == k_CCOut; }
919 bool isITMask()
const {
return Kind == k_ITCondMask; }
920 bool isITCondCode()
const {
return Kind == k_CondCode; }
921 bool isImm()
const override {
922 return Kind == k_Immediate;
925 bool isARMBranchTarget()
const {
926 if (!isImm())
return false;
928 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
929 return CE->getValue() % 4 == 0;
934 bool isThumbBranchTarget()
const {
935 if (!isImm())
return false;
937 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
938 return CE->getValue() % 2 == 0;
944 template<
unsigned w
idth,
unsigned scale>
945 bool isUnsignedOffset()
const {
946 if (!isImm())
return false;
947 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
948 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
949 int64_t Val = CE->getValue();
951 int64_t Max = Align * ((1LL << width) - 1);
952 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
959 template<
unsigned w
idth,
unsigned scale>
960 bool isSignedOffset()
const {
961 if (!isImm())
return false;
962 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
963 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
964 int64_t Val = CE->getValue();
966 int64_t Max = Align * ((1LL << (width-1)) - 1);
967 int64_t Min = -Align * (1LL << (width-1));
968 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
977 bool isThumbMemPC()
const {
980 if (isa<MCSymbolRefExpr>(Imm.Val))
return true;
982 if (!CE)
return false;
986 if(!
Memory.OffsetImm ||
Memory.OffsetRegNum)
return false;
987 if(
Memory.BaseRegNum != ARM::PC)
return false;
988 Val =
Memory.OffsetImm->getValue();
991 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
994 bool isFPImm()
const {
995 if (!isImm())
return false;
997 if (!CE)
return false;
1002 template<
int64_t N,
int64_t M>
1003 bool isImmediate()
const {
1004 if (!isImm())
return false;
1006 if (!CE)
return false;
1008 return Value >=
N && Value <= M;
1011 template<
int64_t N,
int64_t M>
1012 bool isImmediateS4()
const {
1013 if (!isImm())
return false;
1015 if (!CE)
return false;
1017 return ((Value & 3) == 0) && Value >=
N && Value <= M;
1020 bool isFBits16()
const {
1021 return isImmediate<0, 17>();
1023 bool isFBits32()
const {
1024 return isImmediate<1, 33>();
1026 bool isImm8s4()
const {
1027 return isImmediateS4<-1020, 1020>();
1029 bool isImm0_1020s4()
const {
1030 return isImmediateS4<0, 1020>();
1032 bool isImm0_508s4()
const {
1033 return isImmediateS4<0, 508>();
1035 bool isImm0_508s4Neg()
const {
1036 if (!isImm())
return false;
1038 if (!CE)
return false;
1041 return ((Value & 3) == 0) && Value > 0 && Value <= 508;
1044 bool isImm0_4095Neg()
const {
1045 if (!isImm())
return false;
1047 if (!CE)
return false;
1052 if ((CE->
getValue() >> 32) > 0)
return false;
1054 return Value > 0 && Value < 4096;
1057 bool isImm0_7()
const {
1058 return isImmediate<0, 7>();
1061 bool isImm1_16()
const {
1062 return isImmediate<1, 16>();
1065 bool isImm1_32()
const {
1066 return isImmediate<1, 32>();
1069 bool isImm8_255()
const {
1070 return isImmediate<8, 255>();
1073 bool isImm256_65535Expr()
const {
1074 if (!isImm())
return false;
1078 if (!CE)
return true;
1080 return Value >= 256 && Value < 65536;
1083 bool isImm0_65535Expr()
const {
1084 if (!isImm())
return false;
1088 if (!CE)
return true;
1090 return Value >= 0 && Value < 65536;
1093 bool isImm24bit()
const {
1094 return isImmediate<0, 0xffffff + 1>();
1097 bool isImmThumbSR()
const {
1098 return isImmediate<1, 33>();
1101 bool isPKHLSLImm()
const {
1102 return isImmediate<0, 32>();
1105 bool isPKHASRImm()
const {
1106 return isImmediate<0, 33>();
1109 bool isAdrLabel()
const {
1112 if (isImm() && !isa<MCConstantExpr>(getImm()))
1116 if (!isImm())
return false;
1118 if (!CE)
return false;
1124 bool isT2SOImm()
const {
1127 if (isImm() && !isa<MCConstantExpr>(getImm())) {
1134 if (!isImm())
return false;
1136 if (!CE)
return false;
1141 bool isT2SOImmNot()
const {
1142 if (!isImm())
return false;
1144 if (!CE)
return false;
1150 bool isT2SOImmNeg()
const {
1151 if (!isImm())
return false;
1153 if (!CE)
return false;
1160 bool isSetEndImm()
const {
1161 if (!isImm())
return false;
1163 if (!CE)
return false;
1165 return Value == 1 || Value == 0;
1168 bool isReg()
const override {
return Kind == k_Register; }
1169 bool isRegList()
const {
return Kind == k_RegisterList; }
1170 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1171 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1172 bool isToken()
const override {
return Kind == k_Token; }
1173 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1174 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1175 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1176 bool isMem()
const override {
1177 if (Kind != k_Memory)
1180 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.BaseRegNum))
1182 if (
Memory.OffsetRegNum &&
1183 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
Memory.OffsetRegNum))
1187 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1188 bool isRegShiftedReg()
const {
1189 return Kind == k_ShiftedRegister &&
1190 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1191 RegShiftedReg.SrcReg) &&
1192 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1193 RegShiftedReg.ShiftReg);
1195 bool isRegShiftedImm()
const {
1196 return Kind == k_ShiftedImmediate &&
1197 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1198 RegShiftedImm.SrcReg);
1200 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1201 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1203 bool isModImmNot()
const {
1204 if (!isImm())
return false;
1206 if (!CE)
return false;
1211 bool isModImmNeg()
const {
1212 if (!isImm())
return false;
1214 if (!CE)
return false;
1220 bool isThumbModImmNeg1_7()
const {
1221 if (!isImm())
return false;
1223 if (!CE)
return false;
1225 return 0 < Value && Value < 8;
1228 bool isThumbModImmNeg8_255()
const {
1229 if (!isImm())
return false;
1231 if (!CE)
return false;
1233 return 7 < Value && Value < 256;
1236 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1237 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1238 bool isPostIdxRegShifted()
const {
1239 return Kind == k_PostIndexRegister &&
1240 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1242 bool isPostIdxReg()
const {
1245 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1249 return Memory.OffsetRegNum == 0 &&
Memory.OffsetImm ==
nullptr &&
1250 (alignOK ||
Memory.Alignment == Alignment);
1252 bool isMemPCRelImm12()
const {
1256 if (
Memory.BaseRegNum != ARM::PC)
1259 if (!
Memory.OffsetImm)
return true;
1260 int64_t Val =
Memory.OffsetImm->getValue();
1261 return (Val > -4096 && Val < 4096) ||
1262 (Val == std::numeric_limits<int32_t>::min());
1265 bool isAlignedMemory()
const {
1266 return isMemNoOffset(
true);
1269 bool isAlignedMemoryNone()
const {
1270 return isMemNoOffset(
false, 0);
1273 bool isDupAlignedMemoryNone()
const {
1274 return isMemNoOffset(
false, 0);
1277 bool isAlignedMemory16()
const {
1278 if (isMemNoOffset(
false, 2))
1280 return isMemNoOffset(
false, 0);
1283 bool isDupAlignedMemory16()
const {
1284 if (isMemNoOffset(
false, 2))
1286 return isMemNoOffset(
false, 0);
1289 bool isAlignedMemory32()
const {
1290 if (isMemNoOffset(
false, 4))
1292 return isMemNoOffset(
false, 0);
1295 bool isDupAlignedMemory32()
const {
1296 if (isMemNoOffset(
false, 4))
1298 return isMemNoOffset(
false, 0);
1301 bool isAlignedMemory64()
const {
1302 if (isMemNoOffset(
false, 8))
1304 return isMemNoOffset(
false, 0);
1307 bool isDupAlignedMemory64()
const {
1308 if (isMemNoOffset(
false, 8))
1310 return isMemNoOffset(
false, 0);
1313 bool isAlignedMemory64or128()
const {
1314 if (isMemNoOffset(
false, 8))
1316 if (isMemNoOffset(
false, 16))
1318 return isMemNoOffset(
false, 0);
1321 bool isDupAlignedMemory64or128()
const {
1322 if (isMemNoOffset(
false, 8))
1324 if (isMemNoOffset(
false, 16))
1326 return isMemNoOffset(
false, 0);
1329 bool isAlignedMemory64or128or256()
const {
1330 if (isMemNoOffset(
false, 8))
1332 if (isMemNoOffset(
false, 16))
1334 if (isMemNoOffset(
false, 32))
1336 return isMemNoOffset(
false, 0);
1339 bool isAddrMode2()
const {
1340 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1342 if (
Memory.OffsetRegNum)
return true;
1344 if (!
Memory.OffsetImm)
return true;
1345 int64_t Val =
Memory.OffsetImm->getValue();
1346 return Val > -4096 && Val < 4096;
1349 bool isAM2OffsetImm()
const {
1350 if (!isImm())
return false;
1353 if (!CE)
return false;
1355 return (Val == std::numeric_limits<int32_t>::min()) ||
1356 (Val > -4096 && Val < 4096);
1359 bool isAddrMode3()
const {
1363 if (isImm() && !isa<MCConstantExpr>(getImm()))
1365 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1369 if (
Memory.OffsetRegNum)
return true;
1371 if (!
Memory.OffsetImm)
return true;
1372 int64_t Val =
Memory.OffsetImm->getValue();
1375 return (Val > -256 && Val < 256) ||
1376 Val == std::numeric_limits<int32_t>::min();
1379 bool isAM3Offset()
const {
1386 if (!CE)
return false;
1389 return (Val > -256 && Val < 256) ||
1390 Val == std::numeric_limits<int32_t>::min();
1393 bool isAddrMode5()
const {
1397 if (isImm() && !isa<MCConstantExpr>(getImm()))
1399 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1401 if (
Memory.OffsetRegNum)
return false;
1403 if (!
Memory.OffsetImm)
return true;
1404 int64_t Val =
Memory.OffsetImm->getValue();
1405 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1406 Val == std::numeric_limits<int32_t>::min();
1409 bool isAddrMode5FP16()
const {
1413 if (isImm() && !isa<MCConstantExpr>(getImm()))
1415 if (!
isMem() ||
Memory.Alignment != 0)
return false;
1417 if (
Memory.OffsetRegNum)
return false;
1419 if (!
Memory.OffsetImm)
return true;
1420 int64_t Val =
Memory.OffsetImm->getValue();
1421 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1422 Val == std::numeric_limits<int32_t>::min();
1425 bool isMemTBB()
const {
1432 bool isMemTBH()
const {
1440 bool isMemRegOffset()
const {
1446 bool isT2MemRegOffset()
const {
1458 bool isMemThumbRR()
const {
1468 bool isMemThumbRIs4()
const {
1473 if (!
Memory.OffsetImm)
return true;
1474 int64_t Val =
Memory.OffsetImm->getValue();
1475 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1478 bool isMemThumbRIs2()
const {
1483 if (!
Memory.OffsetImm)
return true;
1484 int64_t Val =
Memory.OffsetImm->getValue();
1485 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1488 bool isMemThumbRIs1()
const {
1493 if (!
Memory.OffsetImm)
return true;
1494 int64_t Val =
Memory.OffsetImm->getValue();
1495 return Val >= 0 && Val <= 31;
1498 bool isMemThumbSPI()
const {
1503 if (!
Memory.OffsetImm)
return true;
1504 int64_t Val =
Memory.OffsetImm->getValue();
1505 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1508 bool isMemImm8s4Offset()
const {
1512 if (isImm() && !isa<MCConstantExpr>(getImm()))
1517 if (!
Memory.OffsetImm)
return true;
1518 int64_t Val =
Memory.OffsetImm->getValue();
1520 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1521 Val == std::numeric_limits<int32_t>::min();
1524 bool isMemImm0_1020s4Offset()
const {
1528 if (!
Memory.OffsetImm)
return true;
1529 int64_t Val =
Memory.OffsetImm->getValue();
1530 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1533 bool isMemImm8Offset()
const {
1537 if (
Memory.BaseRegNum == ARM::PC)
return false;
1539 if (!
Memory.OffsetImm)
return true;
1540 int64_t Val =
Memory.OffsetImm->getValue();
1541 return (Val == std::numeric_limits<int32_t>::min()) ||
1542 (Val > -256 && Val < 256);
1545 bool isMemPosImm8Offset()
const {
1549 if (!
Memory.OffsetImm)
return true;
1550 int64_t Val =
Memory.OffsetImm->getValue();
1551 return Val >= 0 && Val < 256;
1554 bool isMemNegImm8Offset()
const {
1558 if (
Memory.BaseRegNum == ARM::PC)
return false;
1560 if (!
Memory.OffsetImm)
return false;
1561 int64_t Val =
Memory.OffsetImm->getValue();
1562 return (Val == std::numeric_limits<int32_t>::min()) ||
1563 (Val > -256 && Val < 0);
1566 bool isMemUImm12Offset()
const {
1570 if (!
Memory.OffsetImm)
return true;
1571 int64_t Val =
Memory.OffsetImm->getValue();
1572 return (Val >= 0 && Val < 4096);
1575 bool isMemImm12Offset()
const {
1580 if (isImm() && !isa<MCConstantExpr>(getImm()))
1586 if (!
Memory.OffsetImm)
return true;
1587 int64_t Val =
Memory.OffsetImm->getValue();
1588 return (Val > -4096 && Val < 4096) ||
1589 (Val == std::numeric_limits<int32_t>::min());
1592 bool isConstPoolAsmImm()
const {
1595 return (isConstantPoolImm());
1598 bool isPostIdxImm8()
const {
1599 if (!isImm())
return false;
1601 if (!CE)
return false;
1603 return (Val > -256 && Val < 256) ||
1604 (Val == std::numeric_limits<int32_t>::min());
1607 bool isPostIdxImm8s4()
const {
1608 if (!isImm())
return false;
1610 if (!CE)
return false;
1612 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
1613 (Val == std::numeric_limits<int32_t>::min());
1616 bool isMSRMask()
const {
return Kind == k_MSRMask; }
1617 bool isBankedReg()
const {
return Kind == k_BankedReg; }
1618 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
1621 bool isSingleSpacedVectorList()
const {
1622 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
1625 bool isDoubleSpacedVectorList()
const {
1626 return Kind == k_VectorList && VectorList.isDoubleSpaced;
1629 bool isVecListOneD()
const {
1630 if (!isSingleSpacedVectorList())
return false;
1631 return VectorList.Count == 1;
1634 bool isVecListDPair()
const {
1635 if (!isSingleSpacedVectorList())
return false;
1636 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1640 bool isVecListThreeD()
const {
1641 if (!isSingleSpacedVectorList())
return false;
1642 return VectorList.Count == 3;
1645 bool isVecListFourD()
const {
1646 if (!isSingleSpacedVectorList())
return false;
1647 return VectorList.Count == 4;
1650 bool isVecListDPairSpaced()
const {
1651 if (Kind != k_VectorList)
return false;
1652 if (isSingleSpacedVectorList())
return false;
1653 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1657 bool isVecListThreeQ()
const {
1658 if (!isDoubleSpacedVectorList())
return false;
1659 return VectorList.Count == 3;
1662 bool isVecListFourQ()
const {
1663 if (!isDoubleSpacedVectorList())
return false;
1664 return VectorList.Count == 4;
1667 bool isSingleSpacedVectorAllLanes()
const {
1668 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
1671 bool isDoubleSpacedVectorAllLanes()
const {
1672 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
1675 bool isVecListOneDAllLanes()
const {
1676 if (!isSingleSpacedVectorAllLanes())
return false;
1677 return VectorList.Count == 1;
1680 bool isVecListDPairAllLanes()
const {
1681 if (!isSingleSpacedVectorAllLanes())
return false;
1682 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1686 bool isVecListDPairSpacedAllLanes()
const {
1687 if (!isDoubleSpacedVectorAllLanes())
return false;
1688 return VectorList.Count == 2;
1691 bool isVecListThreeDAllLanes()
const {
1692 if (!isSingleSpacedVectorAllLanes())
return false;
1693 return VectorList.Count == 3;
1696 bool isVecListThreeQAllLanes()
const {
1697 if (!isDoubleSpacedVectorAllLanes())
return false;
1698 return VectorList.Count == 3;
1701 bool isVecListFourDAllLanes()
const {
1702 if (!isSingleSpacedVectorAllLanes())
return false;
1703 return VectorList.Count == 4;
1706 bool isVecListFourQAllLanes()
const {
1707 if (!isDoubleSpacedVectorAllLanes())
return false;
1708 return VectorList.Count == 4;
1711 bool isSingleSpacedVectorIndexed()
const {
1712 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
1715 bool isDoubleSpacedVectorIndexed()
const {
1716 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
1719 bool isVecListOneDByteIndexed()
const {
1720 if (!isSingleSpacedVectorIndexed())
return false;
1721 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
1724 bool isVecListOneDHWordIndexed()
const {
1725 if (!isSingleSpacedVectorIndexed())
return false;
1726 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1729 bool isVecListOneDWordIndexed()
const {
1730 if (!isSingleSpacedVectorIndexed())
return false;
1731 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1734 bool isVecListTwoDByteIndexed()
const {
1735 if (!isSingleSpacedVectorIndexed())
return false;
1736 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
1739 bool isVecListTwoDHWordIndexed()
const {
1740 if (!isSingleSpacedVectorIndexed())
return false;
1741 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1744 bool isVecListTwoQWordIndexed()
const {
1745 if (!isDoubleSpacedVectorIndexed())
return false;
1746 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1749 bool isVecListTwoQHWordIndexed()
const {
1750 if (!isDoubleSpacedVectorIndexed())
return false;
1751 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1754 bool isVecListTwoDWordIndexed()
const {
1755 if (!isSingleSpacedVectorIndexed())
return false;
1756 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1759 bool isVecListThreeDByteIndexed()
const {
1760 if (!isSingleSpacedVectorIndexed())
return false;
1761 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
1764 bool isVecListThreeDHWordIndexed()
const {
1765 if (!isSingleSpacedVectorIndexed())
return false;
1766 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1769 bool isVecListThreeQWordIndexed()
const {
1770 if (!isDoubleSpacedVectorIndexed())
return false;
1771 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1774 bool isVecListThreeQHWordIndexed()
const {
1775 if (!isDoubleSpacedVectorIndexed())
return false;
1776 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
1779 bool isVecListThreeDWordIndexed()
const {
1780 if (!isSingleSpacedVectorIndexed())
return false;
1781 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
1784 bool isVecListFourDByteIndexed()
const {
1785 if (!isSingleSpacedVectorIndexed())
return false;
1786 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1789 bool isVecListFourDHWordIndexed()
const {
1790 if (!isSingleSpacedVectorIndexed())
return false;
1791 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1794 bool isVecListFourQWordIndexed()
const {
1795 if (!isDoubleSpacedVectorIndexed())
return false;
1796 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1799 bool isVecListFourQHWordIndexed()
const {
1800 if (!isDoubleSpacedVectorIndexed())
return false;
1801 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1804 bool isVecListFourDWordIndexed()
const {
1805 if (!isSingleSpacedVectorIndexed())
return false;
1806 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1809 bool isVectorIndex8()
const {
1810 if (Kind != k_VectorIndex)
return false;
1811 return VectorIndex.Val < 8;
1814 bool isVectorIndex16()
const {
1815 if (Kind != k_VectorIndex)
return false;
1816 return VectorIndex.Val < 4;
1819 bool isVectorIndex32()
const {
1820 if (Kind != k_VectorIndex)
return false;
1821 return VectorIndex.Val < 2;
1823 bool isVectorIndex64()
const {
1824 if (Kind != k_VectorIndex)
return false;
1825 return VectorIndex.Val < 1;
1828 bool isNEONi8splat()
const {
1829 if (!isImm())
return false;
1832 if (!CE)
return false;
1836 return Value >= 0 && Value < 256;
1840 if (isNEONByteReplicate(2))
1846 if (!CE)
return false;
1851 bool isNEONi16splatNot()
const {
1856 if (!CE)
return false;
1862 if (isNEONByteReplicate(4))
1868 if (!CE)
return false;
1873 bool isNEONi32splatNot()
const {
1878 if (!CE)
return false;
1883 static bool isValidNEONi32vmovImm(int64_t
Value) {
1886 return ((Value & 0xffffffffffffff00) == 0) ||
1887 ((Value & 0xffffffffffff00ff) == 0) ||
1888 ((Value & 0xffffffffff00ffff) == 0) ||
1889 ((Value & 0xffffffff00ffffff) == 0) ||
1890 ((Value & 0xffffffffffff00ff) == 0xff) ||
1891 ((Value & 0xffffffffff00ffff) == 0xffff);
1894 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
1895 assert((Width == 8 || Width == 16 || Width == 32) &&
1896 "Invalid element width");
1897 assert(NumElems * Width <= 64 &&
"Invalid result width");
1911 uint64_t
Mask = (1ull << Width) - 1;
1912 uint64_t Elem = Value &
Mask;
1913 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
1915 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
1918 for (
unsigned i = 1; i < NumElems; ++i) {
1920 if ((Value & Mask) != Elem)
1926 bool isNEONByteReplicate(
unsigned NumBytes)
const {
1927 return isNEONReplicate(8, NumBytes,
false);
1930 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
1931 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
1932 "Invalid source width");
1933 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
1934 "Invalid destination width");
1935 assert(FromW < ToW &&
"ToW is not less than FromW");
1938 template<
unsigned FromW,
unsigned ToW>
1939 bool isNEONmovReplicate()
const {
1940 checkNeonReplicateArgs(FromW, ToW);
1941 if (ToW == 64 && isNEONi64splat())
1943 return isNEONReplicate(FromW, ToW / FromW,
false);
1946 template<
unsigned FromW,
unsigned ToW>
1947 bool isNEONinvReplicate()
const {
1948 checkNeonReplicateArgs(FromW, ToW);
1949 return isNEONReplicate(FromW, ToW / FromW,
true);
1952 bool isNEONi32vmov()
const {
1953 if (isNEONByteReplicate(4))
1961 return isValidNEONi32vmovImm(CE->
getValue());
1964 bool isNEONi32vmovNeg()
const {
1965 if (!isImm())
return false;
1968 if (!CE)
return false;
1969 return isValidNEONi32vmovImm(~CE->
getValue());
1972 bool isNEONi64splat()
const {
1973 if (!isImm())
return false;
1976 if (!CE)
return false;
1979 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
1980 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff)
return false;
1984 template<
int64_t Angle,
int64_t Remainder>
1985 bool isComplexRotation()
const {
1986 if (!isImm())
return false;
1989 if (!CE)
return false;
1992 return (Value % Angle == Remainder && Value <= 270);
1999 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2005 void addARMBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2006 assert(N == 1 &&
"Invalid number of operands!");
2007 addExpr(Inst, getImm());
2010 void addThumbBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
2011 assert(N == 1 &&
"Invalid number of operands!");
2012 addExpr(Inst, getImm());
2015 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2016 assert(N == 2 &&
"Invalid number of operands!");
2022 void addCoprocNumOperands(
MCInst &Inst,
unsigned N)
const {
2023 assert(N == 1 &&
"Invalid number of operands!");
2027 void addCoprocRegOperands(
MCInst &Inst,
unsigned N)
const {
2028 assert(N == 1 &&
"Invalid number of operands!");
2032 void addCoprocOptionOperands(
MCInst &Inst,
unsigned N)
const {
2033 assert(N == 1 &&
"Invalid number of operands!");
2037 void addITMaskOperands(
MCInst &Inst,
unsigned N)
const {
2038 assert(N == 1 &&
"Invalid number of operands!");
2042 void addITCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
2043 assert(N == 1 &&
"Invalid number of operands!");
2047 void addCCOutOperands(
MCInst &Inst,
unsigned N)
const {
2048 assert(N == 1 &&
"Invalid number of operands!");
2052 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
2053 assert(N == 1 &&
"Invalid number of operands!");
2057 void addRegShiftedRegOperands(
MCInst &Inst,
unsigned N)
const {
2058 assert(N == 3 &&
"Invalid number of operands!");
2059 assert(isRegShiftedReg() &&
2060 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2067 void addRegShiftedImmOperands(
MCInst &Inst,
unsigned N)
const {
2068 assert(N == 2 &&
"Invalid number of operands!");
2069 assert(isRegShiftedImm() &&
2070 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2073 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2078 void addShifterImmOperands(
MCInst &Inst,
unsigned N)
const {
2079 assert(N == 1 &&
"Invalid number of operands!");
2084 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
2085 assert(N == 1 &&
"Invalid number of operands!");
2092 void addDPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2093 addRegListOperands(Inst, N);
2096 void addSPRRegListOperands(
MCInst &Inst,
unsigned N)
const {
2097 addRegListOperands(Inst, N);
2100 void addRotImmOperands(
MCInst &Inst,
unsigned N)
const {
2101 assert(N == 1 &&
"Invalid number of operands!");
2106 void addModImmOperands(
MCInst &Inst,
unsigned N)
const {
2107 assert(N == 1 &&
"Invalid number of operands!");
2111 return addImmOperands(Inst, N);
2116 void addModImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2117 assert(N == 1 &&
"Invalid number of operands!");
2123 void addModImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2124 assert(N == 1 &&
"Invalid number of operands!");
2130 void addThumbModImmNeg8_255Operands(
MCInst &Inst,
unsigned N)
const {
2131 assert(N == 1 &&
"Invalid number of operands!");
2137 void addThumbModImmNeg1_7Operands(
MCInst &Inst,
unsigned N)
const {
2138 assert(N == 1 &&
"Invalid number of operands!");
2144 void addBitfieldOperands(
MCInst &Inst,
unsigned N)
const {
2145 assert(N == 1 &&
"Invalid number of operands!");
2147 unsigned lsb = Bitfield.LSB;
2148 unsigned width = Bitfield.Width;
2151 (32 - (lsb + width)));
2155 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
2156 assert(N == 1 &&
"Invalid number of operands!");
2157 addExpr(Inst, getImm());
2160 void addFBits16Operands(
MCInst &Inst,
unsigned N)
const {
2161 assert(N == 1 &&
"Invalid number of operands!");
2166 void addFBits32Operands(
MCInst &Inst,
unsigned N)
const {
2167 assert(N == 1 &&
"Invalid number of operands!");
2172 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2173 assert(N == 1 &&
"Invalid number of operands!");
2179 void addImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2180 assert(N == 1 &&
"Invalid number of operands!");
2187 void addImm0_1020s4Operands(
MCInst &Inst,
unsigned N)
const {
2188 assert(N == 1 &&
"Invalid number of operands!");
2195 void addImm0_508s4NegOperands(
MCInst &Inst,
unsigned N)
const {
2196 assert(N == 1 &&
"Invalid number of operands!");
2203 void addImm0_508s4Operands(
MCInst &Inst,
unsigned N)
const {
2204 assert(N == 1 &&
"Invalid number of operands!");
2211 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
2212 assert(N == 1 &&
"Invalid number of operands!");
2219 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
2220 assert(N == 1 &&
"Invalid number of operands!");
2227 void addImmThumbSROperands(
MCInst &Inst,
unsigned N)
const {
2228 assert(N == 1 &&
"Invalid number of operands!");
2236 void addPKHASRImmOperands(
MCInst &Inst,
unsigned N)
const {
2237 assert(N == 1 &&
"Invalid number of operands!");
2245 void addT2SOImmNotOperands(
MCInst &Inst,
unsigned N)
const {
2246 assert(N == 1 &&
"Invalid number of operands!");
2253 void addT2SOImmNegOperands(
MCInst &Inst,
unsigned N)
const {
2254 assert(N == 1 &&
"Invalid number of operands!");
2261 void addImm0_4095NegOperands(
MCInst &Inst,
unsigned N)
const {
2262 assert(N == 1 &&
"Invalid number of operands!");
2269 void addUnsignedOffset_b8s2Operands(
MCInst &Inst,
unsigned N)
const {
2270 if(
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
2276 assert(SR &&
"Unknown value type!");
2280 void addThumbMemPCOperands(
MCInst &Inst,
unsigned N)
const {
2281 assert(N == 1 &&
"Invalid number of operands!");
2291 assert(SR &&
"Unknown value type!");
2297 assert(isa<MCConstantExpr>(
Memory.OffsetImm) &&
"Unknown value type!");
2301 void addMemBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2302 assert(N == 1 &&
"Invalid number of operands!");
2306 void addInstSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2307 assert(N == 1 &&
"Invalid number of operands!");
2311 void addTraceSyncBarrierOptOperands(
MCInst &Inst,
unsigned N)
const {
2312 assert(N == 1 &&
"Invalid number of operands!");
2316 void addMemNoOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2317 assert(N == 1 &&
"Invalid number of operands!");
2321 void addMemPCRelImm12Operands(
MCInst &Inst,
unsigned N)
const {
2322 assert(N == 1 &&
"Invalid number of operands!");
2323 int32_t Imm =
Memory.OffsetImm->getValue();
2327 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
2328 assert(N == 1 &&
"Invalid number of operands!");
2329 assert(isImm() &&
"Not an immediate!");
2333 if (!isa<MCConstantExpr>(getImm())) {
2343 void addAlignedMemoryOperands(
MCInst &Inst,
unsigned N)
const {
2344 assert(N == 2 &&
"Invalid number of operands!");
2349 void addDupAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2350 addAlignedMemoryOperands(Inst, N);
2353 void addAlignedMemoryNoneOperands(
MCInst &Inst,
unsigned N)
const {
2354 addAlignedMemoryOperands(Inst, N);
2357 void addAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2358 addAlignedMemoryOperands(Inst, N);
2361 void addDupAlignedMemory16Operands(
MCInst &Inst,
unsigned N)
const {
2362 addAlignedMemoryOperands(Inst, N);
2365 void addAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2366 addAlignedMemoryOperands(Inst, N);
2369 void addDupAlignedMemory32Operands(
MCInst &Inst,
unsigned N)
const {
2370 addAlignedMemoryOperands(Inst, N);
2373 void addAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2374 addAlignedMemoryOperands(Inst, N);
2377 void addDupAlignedMemory64Operands(
MCInst &Inst,
unsigned N)
const {
2378 addAlignedMemoryOperands(Inst, N);
2381 void addAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2382 addAlignedMemoryOperands(Inst, N);
2385 void addDupAlignedMemory64or128Operands(
MCInst &Inst,
unsigned N)
const {
2386 addAlignedMemoryOperands(Inst, N);
2389 void addAlignedMemory64or128or256Operands(
MCInst &Inst,
unsigned N)
const {
2390 addAlignedMemoryOperands(Inst, N);
2393 void addAddrMode2Operands(
MCInst &Inst,
unsigned N)
const {
2394 assert(N == 3 &&
"Invalid number of operands!");
2395 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2396 if (!
Memory.OffsetRegNum) {
2399 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2400 if (Val < 0) Val = -Val;
2413 void addAM2OffsetImmOperands(
MCInst &Inst,
unsigned N)
const {
2414 assert(N == 2 &&
"Invalid number of operands!");
2416 assert(CE &&
"non-constant AM2OffsetImm operand!");
2420 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2421 if (Val < 0) Val = -Val;
2427 void addAddrMode3Operands(
MCInst &Inst,
unsigned N)
const {
2428 assert(N == 3 &&
"Invalid number of operands!");
2439 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2440 if (!
Memory.OffsetRegNum) {
2443 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2444 if (Val < 0) Val = -Val;
2456 void addAM3OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2457 assert(N == 2 &&
"Invalid number of operands!");
2458 if (Kind == k_PostIndexRegister) {
2471 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2472 if (Val < 0) Val = -Val;
2478 void addAddrMode5Operands(
MCInst &Inst,
unsigned N)
const {
2479 assert(N == 2 &&
"Invalid number of operands!");
2490 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2493 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2494 if (Val < 0) Val = -Val;
2500 void addAddrMode5FP16Operands(
MCInst &Inst,
unsigned N)
const {
2501 assert(N == 2 &&
"Invalid number of operands!");
2512 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 2 : 0;
2515 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
2516 if (Val < 0) Val = -Val;
2522 void addMemImm8s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2523 assert(N == 2 &&
"Invalid number of operands!");
2533 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2538 void addMemImm0_1020s4OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2539 assert(N == 2 &&
"Invalid number of operands!");
2541 int32_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() / 4 : 0;
2546 void addMemImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2547 assert(N == 2 &&
"Invalid number of operands!");
2548 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2553 void addMemPosImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2554 addMemImm8OffsetOperands(Inst, N);
2557 void addMemNegImm8OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2558 addMemImm8OffsetOperands(Inst, N);
2561 void addMemUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2562 assert(N == 2 &&
"Invalid number of operands!");
2565 addExpr(Inst, getImm());
2571 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2576 void addMemImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
2577 assert(N == 2 &&
"Invalid number of operands!");
2580 addExpr(Inst, getImm());
2586 int64_t Val =
Memory.OffsetImm ?
Memory.OffsetImm->getValue() : 0;
2591 void addConstPoolAsmImmOperands(
MCInst &Inst,
unsigned N)
const {
2592 assert(N == 1 &&
"Invalid number of operands!");
2595 addExpr(Inst, getConstantPoolImm());
2599 void addMemTBBOperands(
MCInst &Inst,
unsigned N)
const {
2600 assert(N == 2 &&
"Invalid number of operands!");
2605 void addMemTBHOperands(
MCInst &Inst,
unsigned N)
const {
2606 assert(N == 2 &&
"Invalid number of operands!");
2611 void addMemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2612 assert(N == 3 &&
"Invalid number of operands!");
2621 void addT2MemRegOffsetOperands(
MCInst &Inst,
unsigned N)
const {
2622 assert(N == 3 &&
"Invalid number of operands!");
2628 void addMemThumbRROperands(
MCInst &Inst,
unsigned N)
const {
2629 assert(N == 2 &&
"Invalid number of operands!");
2634 void addMemThumbRIs4Operands(
MCInst &Inst,
unsigned N)
const {
2635 assert(N == 2 &&
"Invalid number of operands!");
2636 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2641 void addMemThumbRIs2Operands(
MCInst &Inst,
unsigned N)
const {
2642 assert(N == 2 &&
"Invalid number of operands!");
2643 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 2) : 0;
2648 void addMemThumbRIs1Operands(
MCInst &Inst,
unsigned N)
const {
2649 assert(N == 2 &&
"Invalid number of operands!");
2650 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue()) : 0;
2655 void addMemThumbSPIOperands(
MCInst &Inst,
unsigned N)
const {
2656 assert(N == 2 &&
"Invalid number of operands!");
2657 int64_t Val =
Memory.OffsetImm ? (
Memory.OffsetImm->getValue() / 4) : 0;
2662 void addPostIdxImm8Operands(
MCInst &Inst,
unsigned N)
const {
2663 assert(N == 1 &&
"Invalid number of operands!");
2665 assert(CE &&
"non-constant post-idx-imm8 operand!");
2667 bool isAdd = Imm >= 0;
2668 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
2669 Imm = (Imm < 0 ? -Imm : Imm) | (
int)isAdd << 8;
2673 void addPostIdxImm8s4Operands(
MCInst &Inst,
unsigned N)
const {
2674 assert(N == 1 &&
"Invalid number of operands!");
2676 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
2678 bool isAdd = Imm >= 0;
2679 if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
2681 Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
2685 void addPostIdxRegOperands(
MCInst &Inst,
unsigned N)
const {
2686 assert(N == 2 &&
"Invalid number of operands!");
2691 void addPostIdxRegShiftedOperands(
MCInst &Inst,
unsigned N)
const {
2692 assert(N == 2 &&
"Invalid number of operands!");
2698 PostIdxReg.ShiftTy);
2702 void addMSRMaskOperands(
MCInst &Inst,
unsigned N)
const {
2703 assert(N == 1 &&
"Invalid number of operands!");
2707 void addBankedRegOperands(
MCInst &Inst,
unsigned N)
const {
2708 assert(N == 1 &&
"Invalid number of operands!");
2712 void addProcIFlagsOperands(
MCInst &Inst,
unsigned N)
const {
2713 assert(N == 1 &&
"Invalid number of operands!");
2717 void addVecListOperands(
MCInst &Inst,
unsigned N)
const {
2718 assert(N == 1 &&
"Invalid number of operands!");
2722 void addVecListIndexedOperands(
MCInst &Inst,
unsigned N)
const {
2723 assert(N == 2 &&
"Invalid number of operands!");
2728 void addVectorIndex8Operands(
MCInst &Inst,
unsigned N)
const {
2729 assert(N == 1 &&
"Invalid number of operands!");
2733 void addVectorIndex16Operands(
MCInst &Inst,
unsigned N)
const {
2734 assert(N == 1 &&
"Invalid number of operands!");
2738 void addVectorIndex32Operands(
MCInst &Inst,
unsigned N)
const {
2739 assert(N == 1 &&
"Invalid number of operands!");
2743 void addVectorIndex64Operands(
MCInst &Inst,
unsigned N)
const {
2744 assert(N == 1 &&
"Invalid number of operands!");
2748 void addNEONi8splatOperands(
MCInst &Inst,
unsigned N)
const {
2749 assert(N == 1 &&
"Invalid number of operands!");
2756 void addNEONi16splatOperands(
MCInst &Inst,
unsigned N)
const {
2757 assert(N == 1 &&
"Invalid number of operands!");
2765 void addNEONi16splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2766 assert(N == 1 &&
"Invalid number of operands!");
2774 void addNEONi32splatOperands(
MCInst &Inst,
unsigned N)
const {
2775 assert(N == 1 &&
"Invalid number of operands!");
2783 void addNEONi32splatNotOperands(
MCInst &Inst,
unsigned N)
const {
2784 assert(N == 1 &&
"Invalid number of operands!");
2792 void addNEONi8ReplicateOperands(
MCInst &Inst,
bool Inv)
const {
2797 "All instructions that wants to replicate non-zero byte " 2798 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
2802 unsigned B = Value & 0xff;
2807 void addNEONinvi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2808 assert(N == 1 &&
"Invalid number of operands!");
2809 addNEONi8ReplicateOperands(Inst,
true);
2812 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
2813 if (Value >= 256 && Value <= 0xffff)
2814 Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
2815 else if (Value > 0xffff && Value <= 0xffffff)
2816 Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
2817 else if (Value > 0xffffff)
2818 Value = (Value >> 24) | 0x600;
2822 void addNEONi32vmovOperands(
MCInst &Inst,
unsigned N)
const {
2823 assert(N == 1 &&
"Invalid number of operands!");
2826 unsigned Value = encodeNeonVMOVImmediate(CE->
getValue());
2830 void addNEONvmovi8ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2831 assert(N == 1 &&
"Invalid number of operands!");
2832 addNEONi8ReplicateOperands(Inst,
false);
2835 void addNEONvmovi16ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2836 assert(N == 1 &&
"Invalid number of operands!");
2842 "All instructions that want to replicate non-zero half-word " 2843 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
2845 unsigned Elem = Value & 0xffff;
2847 Elem = (Elem >> 8) | 0x200;
2851 void addNEONi32vmovNegOperands(
MCInst &Inst,
unsigned N)
const {
2852 assert(N == 1 &&
"Invalid number of operands!");
2855 unsigned Value = encodeNeonVMOVImmediate(~CE->
getValue());
2859 void addNEONvmovi32ReplicateOperands(
MCInst &Inst,
unsigned N)
const {
2860 assert(N == 1 &&
"Invalid number of operands!");
2866 "All instructions that want to replicate non-zero word " 2867 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
2869 unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
2873 void addNEONi64splatOperands(
MCInst &Inst,
unsigned N)
const {
2874 assert(N == 1 &&
"Invalid number of operands!");
2879 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
2880 Imm |= (Value & 1) << i;
2885 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2886 assert(N == 1 &&
"Invalid number of operands!");
2891 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2892 assert(N == 1 &&
"Invalid number of operands!");
2899 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask,
SMLoc S) {
2900 auto Op = make_unique<ARMOperand>(k_ITCondMask);
2909 auto Op = make_unique<ARMOperand>(k_CondCode);
2916 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal,
SMLoc S) {
2917 auto Op = make_unique<ARMOperand>(k_CoprocNum);
2918 Op->Cop.Val = CopVal;
2924 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal,
SMLoc S) {
2925 auto Op = make_unique<ARMOperand>(k_CoprocReg);
2926 Op->Cop.Val = CopVal;
2932 static std::unique_ptr<ARMOperand> CreateCoprocOption(
unsigned Val,
SMLoc S,
2934 auto Op = make_unique<ARMOperand>(k_CoprocOption);
2941 static std::unique_ptr<ARMOperand> CreateCCOut(
unsigned RegNum,
SMLoc S) {
2942 auto Op = make_unique<ARMOperand>(k_CCOut);
2943 Op->Reg.RegNum = RegNum;
2949 static std::unique_ptr<ARMOperand> CreateToken(
StringRef Str,
SMLoc S) {
2950 auto Op = make_unique<ARMOperand>(k_Token);
2951 Op->Tok.Data = Str.
data();
2952 Op->Tok.Length = Str.
size();
2958 static std::unique_ptr<ARMOperand> CreateReg(
unsigned RegNum,
SMLoc S,
2960 auto Op = make_unique<ARMOperand>(k_Register);
2961 Op->Reg.RegNum = RegNum;
2967 static std::unique_ptr<ARMOperand>
2969 unsigned ShiftReg,
unsigned ShiftImm,
SMLoc S,
2971 auto Op = make_unique<ARMOperand>(k_ShiftedRegister);
2972 Op->RegShiftedReg.ShiftTy = ShTy;
2973 Op->RegShiftedReg.SrcReg = SrcReg;
2974 Op->RegShiftedReg.ShiftReg = ShiftReg;
2975 Op->RegShiftedReg.ShiftImm = ShiftImm;
2981 static std::unique_ptr<ARMOperand>
2984 auto Op = make_unique<ARMOperand>(k_ShiftedImmediate);
2985 Op->RegShiftedImm.ShiftTy = ShTy;
2986 Op->RegShiftedImm.SrcReg = SrcReg;
2987 Op->RegShiftedImm.ShiftImm = ShiftImm;
2993 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
2995 auto Op = make_unique<ARMOperand>(k_ShifterImmediate);
2996 Op->ShifterImm.isASR = isASR;
2997 Op->ShifterImm.Imm = Imm;
3003 static std::unique_ptr<ARMOperand> CreateRotImm(
unsigned Imm,
SMLoc S,
3005 auto Op = make_unique<ARMOperand>(k_RotateImmediate);
3006 Op->RotImm.Imm = Imm;
3012 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3014 auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
3016 Op->ModImm.Rot = Rot;
3022 static std::unique_ptr<ARMOperand>
3024 auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate);
3031 static std::unique_ptr<ARMOperand>
3032 CreateBitfield(
unsigned LSB,
unsigned Width,
SMLoc S,
SMLoc E) {
3033 auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
3034 Op->Bitfield.LSB = LSB;
3035 Op->Bitfield.Width = Width;
3041 static std::unique_ptr<ARMOperand>
3044 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3045 KindTy Kind = k_RegisterList;
3047 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Regs.front().second))
3048 Kind = k_DPRRegisterList;
3049 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
3051 Kind = k_SPRRegisterList;
3056 auto Op = make_unique<ARMOperand>(
Kind);
3058 I = Regs.begin(), E = Regs.end();
I !=
E; ++
I)
3059 Op->Registers.push_back(
I->second);
3060 Op->StartLoc = StartLoc;
3061 Op->EndLoc = EndLoc;
3065 static std::unique_ptr<ARMOperand> CreateVectorList(
unsigned RegNum,
3067 bool isDoubleSpaced,
3069 auto Op = make_unique<ARMOperand>(k_VectorList);
3070 Op->VectorList.RegNum = RegNum;
3071 Op->VectorList.Count = Count;
3072 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3078 static std::unique_ptr<ARMOperand>
3079 CreateVectorListAllLanes(
unsigned RegNum,
unsigned Count,
bool isDoubleSpaced,
3081 auto Op = make_unique<ARMOperand>(k_VectorListAllLanes);
3082 Op->VectorList.RegNum = RegNum;
3083 Op->VectorList.Count = Count;
3084 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3090 static std::unique_ptr<ARMOperand>
3091 CreateVectorListIndexed(
unsigned RegNum,
unsigned Count,
unsigned Index,
3093 auto Op = make_unique<ARMOperand>(k_VectorListIndexed);
3094 Op->VectorList.RegNum = RegNum;
3095 Op->VectorList.Count = Count;
3096 Op->VectorList.LaneIndex =
Index;
3097 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3103 static std::unique_ptr<ARMOperand>
3105 auto Op = make_unique<ARMOperand>(k_VectorIndex);
3106 Op->VectorIndex.Val = Idx;
3112 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
3114 auto Op = make_unique<ARMOperand>(k_Immediate);
3121 static std::unique_ptr<ARMOperand>
3124 unsigned ShiftImm,
unsigned Alignment,
bool isNegative,
SMLoc S,
3126 auto Op = make_unique<ARMOperand>(k_Memory);
3127 Op->Memory.BaseRegNum = BaseRegNum;
3128 Op->Memory.OffsetImm = OffsetImm;
3129 Op->Memory.OffsetRegNum = OffsetRegNum;
3130 Op->Memory.ShiftType = ShiftType;
3131 Op->Memory.ShiftImm = ShiftImm;
3132 Op->Memory.Alignment = Alignment;
3133 Op->Memory.isNegative = isNegative;
3136 Op->AlignmentLoc = AlignmentLoc;
3140 static std::unique_ptr<ARMOperand>
3143 auto Op = make_unique<ARMOperand>(k_PostIndexRegister);
3144 Op->PostIdxReg.RegNum = RegNum;
3145 Op->PostIdxReg.isAdd = isAdd;
3146 Op->PostIdxReg.ShiftTy = ShiftTy;
3147 Op->PostIdxReg.ShiftImm = ShiftImm;
3153 static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt,
3155 auto Op = make_unique<ARMOperand>(k_MemBarrierOpt);
3156 Op->MBOpt.Val = Opt;
3162 static std::unique_ptr<ARMOperand>
3164 auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt);
3165 Op->ISBOpt.Val = Opt;
3171 static std::unique_ptr<ARMOperand>
3173 auto Op = make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
3174 Op->TSBOpt.Val = Opt;
3182 auto Op = make_unique<ARMOperand>(k_ProcIFlags);
3189 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask,
SMLoc S) {
3190 auto Op = make_unique<ARMOperand>(k_MSRMask);
3191 Op->MMask.Val = MMask;
3197 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg,
SMLoc S) {
3198 auto Op = make_unique<ARMOperand>(k_BankedReg);
3199 Op->BankedReg.Val =
Reg;
3209 auto RegName = [](
unsigned Reg) {
3221 OS <<
"<ccout " << RegName(
getReg()) <<
">";
3223 case k_ITCondMask: {
3224 static const char *
const MaskStr[] = {
3225 "(invalid)",
"(teee)",
"(tee)",
"(teet)",
3226 "(te)",
"(tete)",
"(tet)",
"(tett)",
3227 "(t)",
"(ttee)",
"(tte)",
"(ttet)",
3228 "(tt)",
"(ttte)",
"(ttt)",
"(tttt)" 3230 assert((ITMask.Mask & 0xf) == ITMask.Mask);
3231 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
3235 OS <<
"<coprocessor number: " << getCoproc() <<
">";
3238 OS <<
"<coprocessor register: " << getCoproc() <<
">";
3240 case k_CoprocOption:
3241 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
3244 OS <<
"<mask: " << getMSRMask() <<
">";
3247 OS <<
"<banked reg: " << getBankedReg() <<
">";
3252 case k_MemBarrierOpt:
3253 OS <<
"<ARM_MB::" <<
MemBOptToString(getMemBarrierOpt(),
false) <<
">";
3255 case k_InstSyncBarrierOpt:
3258 case k_TraceSyncBarrierOpt:
3264 OS <<
" base:" << RegName(
Memory.BaseRegNum);
3266 OS <<
" offset-imm:" << *
Memory.OffsetImm;
3268 OS <<
" offset-reg:" << (
Memory.isNegative ?
"-" :
"")
3269 << RegName(
Memory.OffsetRegNum);
3272 OS <<
" shift-imm:" <<
Memory.ShiftImm;
3275 OS <<
" alignment:" <<
Memory.Alignment;
3278 case k_PostIndexRegister:
3279 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
3280 << RegName(PostIdxReg.RegNum);
3283 << PostIdxReg.ShiftImm;
3286 case k_ProcIFlags: {
3287 OS <<
"<ARM_PROC::";
3288 unsigned IFlags = getProcIFlags();
3289 for (
int i=2; i >= 0; --i)
3290 if (IFlags & (1 << i))
3296 OS <<
"<register " << RegName(
getReg()) <<
">";
3298 case k_ShifterImmediate:
3299 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
3300 <<
" #" << ShifterImm.Imm <<
">";
3302 case k_ShiftedRegister:
3303 OS <<
"<so_reg_reg " << RegName(RegShiftedReg.SrcReg) <<
" " 3305 << RegName(RegShiftedReg.ShiftReg) <<
">";
3307 case k_ShiftedImmediate:
3308 OS <<
"<so_reg_imm " << RegName(RegShiftedImm.SrcReg) <<
" " 3310 << RegShiftedImm.ShiftImm <<
">";
3312 case k_RotateImmediate:
3313 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
3315 case k_ModifiedImmediate:
3316 OS <<
"<mod_imm #" << ModImm.Bits <<
", #" 3317 << ModImm.Rot <<
")>";
3319 case k_ConstantPoolImmediate:
3320 OS <<
"<constant_pool_imm #" << *getConstantPoolImm();
3322 case k_BitfieldDescriptor:
3323 OS <<
"<bitfield " <<
"lsb: " << Bitfield.LSB
3324 <<
", width: " << Bitfield.Width <<
">";
3326 case k_RegisterList:
3327 case k_DPRRegisterList:
3328 case k_SPRRegisterList: {
3329 OS <<
"<register_list ";
3335 if (++
I <
E) OS <<
", ";
3342 OS <<
"<vector_list " << VectorList.Count <<
" * " 3343 << RegName(VectorList.RegNum) <<
">";
3345 case k_VectorListAllLanes:
3346 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * " 3347 << RegName(VectorList.RegNum) <<
">";
3349 case k_VectorListIndexed:
3350 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") " 3351 << VectorList.Count <<
" * " << RegName(VectorList.RegNum) <<
">";
3357 OS <<
"<vectorindex " << getVectorIndex() <<
">";
3369 bool ARMAsmParser::ParseRegister(
unsigned &RegNo,
3371 const AsmToken &Tok = getParser().getTok();
3374 RegNo = tryParseRegister();
3376 return (RegNo == (
unsigned)-1);
3382 int ARMAsmParser::tryParseRegister() {
3391 .Case(
"r13", ARM::SP)
3392 .
Case(
"r14", ARM::LR)
3393 .
Case(
"r15", ARM::PC)
3394 .
Case(
"ip", ARM::R12)
3396 .
Case(
"a1", ARM::R0)
3397 .
Case(
"a2", ARM::R1)
3399 .
Case(
"a4", ARM::R3)
3401 .
Case(
"v2", ARM::R5)
3403 .
Case(
"v4", ARM::R7)
3404 .
Case(
"v5", ARM::R8)
3405 .
Case(
"v6", ARM::R9)
3406 .
Case(
"v7", ARM::R10)
3407 .
Case(
"v8", ARM::R11)
3408 .
Case(
"sb", ARM::R9)
3409 .
Case(
"sl", ARM::R10)
3410 .
Case(
"fp", ARM::R11)
3419 if (Entry == RegisterReqs.
end())
3422 return Entry->getValue();
3426 if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
3439 int ARMAsmParser::tryParseShiftRegister(
OperandVector &Operands) {
3464 std::unique_ptr<ARMOperand> PrevOp(
3466 if (!PrevOp->isReg())
3467 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
3468 int SrcReg = PrevOp->getReg();
3484 const MCExpr *ShiftExpr =
nullptr;
3485 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
3486 Error(ImmLoc,
"invalid immediate shift value");
3492 Error(ImmLoc,
"invalid immediate shift value");
3502 Error(ImmLoc,
"immediate shift value out of range");
3512 ShiftReg = tryParseRegister();
3513 if (ShiftReg == -1) {
3514 Error(L,
"expected immediate or register in shift operand");
3519 "expected immediate or register in shift operand");
3525 Operands.
push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
3529 Operands.
push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
3541 bool ARMAsmParser::tryParseRegisterWithWriteBack(
OperandVector &Operands) {
3545 int RegNo = tryParseRegister();
3549 Operands.
push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
3567 if (getParser().parseExpression(ImmVal))
3571 return TokError(
"immediate value expected for vector index");
3599 if (Name.
size() < 2 || Name[0] != CoprocOp)
3603 switch (Name.
size()) {
3626 case '0':
return 10;
3627 case '1':
return 11;
3628 case '2':
return 12;
3629 case '3':
return 13;
3630 case '4':
return 14;
3631 case '5':
return 15;
3658 ARMAsmParser::parseCoprocNumOperand(
OperandVector &Operands) {
3669 if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
3673 Operands.
push_back(ARMOperand::CreateCoprocNum(Num, S));
3681 ARMAsmParser::parseCoprocRegOperand(
OperandVector &Operands) {
3693 Operands.
push_back(ARMOperand::CreateCoprocReg(Reg, S));
3700 ARMAsmParser::parseCoprocOptionOperand(
OperandVector &Operands) {
3711 if (getParser().parseExpression(Expr)) {
3712 Error(Loc,
"illegal expression");
3717 Error(Loc,
"coprocessor option must be an immediate in range [0, 255]");
3728 Operands.
push_back(ARMOperand::CreateCoprocOption(Val, S, E));
3739 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3743 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
3746 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
3747 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
3748 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
3749 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
3750 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
3755 bool ARMAsmParser::parseRegisterList(
OperandVector &Operands) {
3758 return TokError(
"Token is not a Left Curly Brace");
3765 int Reg = tryParseRegister();
3767 return Error(RegLoc,
"register expected");
3775 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3776 Reg = getDRegFromQReg(Reg);
3777 EReg =
MRI->getEncodingValue(Reg);
3778 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3782 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3783 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
3784 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg))
3785 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
3786 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(Reg))
3787 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
3789 return Error(RegLoc,
"invalid register in register list");
3792 EReg =
MRI->getEncodingValue(Reg);
3793 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3803 int EndReg = tryParseRegister();
3805 return Error(AfterMinusLoc,
"register expected");
3807 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
3808 EndReg = getDRegFromQReg(EndReg) + 1;
3815 return Error(AfterMinusLoc,
"invalid register in register list");
3817 if (
MRI->getEncodingValue(Reg) >
MRI->getEncodingValue(EndReg))
3818 return Error(AfterMinusLoc,
"bad range in register list");
3821 while (Reg != EndReg) {
3823 EReg =
MRI->getEncodingValue(Reg);
3824 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3832 Reg = tryParseRegister();
3834 return Error(RegLoc,
"register expected");
3836 bool isQReg =
false;
3837 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3838 Reg = getDRegFromQReg(Reg);
3843 return Error(RegLoc,
"invalid register in register list");
3845 if (
MRI->getEncodingValue(Reg) <
MRI->getEncodingValue(OldReg)) {
3846 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
3847 Warning(RegLoc,
"register list not in ascending order");
3849 return Error(RegLoc,
"register list not in ascending order");
3851 if (
MRI->getEncodingValue(Reg) ==
MRI->getEncodingValue(OldReg)) {
3853 ") in register list");
3857 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
3859 return Error(RegLoc,
"non-contiguous register range");
3860 EReg =
MRI->getEncodingValue(Reg);
3861 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3863 EReg =
MRI->getEncodingValue(++Reg);
3864 Registers.
push_back(std::pair<unsigned, unsigned>(EReg, Reg));
3874 Operands.
push_back(ARMOperand::CreateRegList(Registers, S, E));
3894 LaneKind = AllLanes;
3907 if (getParser().parseExpression(LaneIndex)) {
3908 Error(Loc,
"illegal expression");
3913 Error(Loc,
"lane index must be empty or an integer");
3925 if (Val < 0 || Val > 7) {
3930 LaneKind = IndexedLane;
3949 int Reg = tryParseRegister();
3952 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg)) {
3958 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 1,
false, S, E));
3961 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1,
false,
3965 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
3972 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
3973 Reg = getDRegFromQReg(Reg);
3979 Reg =
MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3980 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3981 Operands.
push_back(ARMOperand::CreateVectorList(Reg, 2,
false, S, E));
3984 Reg =
MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3985 &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3986 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2,
false,
3990 Operands.
push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
3997 Error(S,
"vector register expected");
4007 int Reg = tryParseRegister();
4009 Error(RegLoc,
"register expected");
4014 unsigned FirstReg =
Reg;
4017 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
4018 FirstReg = Reg = getDRegFromQReg(Reg);
4034 else if (Spacing == 2) {
4036 "sequential registers in double spaced list");
4041 int EndReg = tryParseRegister();
4043 Error(AfterMinusLoc,
"register expected");
4047 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4048 EndReg = getDRegFromQReg(EndReg) + 1;
4054 if (!ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(EndReg)) {
4055 Error(AfterMinusLoc,
"invalid register in register list");
4060 Error(AfterMinusLoc,
"bad range in register list");
4065 unsigned NextLaneIndex;
4066 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4069 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4070 Error(AfterMinusLoc,
"mismatched lane index in register list");
4075 Count += EndReg -
Reg;
4082 Reg = tryParseRegister();
4084 Error(RegLoc,
"register expected");
4093 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(Reg)) {
4096 else if (Spacing == 2) {
4098 "invalid register in double-spaced list (must be 'D' register')");
4101 Reg = getDRegFromQReg(Reg);
4102 if (Reg != OldReg + 1) {
4103 Error(RegLoc,
"non-contiguous register range");
4110 unsigned NextLaneIndex;
4112 if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
4115 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4116 Error(LaneLoc,
"mismatched lane index in register list");
4125 Spacing = 1 + (Reg == OldReg + 2);
4128 if (Reg != OldReg + Spacing) {
4129 Error(RegLoc,
"non-contiguous register range");
4135 unsigned NextLaneIndex;
4139 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
4140 Error(EndLoc,
"mismatched lane index in register list");
4158 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4159 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4160 FirstReg =
MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4162 Operands.
push_back(ARMOperand::CreateVectorList(FirstReg, Count,
4163 (Spacing == 2), S, E));
4170 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
4171 &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
4172 FirstReg =
MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
4174 Operands.
push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
4179 Operands.
push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
4190 ARMAsmParser::parseMemBarrierOptOperand(
OperandVector &Operands) {
4234 const MCExpr *MemBarrierID;
4235 if (getParser().parseExpression(MemBarrierID)) {
4236 Error(Loc,
"illegal expression");
4242 Error(Loc,
"constant expression expected");
4248 Error(Loc,
"immediate value out of range");
4261 ARMAsmParser::parseTraceSyncBarrierOptOperand(
OperandVector &Operands) {
4280 ARMAsmParser::parseInstSyncBarrierOptOperand(
OperandVector &Operands) {
4302 const MCExpr *ISBarrierID;
4303 if (getParser().parseExpression(ISBarrierID)) {
4304 Error(Loc,
"illegal expression");
4310 Error(Loc,
"constant expression expected");
4316 Error(Loc,
"immediate value out of range");
4324 Operands.
push_back(ARMOperand::CreateInstSyncBarrierOpt(
4332 ARMAsmParser::parseProcIFlagsOperand(
OperandVector &Operands) {
4343 if (IFlagsStr !=
"none") {
4344 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
4353 if (Flag == ~0U || (IFlags & Flag))
4367 ARMAsmParser::parseMSRMaskOperand(
OperandVector &Operands) {
4374 if (Val > 255 || Val < 0) {
4377 unsigned SYSmvalue = Val & 0xFF;
4379 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
4388 auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.
lower());
4389 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
4392 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
4395 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
4400 size_t Start = 0, Next = Mask.
find(
'_');
4402 std::string SpecReg = Mask.
slice(Start, Next).
lower();
4404 Flags = Mask.
slice(Next+1, Mask.
size());
4409 unsigned FlagsVal = 0;
4411 if (SpecReg ==
"apsr") {
4415 .
Case(
"nzcvqg", 0xc)
4418 if (FlagsVal == ~0U) {
4424 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
4426 if (Flags ==
"all" || Flags ==
"")
4428 for (
int i = 0, e = Flags.
size(); i != e; ++i) {
4438 if (Flag == ~0U || (FlagsVal & Flag))
4454 if (SpecReg ==
"spsr")
4458 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
4465 ARMAsmParser::parseBankedRegOperand(
OperandVector &Operands) {
4473 auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.
lower());
4476 unsigned Encoding = TheReg->Encoding;
4479 Operands.
push_back(ARMOperand::CreateBankedReg(Encoding, S));
4493 std::string LowerOp = Op.
lower();
4494 std::string UpperOp = Op.
upper();
4495 if (ShiftName != LowerOp && ShiftName != UpperOp) {
4509 const MCExpr *ShiftAmount;
4512 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4513 Error(Loc,
"illegal expression");
4518 Error(Loc,
"constant expression expected");
4522 if (Val < Low || Val > High) {
4523 Error(Loc,
"immediate value out of range");
4527 Operands.
push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
4538 Error(S,
"'be' or 'le' operand expected");
4548 Error(S,
"'be' or 'le' operand expected");
4568 Error(S,
"shift operator 'asr' or 'lsl' expected");
4573 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
4575 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
4578 Error(S,
"shift operator 'asr' or 'lsl' expected");
4592 const MCExpr *ShiftAmount;
4594 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4595 Error(ExLoc,
"malformed shift expression");
4600 Error(ExLoc,
"shift amount must be an immediate");
4607 if (Val < 1 || Val > 32) {
4608 Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
4613 Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
4616 if (Val == 32) Val = 0;
4619 if (Val < 0 || Val > 31) {
4620 Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
4625 Operands.
push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
4641 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
4654 const MCExpr *ShiftAmount;
4656 if (getParser().parseExpression(ShiftAmount, EndLoc)) {
4657 Error(ExLoc,
"malformed rotate expression");
4662 Error(ExLoc,
"rotate amount must be an immediate");
4670 if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
4671 Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
4675 Operands.
push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
4715 if (getParser().parseExpression(Imm1Exp, Ex1)) {
4716 Error(Sx1,
"malformed expression");
4728 Operands.
push_back(ARMOperand::CreateModImm((Enc & 0xFF),
4741 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4747 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
4753 Error(Sx1,
"expected modified immediate operand: #[0, 255], #even[0-30]");
4758 Error(Sx1,
"immediate operand must a number in the range [0, 255]");
4775 if (getParser().parseExpression(Imm2Exp, Ex2)) {
4776 Error(Sx2,
"malformed expression");
4784 if (!(Imm2 & ~0x1E)) {
4786 Operands.
push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
4789 Error(Sx2,
"immediate operand must an even number in the range [0, 30]");
4792 Error(Sx2,
"constant expression expected");
4811 if (getParser().parseExpression(LSBExpr)) {
4812 Error(E,
"malformed immediate expression");
4817 Error(E,
"'lsb' operand must be an immediate");
4823 if (LSB < 0 || LSB > 31) {
4824 Error(E,
"'lsb' operand must be in the range [0,31]");
4844 if (getParser().parseExpression(WidthExpr, EndLoc)) {
4845 Error(E,
"malformed immediate expression");
4850 Error(E,
"'width' operand must be an immediate");
4856 if (Width < 1 || Width > 32 - LSB) {
4857 Error(E,
"'width' operand must be in the range [1,32-lsb]");
4861 Operands.
push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
4879 bool haveEaten =
false;
4891 int Reg = tryParseRegister();
4900 unsigned ShiftImm = 0;
4903 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
4910 Operands.
push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
4942 if (getParser().parseExpression(Offset, E))
4946 Error(S,
"constant expression expected");
4952 if (isNegative && Val == 0)
4953 Val = std::numeric_limits<int32_t>::min();
4961 bool haveEaten =
false;
4973 int Reg = tryParseRegister();
4990 void ARMAsmParser::cvtThumbMultiply(
MCInst &Inst,
4992 ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
4993 ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
4997 if (Operands.
size() == 6 &&
4998 ((ARMOperand &)*Operands[4]).getReg() ==
4999 ((ARMOperand &)*Operands[3]).getReg())
5001 ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
5003 ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
5006 void ARMAsmParser::cvtThumbBranches(
MCInst &Inst,
5008 int CondOp = -1, ImmOp = -1;
5011 case ARM::tBcc: CondOp = 1; ImmOp = 2;
break;
5014 case ARM::t2Bcc: CondOp = 1; ImmOp = 3;
break;
5024 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5025 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5030 unsigned Cond =
static_cast<ARMOperand &
>(*Operands[CondOp]).
getCondCode();
5047 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
5048 if (!op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5054 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[ImmOp]);
5055 if (!op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5060 ((ARMOperand &)*Operands[ImmOp]).addImmOperands(Inst, 1);
5061 ((ARMOperand &)*Operands[CondOp]).addCondCodeOperands(Inst, 2);
5070 return TokError(
"Token is not a Left Bracket");
5075 int BaseRegNum = tryParseRegister();
5076 if (BaseRegNum == -1)
5077 return Error(BaseRegTok.
getLoc(),
"register expected");
5083 return Error(Tok.getLoc(),
"malformed memory operand");
5086 E = Tok.getEndLoc();
5089 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
5104 "Lost colon or comma in memory operand?!");
5113 SMLoc AlignmentLoc = Tok.getLoc();
5116 if (getParser().parseExpression(Expr))
5124 return Error (E,
"constant expression expected");
5130 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
5131 case 16: Align = 2;
break;
5132 case 32: Align = 4;
break;
5133 case 64: Align = 8;
break;
5134 case 128: Align = 16;
break;
5135 case 256: Align = 32;
break;
5146 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, 0,
5148 false, S, E, AlignmentLoc));
5172 if (getParser().parseExpression(Offset))
5180 return Error (E,
"constant expression expected");
5185 if (isNegative && Val == 0)
5197 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
5212 bool isNegative =
false;
5222 int OffsetRegNum = tryParseRegister();
5223 if (OffsetRegNum == -1)
5224 return Error(E,
"register expected");
5228 unsigned ShiftImm = 0;
5231 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
5241 Operands.
push_back(ARMOperand::CreateMem(BaseRegNum,
nullptr, OffsetRegNum,
5242 ShiftType, ShiftImm, 0, isNegative,
5265 return Error(Loc,
"illegal shift operator");
5267 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
5268 ShiftName ==
"asl" || ShiftName ==
"ASL")
5270 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
5272 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5274 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
5276 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
5279 return Error(Loc,
"illegal shift operator");
5294 if (getParser().parseExpression(Expr))
5301 return Error(Loc,
"shift amount must be an immediate");
5306 return Error(Loc,
"immediate shift value out of range");
5348 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*Operands[2]);
5349 bool isVmovf = TyOp.isToken() &&
5350 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
5351 TyOp.getToken() ==
".f16");
5352 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*Operands[0]);
5353 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
5354 Mnemonic.getToken() ==
"fconsts");
5355 if (!(isVmovf || isFconst))
5361 bool isNegative =
false;
5370 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
5372 IntVal ^= (uint64_t)isNegative << 31;
5374 Operands.
push_back(ARMOperand::CreateImm(
5384 if (Val > 255 || Val < 0) {
5385 Error(Loc,
"encoded floating point value out of range");
5389 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
5391 Operands.
push_back(ARMOperand::CreateImm(
5397 Error(Loc,
"invalid floating point immediate");
5418 switch (getLexer().getKind()) {
5426 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
5428 if (!tryParseRegisterWithWriteBack(Operands))
5430 int Res = tryParseShiftRegister(Operands);
5436 if (Mnemonic ==
"vmrs" &&
5440 Operands.
push_back(ARMOperand::CreateToken(
"APSR_nzcv", S));
5457 if (getParser().parseExpression(IdVal))
5460 Operands.
push_back(ARMOperand::CreateImm(IdVal, S, E));
5464 return parseMemory(Operands);
5466 return parseRegisterList(Operands);
5476 if (getParser().parseExpression(ImmVal))
5481 if (isNegative && Val == 0)
5486 Operands.
push_back(ARMOperand::CreateImm(ImmVal, S, E));
5507 if (parsePrefix(RefKind))
5510 const MCExpr *SubExprVal;
5511 if (getParser().parseExpression(SubExprVal))
5517 Operands.
push_back(ARMOperand::CreateImm(ExprVal, S, E));
5522 if (Mnemonic !=
"ldr")
5523 return Error(S,
"unexpected token in operand");
5525 const MCExpr *SubExprVal;
5526 if (getParser().parseExpression(SubExprVal))
5532 Operands.
push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E));
5563 static const struct PrefixEntry {
5564 const char *Spelling;
5566 uint8_t SupportedFormats;
5567 } PrefixEntries[] = {
5576 [&IDVal](
const PrefixEntry &PE) {
5577 return PE.Spelling == IDVal;
5584 uint8_t CurrentFormat;
5585 switch (getContext().getObjectFileInfo()->getObjectFileType()) {
5587 CurrentFormat = MACHO;
5590 CurrentFormat = ELF;
5593 CurrentFormat = COFF;
5596 CurrentFormat = WASM;
5600 if (~
Prefix->SupportedFormats & CurrentFormat) {
5602 "cannot represent relocation in the current file format");
5606 RefKind =
Prefix->VariantKind;
5624 unsigned &PredicationCode,
5626 unsigned &ProcessorIMod,
5629 CarrySetting =
false;
5635 if ((Mnemonic ==
"movs" &&
isThumb()) ||
5636 Mnemonic ==
"teq" || Mnemonic ==
"vceq" || Mnemonic ==
"svc" ||
5637 Mnemonic ==
"mls" || Mnemonic ==
"smmls" || Mnemonic ==
"vcls" ||
5638 Mnemonic ==
"vmls" || Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" ||
5639 Mnemonic ==
"vcge" || Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" ||
5640 Mnemonic ==
"vaclt" || Mnemonic ==
"vacle" || Mnemonic ==
"hlt" ||
5641 Mnemonic ==
"vcgt" || Mnemonic ==
"vcle" || Mnemonic ==
"smlal" ||
5642 Mnemonic ==
"umaal" || Mnemonic ==
"umlal" || Mnemonic ==
"vabal" ||
5643 Mnemonic ==
"vmlal" || Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" ||
5644 Mnemonic ==
"fmuls" || Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" ||
5645 Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" ||
5646 Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" ||
5647 Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
5648 Mnemonic.
startswith(
"vsel") || Mnemonic ==
"vins" || Mnemonic ==
"vmovx" ||
5649 Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
5650 Mnemonic ==
"vudot" || Mnemonic ==
"vsdot" ||
5651 Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
5652 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl")
5657 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
5658 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
5659 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
5660 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs") {
5663 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
5664 PredicationCode = CC;
5671 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" ||
5672 Mnemonic ==
"mrs" || Mnemonic ==
"smmls" || Mnemonic ==
"vabs" ||
5673 Mnemonic ==
"vcls" || Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" ||
5674 Mnemonic ==
"vnmls" || Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" ||
5675 Mnemonic ==
"vrsqrts" || Mnemonic ==
"srs" || Mnemonic ==
"flds" ||
5676 Mnemonic ==
"fmrs" || Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" ||
5677 Mnemonic ==
"fsts" || Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" ||
5678 Mnemonic ==
"fmuls" || Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" ||
5679 Mnemonic ==
"vfms" || Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" ||
5680 Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
5681 (Mnemonic ==
"movs" &&
isThumb()))) {
5682 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
5683 CarrySetting =
true;
5696 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
5697 ProcessorIMod =
IMod;
5703 ITMask = Mnemonic.
slice(2, Mnemonic.
size());
5704 Mnemonic = Mnemonic.
slice(0, 2);
5715 bool &CanAcceptCarrySet,
5716 bool &CanAcceptPredicationCode) {
5718 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5719 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
5720 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
5721 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
5722 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
5723 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
5724 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
5726 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
5727 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
5729 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
5730 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
5731 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
5733 Mnemonic.
startswith(
"vsel") || Mnemonic ==
"vmaxnm" ||
5734 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
5735 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
5736 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
5737 Mnemonic.
startswith(
"aes") || Mnemonic ==
"hvc" || Mnemonic ==
"setpan" ||
5740 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" ||
5741 Mnemonic ==
"vudot" || Mnemonic ==
"vsdot" ||
5742 Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
5743 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" ||
5744 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" ||
5745 Mnemonic ==
"pssbb") {
5747 CanAcceptPredicationCode =
false;
5750 CanAcceptPredicationCode =
5751 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
5752 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
5753 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
5754 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
5755 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
5756 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" &&
5757 Mnemonic !=
"tsb" &&
5759 }
else if (isThumbOne()) {
5761 CanAcceptPredicationCode = Mnemonic !=
"movs";
5763 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
5765 CanAcceptPredicationCode =
true;
5772 void ARMAsmParser::tryConvertingToTwoOperandForm(
StringRef Mnemonic,
5775 if (Operands.
size() != 6)
5778 const auto &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
5779 auto &Op4 =
static_cast<ARMOperand &
>(*Operands[4]);
5780 if (!Op3.isReg() || !Op4.isReg())
5783 auto Op3Reg = Op3.getReg();
5784 auto Op4Reg = Op4.getReg();
5790 auto &Op5 =
static_cast<ARMOperand &
>(*Operands[5]);
5792 if (Mnemonic !=
"add")
5794 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
5795 (Op5.isReg() && Op5.getReg() == ARM::PC);
5796 if (!TryTransform) {
5797 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
5798 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
5799 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
5800 Op5.isImm() && !Op5.isImm0_508s4());
5804 }
else if (!isThumbOne())
5807 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
5808 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
5809 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
5810 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
5816 bool Transform = Op3Reg == Op4Reg;
5821 const ARMOperand *LastOp = &Op5;
5823 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
5824 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
5825 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
5826 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
5837 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
5843 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
5854 bool ARMAsmParser::shouldOmitCCOutOperand(
StringRef Mnemonic,
5867 if (Mnemonic ==
"mov" && Operands.
size() > 4 && !
isThumb() &&
5868 !
static_cast<ARMOperand &
>(*Operands[4]).isModImm() &&
5869 static_cast<ARMOperand &
>(*Operands[4]).isImm0_65535Expr() &&
5870 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5875 if (
isThumb() && Mnemonic ==
"add" && Operands.
size() == 5 &&
5876 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5877 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5878 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0)
5884 if (((
isThumb() && Mnemonic ==
"add") ||
5885 (isThumbTwo() && Mnemonic ==
"sub")) &&
5886 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5887 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5888 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::SP &&
5889 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5890 ((Mnemonic ==
"add" &&
static_cast<ARMOperand &
>(*Operands[5]).
isReg()) ||
5891 static_cast<ARMOperand &>(*Operands[5]).isImm0_1020s4()))
5898 if (isThumbTwo() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5899 Operands.
size() == 6 &&
static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5900 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5901 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
5909 static_cast<ARMOperand &
>(*Operands[5]).isImm0_7())
5913 if (static_cast<ARMOperand &>(*Operands[4]).getReg() != ARM::PC &&
5914 static_cast<ARMOperand &
>(*Operands[5]).isT2SOImm())
5925 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 6 &&
5926 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5927 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5928 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5929 static_cast<ARMOperand &
>(*Operands[5]).
isReg() &&
5937 !inITBlock() || (
static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5938 static_cast<ARMOperand &
>(*Operands[5]).
getReg() &&
5939 static_cast<ARMOperand &
>(*Operands[3]).
getReg() !=
5940 static_cast<ARMOperand &
>(*Operands[4]).
getReg())))
5945 if (isThumbTwo() && Mnemonic ==
"mul" && Operands.
size() == 5 &&
5946 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5947 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
5948 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
5962 if (
isThumb() && (Mnemonic ==
"add" || Mnemonic ==
"sub") &&
5963 (Operands.
size() == 5 || Operands.
size() == 6) &&
5964 static_cast<ARMOperand &>(*Operands[3]).isReg() &&
5965 static_cast<ARMOperand &
>(*Operands[3]).
getReg() == ARM::SP &&
5966 static_cast<ARMOperand &
>(*Operands[1]).
getReg() == 0 &&
5967 (
static_cast<ARMOperand &
>(*Operands[4]).isImm() ||
5968 (Operands.
size() == 6 &&
5969 static_cast<ARMOperand &
>(*Operands[5]).isImm())))
5975 bool ARMAsmParser::shouldOmitPredicateOperand(
StringRef Mnemonic,
5978 unsigned RegIdx = 3;
5979 if ((Mnemonic ==
"vrintz" || Mnemonic ==
"vrintx") &&
5980 (static_cast<ARMOperand &>(*Operands[2]).
getToken() ==
".f32" ||
5981 static_cast<ARMOperand &>(*Operands[2]).
getToken() ==
".f16")) {
5982 if (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
5983 (static_cast<ARMOperand &>(*Operands[3]).
getToken() ==
".f32" ||
5984 static_cast<ARMOperand &>(*Operands[3]).
getToken() ==
".f16"))
5987 if (static_cast<ARMOperand &>(*Operands[RegIdx]).
isReg() &&
5988 (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
5989 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg()) ||
5990 ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
5991 static_cast<ARMOperand &>(*Operands[RegIdx]).
getReg())))
5998 return Tok ==
".8" || Tok ==
".16" || Tok ==
".32" || Tok ==
".64" ||
5999 Tok ==
".i8" || Tok ==
".i16" || Tok ==
".i32" || Tok ==
".i64" ||
6000 Tok ==
".u8" || Tok ==
".u16" || Tok ==
".u32" || Tok ==
".u64" ||
6001 Tok ==
".s8" || Tok ==
".s16" || Tok ==
".s32" || Tok ==
".s64" ||
6002 Tok ==
".p8" || Tok ==
".p16" || Tok ==
".f32" || Tok ==
".f64" ||
6003 Tok ==
".f" || Tok ==
".d";
6014 unsigned VariantID);
6024 void ARMAsmParser::fixupGNULDRDAlias(
StringRef Mnemonic,
6026 if (Mnemonic !=
"ldrd" && Mnemonic !=
"strd")
6028 if (Operands.
size() < 4)
6031 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[2]);
6032 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*Operands[3]);
6043 unsigned RtEncoding =
MRI->getEncodingValue(Op2.getReg());
6044 if (!
isThumb() && (RtEncoding & 1)) {
6049 if (Op2.getReg() == ARM::PC)
6051 unsigned PairedReg = GPR.
getRegister(RtEncoding + 1);
6052 if (!PairedReg || PairedReg == ARM::PC ||
6053 (PairedReg == ARM::SP && !hasV8Ops()))
6057 Operands.
begin() + 3,
6058 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc()));
6071 uint64_t AvailableFeatures = getAvailableFeatures();
6072 unsigned AssemblerDialect = getParser().getAssemblerDialect();
6078 parseDirectiveReq(Name, NameLoc);
6085 size_t Start = 0, Next = Name.
find(
'.');
6089 unsigned PredicationCode;
6090 unsigned ProcessorIMod;
6093 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
6094 ProcessorIMod, ITMask);
6097 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
6098 return Error(NameLoc,
"conditional execution not supported in Thumb1");
6101 Operands.
push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
6108 if (Mnemonic ==
"it") {
6110 if (ITMask.
size() > 3) {
6111 return Error(Loc,
"too many conditions on IT instruction");
6114 for (
unsigned i = ITMask.
size(); i != 0; --i) {
6115 char pos = ITMask[i - 1];
6116 if (pos !=
't' && pos !=
'e') {
6117 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
6120 if (ITMask[i - 1] ==
't')
6123 Operands.
push_back(ARMOperand::CreateITMask(Mask, Loc));
6136 bool CanAcceptCarrySet, CanAcceptPredicationCode;
6137 getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode);
6141 if (!CanAcceptCarrySet && CarrySetting) {
6142 return Error(NameLoc,
"instruction '" + Mnemonic +
6143 "' can not set flags, but 's' suffix specified");
6147 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
6148 return Error(NameLoc,
"instruction '" + Mnemonic +
6149 "' is not predicable, but condition code specified");
6153 if (CanAcceptCarrySet) {
6155 Operands.
push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
6160 if (CanAcceptPredicationCode) {
6163 Operands.
push_back(ARMOperand::CreateCondCode(
6168 if (ProcessorIMod) {
6169 Operands.
push_back(ARMOperand::CreateImm(
6172 }
else if (Mnemonic ==
"cps" && isMClass()) {
6173 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
6179 Next = Name.
find(
'.', Start + 1);
6189 if (ExtraToken ==
".n" && !
isThumb()) {
6191 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in " 6198 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
6200 Operands.
push_back(ARMOperand::CreateToken(ExtraToken, Loc));
6207 if (parseOperand(Operands, Mnemonic)) {
6213 if (parseOperand(Operands, Mnemonic)) {
6222 tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
6231 if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands))
6238 shouldOmitPredicateOperand(Mnemonic, Operands))
6246 if (!
isThumb() && Mnemonic ==
"blx" && Operands.
size() == 3 &&
6247 static_cast<ARMOperand &
>(*Operands[2]).isImm())
6257 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
6258 Mnemonic ==
"stlexd")) {
6259 bool isLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
6260 unsigned Idx = isLoad ? 2 : 3;
6261 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*Operands[Idx]);
6262 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[Idx + 1]);
6266 if (Op1.isReg() && Op2.isReg() && MRC.
contains(Op1.getReg()) &&
6268 unsigned Reg1 = Op1.getReg();
6269 unsigned Reg2 = Op2.getReg();
6270 unsigned Rt =
MRI->getEncodingValue(Reg1);
6271 unsigned Rt2 =
MRI->getEncodingValue(Reg2);
6274 if (Rt + 1 != Rt2 || (Rt & 1)) {
6275 return Error(Op2.getStartLoc(),
6276 isLoad ?
"destination operands must be sequential" 6277 :
"source operands must be sequential");
6279 unsigned NewReg =
MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
6280 &(
MRI->getRegClass(ARM::GPRPairRegClassID)));
6282 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
6288 fixupGNULDRDAlias(Mnemonic, Operands);
6295 if (isThumbTwo() && Mnemonic ==
"sub" && Operands.
size() == 6 &&
6296 static_cast<ARMOperand &
>(*Operands[3]).
isReg() &&
6297 static_cast<ARMOperand &
>(*Operands[3]).
getReg() == ARM::PC &&
6298 static_cast<ARMOperand &
>(*Operands[4]).
isReg() &&
6299 static_cast<ARMOperand &
>(*Operands[4]).
getReg() == ARM::LR &&
6300 static_cast<ARMOperand &
>(*Operands[5]).isImm()) {
6301 Operands.
front() = ARMOperand::CreateToken(Name, NameLoc);
6313 unsigned Reg,
unsigned HiReg,
6314 bool &containsReg) {
6315 containsReg =
false;
6341 return Inst.
getOpcode() == ARM::tBKPT ||
6347 bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
6349 unsigned ListNo,
bool IsARPop) {
6350 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6351 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6357 if (!IsARPop && ListContainsSP)
6358 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6359 "SP may not be in the register list");
6360 else if (ListContainsPC && ListContainsLR)
6361 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6362 "PC and LR may not be in the register list simultaneously");
6366 bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
6369 const ARMOperand &Op =
static_cast<const ARMOperand &
>(*Operands[ListNo]);
6370 bool HasWritebackToken = Op.isToken() && Op.getToken() ==
"!";
6375 if (ListContainsSP && ListContainsPC)
6376 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6377 "SP and PC may not be in the register list");
6378 else if (ListContainsSP)
6379 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6380 "SP may not be in the register list");
6381 else if (ListContainsPC)
6382 return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
6383 "PC may not be in the register list");
6387 bool ARMAsmParser::validateLDRDSTRD(
MCInst &Inst,
6389 bool Load,
bool ARMMode,
bool Writeback) {
6390 unsigned RtIndex = Load || !Writeback ? 0 : 1;
6397 return Error(Operands[3]->getStartLoc(),
6402 return Error(Operands[3]->getStartLoc(),
6403 "Rt must be even-numbered");
6406 if (Rt2 != Rt + 1) {
6408 return Error(Operands[3]->getStartLoc(),
6409 "destination operands must be sequential");
6411 return Error(Operands[3]->getStartLoc(),
6412 "source operands must be sequential");
6419 if (!ARMMode && Load) {
6421 return Error(Operands[3]->getStartLoc(),
6422 "destination operands can't be identical");
6428 if (Rn == Rt || Rn == Rt2) {
6430 return Error(Operands[3]->getStartLoc(),
6431 "base register needs to be different from destination " 6434 return Error(Operands[3]->getStartLoc(),
6435 "source register and base register can't be identical");
6447 bool ARMAsmParser::validateInstruction(
MCInst &Inst,
6450 SMLoc Loc = Operands[0]->getStartLoc();
6458 return Error(Loc,
"instructions in IT block must be predicable");
6461 if (Cond != currentITCond()) {
6464 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
6465 if (static_cast<ARMOperand &>(*Operands[
I]).isCondCode())
6466 CondLoc = Operands[I]->getStartLoc();
6467 return Error(CondLoc,
"incorrect condition in IT block; got '" +
6469 "', but expected '" +
6477 return Error(Loc,
"predicated instructions must be in IT block");
6481 return Warning(Loc,
"predicated instructions should be in IT block");
6486 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
6487 return Error(Loc,
"instruction must be outside of IT block or the last instruction in an IT block");
6490 const unsigned Opcode = Inst.
getOpcode();
6502 if (Cond ==
ARMCC::AL && Mask != 8 && Mask != 12 && Mask != 14 &&
6504 return Error(Loc,
"unpredictable IT predicate sequence");
6508 if (validateLDRDSTRD(Inst, Operands,
true,
true,
6513 case ARM::LDRD_POST:
6514 if (validateLDRDSTRD(Inst, Operands,
true,
true,
6519 if (validateLDRDSTRD(Inst, Operands,
true,
false,
6523 case ARM::t2LDRD_PRE:
6524 case ARM::t2LDRD_POST:
6525 if (validateLDRDSTRD(Inst, Operands,
true,
false,
6532 if (RmReg == ARM::SP && !hasV8Ops())
6533 return Error(Operands[2]->getStartLoc(),
6534 "r13 (SP) is an unpredictable operand to BXJ");
6538 if (validateLDRDSTRD(Inst, Operands,
false,
true,
6543 case ARM::STRD_POST:
6544 if (validateLDRDSTRD(Inst, Operands,
false,
true,
6548 case ARM::t2STRD_PRE:
6549 case ARM::t2STRD_POST:
6550 if (validateLDRDSTRD(Inst, Operands,
false,
false,
6554 case ARM::STR_PRE_IMM:
6555 case ARM::STR_PRE_REG:
6556 case ARM::t2STR_PRE:
6557 case ARM::STR_POST_IMM:
6558 case ARM::STR_POST_REG:
6559 case ARM::t2STR_POST:
6561 case ARM::t2STRH_PRE:
6562 case ARM::STRH_POST:
6563 case ARM::t2STRH_POST:
6564 case ARM::STRB_PRE_IMM:
6565 case ARM::STRB_PRE_REG:
6566 case ARM::t2STRB_PRE:
6567 case ARM::STRB_POST_IMM:
6568 case ARM::STRB_POST_REG:
6569 case ARM::t2STRB_POST: {
6575 return Error(Operands[3]->getStartLoc(),
6576 "source register and base register can't be identical");
6579 case ARM::LDR_PRE_IMM:
6580 case ARM::LDR_PRE_REG:
6581 case ARM::t2LDR_PRE:
6582 case ARM::LDR_POST_IMM:
6583 case ARM::LDR_POST_REG:
6584 case ARM::t2LDR_POST:
6586 case ARM::t2LDRH_PRE:
6587 case ARM::LDRH_POST:
6588 case ARM::t2LDRH_POST:
6589 case ARM::LDRSH_PRE:
6590 case ARM::t2LDRSH_PRE:
6591 case ARM::LDRSH_POST:
6592 case ARM::t2LDRSH_POST:
6593 case ARM::LDRB_PRE_IMM:
6594 case ARM::LDRB_PRE_REG:
6595 case ARM::t2LDRB_PRE:
6596 case ARM::LDRB_POST_IMM:
6597 case ARM::LDRB_POST_REG:
6598 case ARM::t2LDRB_POST:
6599 case ARM::LDRSB_PRE:
6600 case ARM::t2LDRSB_PRE:
6601 case ARM::LDRSB_POST:
6602 case ARM::t2LDRSB_POST: {
6608 return Error(Operands[3]->getStartLoc(),
6609 "destination register and base register can't be identical");
6619 if (Widthm1 >= 32 - LSB)
6620 return Error(Operands[5]->getStartLoc(),
6621 "bitfield width must be in range [1,32-lsb]");
6633 bool HasWritebackToken =
6634 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
6635 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
6636 bool ListContainsBase;
6638 return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
6639 "registers must be in range r0-r7");
6641 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
6642 return Error(Operands[2]->getStartLoc(),
6643 "writeback operator '!' expected");
6646 if (ListContainsBase && HasWritebackToken)
6647 return Error(Operands[3]->getStartLoc(),
6648 "writeback operator '!' not allowed when base register " 6649 "in register list");
6651 if (validatetLDMRegList(Inst, Operands, 3))
6655 case ARM::LDMIA_UPD:
6656 case ARM::LDMDB_UPD:
6657 case ARM::LDMIB_UPD:
6658 case ARM::LDMDA_UPD:
6664 return Error(Operands.
back()->getStartLoc(),
6665 "writeback register not allowed in register list");
6669 if (validatetLDMRegList(Inst, Operands, 3))
6674 if (validatetSTMRegList(Inst, Operands, 3))
6677 case ARM::t2LDMIA_UPD:
6678 case ARM::t2LDMDB_UPD:
6679 case ARM::t2STMIA_UPD:
6680 case ARM::t2STMDB_UPD:
6682 return Error(Operands.
back()->getStartLoc(),
6683 "writeback register not allowed in register list");
6685 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
6686 if (validatetLDMRegList(Inst, Operands, 3))
6689 if (validatetSTMRegList(Inst, Operands, 3))
6694 case ARM::sysLDMIA_UPD:
6695 case ARM::sysLDMDA_UPD:
6696 case ARM::sysLDMDB_UPD:
6697 case ARM::sysLDMIB_UPD:
6699 return Error(Operands[4]->getStartLoc(),
6700 "writeback register only allowed on system LDM " 6701 "if PC in register-list");
6703 case ARM::sysSTMIA_UPD:
6704 case ARM::sysSTMDA_UPD:
6705 case ARM::sysSTMDB_UPD:
6706 case ARM::sysSTMIB_UPD:
6707 return Error(Operands[2]->getStartLoc(),
6708 "system STM cannot have writeback register");
6718 if (Operands.
size() == 6 && (((ARMOperand &)*Operands[3]).getReg() !=
6719 ((ARMOperand &)*Operands[5]).getReg()) &&
6720 (((ARMOperand &)*Operands[3]).getReg() !=
6721 ((ARMOperand &)*Operands[4]).getReg())) {
6722 return Error(Operands[3]->getStartLoc(),
6723 "destination register must match source register");
6731 bool ListContainsBase;
6734 return Error(Operands[2]->getStartLoc(),
6735 "registers must be in range r0-r7 or pc");
6736 if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
6741 bool ListContainsBase;
6744 return Error(Operands[2]->getStartLoc(),
6745 "registers must be in range r0-r7 or lr");
6746 if (validatetSTMRegList(Inst, Operands, 2))
6750 case ARM::tSTMIA_UPD: {
6751 bool ListContainsBase, InvalidLowList;
6753 0, ListContainsBase);
6754 if (InvalidLowList && !isThumbTwo())
6755 return Error(Operands[4]->getStartLoc(),
6756 "registers must be in range r0-r7");
6760 if (InvalidLowList && ListContainsBase)
6761 return Error(Operands[4]->getStartLoc(),
6762 "writeback operator '!' not allowed when base register " 6763 "in register list");
6765 if (validatetSTMRegList(Inst, Operands, 4))
6772 if (!isThumbTwo() &&
6774 return Error(Operands[4]->getStartLoc(),
6775 "source register must be the same as destination");
6781 if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>())
6782 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6785 int op = (Operands[2]->isImm()) ? 2 : 3;
6786 if (!static_cast<ARMOperand &>(*Operands[op]).isSignedOffset<24, 1>())
6787 return Error(Operands[op]->getStartLoc(),
"branch target out of range");
6792 if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<8, 1>())
6793 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6796 int Op = (Operands[2]->isImm()) ? 2 : 3;
6797 if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
6798 return Error(Operands[Op]->getStartLoc(),
"branch target out of range");
6803 if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<6, 1>())
6804 return Error(Operands[2]->getStartLoc(),
"branch target out of range");
6810 case ARM::t2MOVTi16:
6818 int i = (Operands[3]->isImm()) ? 3 : 4;
6819 ARMOperand &Op =
static_cast<ARMOperand &
>(*Operands[i]);
6829 "immediate expression for mov requires :lower16: or :upper16");
6838 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
6839 return Error(Operands[1]->getStartLoc(),
"instruction 'esb' is not " 6840 "predicable, but condition " 6843 return Error(Operands[1]->getStartLoc(),
"instruction 'csdb' is not " 6844 "predicable, but condition " 6859 return Error(Operands[1]->getStartLoc(),
6860 "instruction 'ssbb' is not predicable, but condition code " 6863 return Error(Operands[1]->getStartLoc(),
6864 "instruction 'pssbb' is not predicable, but condition code " 6868 case ARM::VMOVRRS: {
6873 return Error(Operands[5]->getStartLoc(),
6874 "source operands must be sequential");
6877 case ARM::VMOVSRR: {
6882 return Error(Operands[3]->getStartLoc(),
6883 "destination operands must be sequential");
6887 case ARM::VSTMDIA: {
6888 ARMOperand &Op =
static_cast<ARMOperand&
>(*Operands[3]);
6889 auto &RegList = Op.getRegList();
6890 if (RegList.size() < 1 || RegList.size() > 16)
6891 return Error(Operands[3]->getStartLoc(),
6892 "list of registers must be at least 1 and at most 16");
6904 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6905 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6906 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6907 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
6908 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
6909 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
6910 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
6911 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
6912 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
6915 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6916 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6917 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6918 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6919 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6921 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
6922 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
6923 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
6924 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
6925 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
6927 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
6928 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
6929 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
6930 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
6931 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
6934 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6935 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6936 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6937 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
6938 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6939 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
6940 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
6941 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
6942 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
6943 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
6944 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
6945 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
6946 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
6947 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
6948 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
6951 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6952 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6953 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6954 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6955 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6956 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6957 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
6958 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
6959 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
6960 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
6961 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
6962 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
6963 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
6964 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
6965 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
6966 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
6967 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
6968 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
6971 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6972 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6973 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6974 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
6975 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6976 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
6977 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
6978 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
6979 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
6980 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
6981 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
6982 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
6983 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
6984 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
6985 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
6988 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6989 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6990 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6991 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6992 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6993 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
6994 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
6995 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
6996 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
6997 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
6998 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
6999 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
7000 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
7001 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
7002 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
7003 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
7004 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
7005 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
7013 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
7014 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
7015 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
7016 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
7017 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
7018 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
7019 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
7020 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
7021 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
7024 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
7025 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
7026 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
7027 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
7028 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
7029 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
7030 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
7031 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
7032 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
7033 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
7034 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
7035 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
7036 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
7037 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
7038 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
7041 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
7042 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
7043 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
7044 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
7045 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
7046 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
7047 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
7048 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
7049 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
7050 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
7051 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
7052 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
7053 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
7054 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
7055 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
7056 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
7057 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
7058 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
7061 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
7062 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
7063 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
7064 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
7065 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
7066 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
7067 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
7068 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
7069 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
7070 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
7071 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
7072 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
7073 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
7074 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
7075 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
7078 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
7079 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
7080 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
7081 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
7082 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
7083 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
7084 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
7085 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
7086 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
7087 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
7088 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
7089 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
7090 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
7091 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
7092 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
7093 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
7094 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
7095 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
7098 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
7099 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
7100 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
7101 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
7102 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
7103 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
7104 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
7105 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
7106 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
7107 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
7108 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
7109 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
7110 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
7111 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
7112 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
7115 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
7116 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
7117 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
7118 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
7119 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
7120 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
7121 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
7122 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
7123 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
7124 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
7125 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
7126 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
7127 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
7128 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
7129 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
7130 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
7131 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
7132 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
7135 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
7136 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
7137 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
7138 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
7139 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
7140 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
7141 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
7142 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
7143 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
7144 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
7145 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
7146 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
7147 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
7148 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
7149 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
7150 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
7151 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
7152 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
7156 bool ARMAsmParser::processInstruction(
MCInst &Inst,
7161 bool HasWideQualifier =
false;
7162 for (
auto &Op : Operands) {
7163 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
7164 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
7165 HasWideQualifier =
true;
7172 case ARM::LDRT_POST:
7173 case ARM::LDRBT_POST: {
7174 const unsigned Opcode =
7175 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
7176 : ARM::LDRBT_POST_IMM;
7190 case ARM::STRT_POST:
7191 case ARM::STRBT_POST: {
7192 const unsigned Opcode =
7193 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
7194 : ARM::STRBT_POST_IMM;
7226 MCSymbol *Dot = getContext().createTempSymbol();
7245 case ARM::t2LDRpcrel:
7254 case ARM::t2LDRBpcrel:
7257 case ARM::t2LDRHpcrel:
7260 case ARM::t2LDRSBpcrel:
7263 case ARM::t2LDRSHpcrel:
7266 case ARM::LDRConstPool:
7267 case ARM::tLDRConstPool:
7268 case ARM::t2LDRConstPool: {
7273 if (Inst.
getOpcode() == ARM::LDRConstPool)
7275 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
7277 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
7279 const ARMOperand &PoolOperand =
7281 static_cast<ARMOperand &
>(*Operands[4]) :
7282 static_cast<ARMOperand &>(*Operands[3]));
7283 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
7285 if (isa<MCConstantExpr>(SubExprVal) &&
7289 (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
7291 bool MovHasS =
true;
7292 if (Inst.
getOpcode() == ARM::LDRConstPool) {
7302 else if (hasV6T2Ops() &&
7303 Value >=0 && Value < 65536) {
7315 else if (hasThumb2() &&
7320 else if (hasV8MBaseline() &&
7321 Value >=0 && Value < 65536) {
7341 getTargetStreamer().addConstantPoolEntry(SubExprVal,
7342 PoolOperand.getStartLoc());
7353 case ARM::VST1LNdWB_register_Asm_8:
7354 case ARM::VST1LNdWB_register_Asm_16:
7355 case ARM::VST1LNdWB_register_Asm_32: {
7373 case ARM::VST2LNdWB_register_Asm_8:
7374 case ARM::VST2LNdWB_register_Asm_16:
7375 case ARM::VST2LNdWB_register_Asm_32:
7376 case ARM::VST2LNqWB_register_Asm_16:
7377 case ARM::VST2LNqWB_register_Asm_32: {
7397 case ARM::VST3LNdWB_register_Asm_8:
7398 case ARM::VST3LNdWB_register_Asm_16:
7399 case ARM::VST3LNdWB_register_Asm_32:
7400 case ARM::VST3LNqWB_register_Asm_16:
7401 case ARM::VST3LNqWB_register_Asm_32: {
7423 case ARM::VST4LNdWB_register_Asm_8:
7424 case ARM::VST4LNdWB_register_Asm_16:
7425 case ARM::VST4LNdWB_register_Asm_32:
7426 case ARM::VST4LNqWB_register_Asm_16:
7427 case ARM::VST4LNqWB_register_Asm_32: {
7451 case ARM::VST1LNdWB_fixed_Asm_8:
7452 case ARM::VST1LNdWB_fixed_Asm_16:
7453 case ARM::VST1LNdWB_fixed_Asm_32: {
7471 case ARM::VST2LNdWB_fixed_Asm_8:
7472 case ARM::VST2LNdWB_fixed_Asm_16:
7473 case ARM::VST2LNdWB_fixed_Asm_32:
7474 case ARM::VST2LNqWB_fixed_Asm_16:
7475 case ARM::VST2LNqWB_fixed_Asm_32: {
7495 case ARM::VST3LNdWB_fixed_Asm_8:
7496 case ARM::VST3LNdWB_fixed_Asm_16:
7497 case ARM::VST3LNdWB_fixed_Asm_32:
7498 case ARM::VST3LNqWB_fixed_Asm_16:
7499 case ARM::VST3LNqWB_fixed_Asm_32: {
7521 case ARM::VST4LNdWB_fixed_Asm_8:
7522 case ARM::VST4LNdWB_fixed_Asm_16:
7523 case ARM::VST4LNdWB_fixed_Asm_32:
7524 case ARM::VST4LNqWB_fixed_Asm_16:
7525 case ARM::VST4LNqWB_fixed_Asm_32: {
7549 case ARM::VST1LNdAsm_8:
7550 case ARM::VST1LNdAsm_16:
7551 case ARM::VST1LNdAsm_32: {
7567 case ARM::VST2LNdAsm_8:
7568 case ARM::VST2LNdAsm_16:
7569 case ARM::VST2LNdAsm_32:
7570 case ARM::VST2LNqAsm_16:
7571 case ARM::VST2LNqAsm_32: {
7589 case ARM::VST3LNdAsm_8:
7590 case ARM::VST3LNdAsm_16:
7591 case ARM::VST3LNdAsm_32:
7592 case ARM::VST3LNqAsm_16:
7593 case ARM::VST3LNqAsm_32: {
7613 case ARM::VST4LNdAsm_8:
7614 case ARM::VST4LNdAsm_16:
7615 case ARM::VST4LNdAsm_32:
7616 case ARM::VST4LNqAsm_16:
7617 case ARM::VST4LNqAsm_32: {
7640 case ARM::VLD1LNdWB_register_Asm_8:
7641 case ARM::VLD1LNdWB_register_Asm_16:
7642 case ARM::VLD1LNdWB_register_Asm_32: {
7661 case ARM::VLD2LNdWB_register_Asm_8:
7662 case ARM::VLD2LNdWB_register_Asm_16:
7663 case ARM::VLD2LNdWB_register_Asm_32:
7664 case ARM::VLD2LNqWB_register_Asm_16:
7665 case ARM::VLD2LNqWB_register_Asm_32: {
7688 case ARM::VLD3LNdWB_register_Asm_8:
7689 case ARM::VLD3LNdWB_register_Asm_16:
7690 case ARM::VLD3LNdWB_register_Asm_32:
7691 case ARM::VLD3LNqWB_register_Asm_16:
7692 case ARM::VLD3LNqWB_register_Asm_32: {
7719 case ARM::VLD4LNdWB_register_Asm_8:
7720 case ARM::VLD4LNdWB_register_Asm_16:
7721 case ARM::VLD4LNdWB_register_Asm_32:
7722 case ARM::VLD4LNqWB_register_Asm_16:
7723 case ARM::VLD4LNqWB_register_Asm_32: {
7754 case ARM::VLD1LNdWB_fixed_Asm_8:
7755 case ARM::VLD1LNdWB_fixed_Asm_16:
7756 case ARM::VLD1LNdWB_fixed_Asm_32: {
7775 case ARM::VLD2LNdWB_fixed_Asm_8:
7776 case ARM::VLD2LNdWB_fixed_Asm_16:
7777 case ARM::VLD2LNdWB_fixed_Asm_32:
7778 case ARM::VLD2LNqWB_fixed_Asm_16:
7779 case ARM::VLD2LNqWB_fixed_Asm_32: {
7802 case ARM::VLD3LNdWB_fixed_Asm_8:
7803 case ARM::VLD3LNdWB_fixed_Asm_16:
7804 case ARM::VLD3LNdWB_fixed_Asm_32:
7805 case ARM::VLD3LNqWB_fixed_Asm_16:
7806 case ARM::VLD3LNqWB_fixed_Asm_32: {
7833 case ARM::VLD4LNdWB_fixed_Asm_8:
7834 case ARM::VLD4LNdWB_fixed_Asm_16:
7835 case ARM::VLD4LNdWB_fixed_Asm_32:
7836 case ARM::VLD4LNqWB_fixed_Asm_16:
7837 case ARM::VLD4LNqWB_fixed_Asm_32: {
7868 case ARM::VLD1LNdAsm_8:
7869 case ARM::VLD1LNdAsm_16:
7870 case ARM::VLD1LNdAsm_32: {
7887 case ARM::VLD2LNdAsm_8:
7888 case ARM::VLD2LNdAsm_16:
7889 case ARM::VLD2LNdAsm_32:
7890 case ARM::VLD2LNqAsm_16:
7891 case ARM::VLD2LNqAsm_32: {
7912 case ARM::VLD3LNdAsm_8:
7913 case ARM::VLD3LNdAsm_16:
7914 case ARM::VLD3LNdAsm_32:
7915 case ARM::VLD3LNqAsm_16:
7916 case ARM::VLD3LNqAsm_32: {
7941 case ARM::VLD4LNdAsm_8:
7942 case ARM::VLD4LNdAsm_16:
7943 case ARM::VLD4LNdAsm_32:
7944 case ARM::VLD4LNqAsm_16:
7945 case ARM::VLD4LNqAsm_32: {
7975 case ARM::VLD3DUPdAsm_8:
7976 case ARM::VLD3DUPdAsm_16:
7977 case ARM::VLD3DUPdAsm_32:
7978 case ARM::VLD3DUPqAsm_8:
7979 case ARM::VLD3DUPqAsm_16:
7980 case ARM::VLD3DUPqAsm_32: {
7997 case ARM::VLD3DUPdWB_fixed_Asm_8:
7998 case ARM::VLD3DUPdWB_fixed_Asm_16:
7999 case ARM::VLD3DUPdWB_fixed_Asm_32:
8000 case ARM::VLD3DUPqWB_fixed_Asm_8:
8001 case ARM::VLD3DUPqWB_fixed_Asm_16:
8002 case ARM::VLD3DUPqWB_fixed_Asm_32: {
8021 case ARM::VLD3DUPdWB_register_Asm_8:
8022 case ARM::VLD3DUPdWB_register_Asm_16:
8023 case ARM::VLD3DUPdWB_register_Asm_32:
8024 case ARM::VLD3DUPqWB_register_Asm_8:
8025 case ARM::VLD3DUPqWB_register_Asm_16:
8026 case ARM::VLD3DUPqWB_register_Asm_32: {
8046 case ARM::VLD3dAsm_8:
8047 case ARM::VLD3dAsm_16:
8048 case ARM::VLD3dAsm_32:
8049 case ARM::VLD3qAsm_8:
8050 case ARM::VLD3qAsm_16:
8051 case ARM::VLD3qAsm_32: {
8068 case ARM::VLD3dWB_fixed_Asm_8:
8069 case ARM::VLD3dWB_fixed_Asm_16:
8070 case ARM::VLD3dWB_fixed_Asm_32:
8071 case ARM::VLD3qWB_fixed_Asm_8:
8072 case ARM::VLD3qWB_fixed_Asm_16:
8073 case ARM::VLD3qWB_fixed_Asm_32: {
8092 case ARM::VLD3dWB_register_Asm_8:
8093 case ARM::VLD3dWB_register_Asm_16:
8094 case ARM::VLD3dWB_register_Asm_32:
8095 case ARM::VLD3qWB_register_Asm_8:
8096 case ARM::VLD3qWB_register_Asm_16:
8097 case ARM::VLD3qWB_register_Asm_32: {
8117 case ARM::VLD4DUPdAsm_8:
8118 case ARM::VLD4DUPdAsm_16:
8119 case ARM::VLD4DUPdAsm_32:
8120 case ARM::VLD4DUPqAsm_8:
8121 case ARM::VLD4DUPqAsm_16:
8122 case ARM::VLD4DUPqAsm_32: {
8141 case ARM::VLD4DUPdWB_fixed_Asm_8:
8142 case ARM::VLD4DUPdWB_fixed_Asm_16:
8143 case ARM::VLD4DUPdWB_fixed_Asm_32:
8144 case ARM::VLD4DUPqWB_fixed_Asm_8:
8145 case ARM::VLD4DUPqWB_fixed_Asm_16:
8146 case ARM::VLD4DUPqWB_fixed_Asm_32: {
8167 case ARM::VLD4DUPdWB_register_Asm_8:
8168 case ARM::VLD4DUPdWB_register_Asm_16:
8169 case ARM::VLD4DUPdWB_register_Asm_32:
8170 case ARM::VLD4DUPqWB_register_Asm_8:
8171 case ARM::VLD4DUPqWB_register_Asm_16:
8172 case ARM::VLD4DUPqWB_register_Asm_32: {
8194 case ARM::VLD4dAsm_8:
8195 case ARM::VLD4dAsm_16:
8196 case ARM::VLD4dAsm_32:
8197 case ARM::VLD4qAsm_8:
8198 case ARM::VLD4qAsm_16:
8199 case ARM::VLD4qAsm_32: {
8218 case ARM::VLD4dWB_fixed_Asm_8:
8219 case ARM::VLD4dWB_fixed_Asm_16:
8220 case ARM::VLD4dWB_fixed_Asm_32:
8221 case ARM::VLD4qWB_fixed_Asm_8:
8222 case ARM::VLD4qWB_fixed_Asm_16:
8223 case ARM::VLD4qWB_fixed_Asm_32: {
8244 case ARM::VLD4dWB_register_Asm_8:
8245 case ARM::VLD4dWB_register_Asm_16:
8246 case ARM::VLD4dWB_register_Asm_32:
8247 case ARM::VLD4qWB_register_Asm_8:
8248 case ARM::VLD4qWB_register_Asm_16:
8249 case ARM::VLD4qWB_register_Asm_32: {
8271 case ARM::VST3dAsm_8:
8272 case ARM::VST3dAsm_16:
8273 case ARM::VST3dAsm_32:
8274 case ARM::VST3qAsm_8:
8275 case ARM::VST3qAsm_16:
8276 case ARM::VST3qAsm_32: {
8293 case ARM::VST3dWB_fixed_Asm_8:
8294 case ARM::VST3dWB_fixed_Asm_16:
8295 case ARM::VST3dWB_fixed_Asm_32:
8296 case ARM::VST3qWB_fixed_Asm_8:
8297 case ARM::VST3qWB_fixed_Asm_16:
8298 case ARM::VST3qWB_fixed_Asm_32: {
8317 case ARM::VST3dWB_register_Asm_8:
8318 case ARM::VST3dWB_register_Asm_16:
8319 case ARM::VST3dWB_register_Asm_32:
8320 case ARM::VST3qWB_register_Asm_8:
8321 case ARM::VST3qWB_register_Asm_16:
8322 case ARM::VST3qWB_register_Asm_32: {
8342 case ARM::VST4dAsm_8:
8343 case ARM::VST4dAsm_16:
8344 case ARM::VST4dAsm_32:
8345 case ARM::VST4qAsm_8:
8346 case ARM::VST4qAsm_16:
8347 case ARM::VST4qAsm_32: {
8366 case ARM::VST4dWB_fixed_Asm_8:
8367 case ARM::VST4dWB_fixed_Asm_16:
8368 case ARM::VST4dWB_fixed_Asm_32:
8369 case ARM::VST4qWB_fixed_Asm_8:
8370 case ARM::VST4qWB_fixed_Asm_16:
8371 case ARM::VST4qWB_fixed_Asm_32: {
8392 case ARM::VST4dWB_register_Asm_8:
8393 case ARM::VST4dWB_register_Asm_16:
8394 case ARM::VST4dWB_register_Asm_32:
8395 case ARM::VST4qWB_register_Asm_8:
8396 case ARM::VST4qWB_register_Asm_16:
8397 case ARM::VST4qWB_register_Asm_32: {
8425 !HasWideQualifier) {
8429 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
8430 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
8431 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
8449 case ARM::t2MOVSsr: {
8453 bool isNarrow =
false;
8458 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr) &&
8465 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
8466 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
8467 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
8468 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
8474 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
8481 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
8486 case ARM::t2MOVSsi: {
8490 bool isNarrow =
false;
8493 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi) &&
8511 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
8515 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
8516 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
8517 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
8518 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
8519 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
8522 if (Amount == 32) Amount = 0;
8525 if (isNarrow && !isMov)
8527 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8529 if (newOpc != ARM::t2RRX && !isMov)
8535 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
8579 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
8588 if (Opc == ARM::MOVsi)
8609 case ARM::t2LDMIA_UPD: {
8625 case ARM::t2STMDB_UPD: {
8641 case ARM::LDMIA_UPD:
8644 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"pop" &&
8659 case ARM::STMDB_UPD:
8662 if (static_cast<ARMOperand &>(*Operands[0]).getToken() ==
"push" &&
8675 case ARM::t2ADDri12:
8678 if (static_cast<ARMOperand &>(*Operands[0]).getToken() !=
"add" ||
8684 case ARM::t2SUBri12:
8687 if (static_cast<ARMOperand &>(*Operands[0]).
getToken() !=
"sub" ||
8714 case ARM::t2SUBri: {
8728 ARM::tADDi8 : ARM::tSUBi8);
8738 case ARM::t2ADDrr: {
8808 bool hasWritebackToken =
8809 (
static_cast<ARMOperand &
>(*Operands[3]).isToken() &&
8810 static_cast<ARMOperand &
>(*Operands[3]).
getToken() ==
"!");
8811 bool listContainsBase;
8813 (!listContainsBase && !hasWritebackToken) ||
8814 (listContainsBase && hasWritebackToken)) {
8817 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
8820 if (hasWritebackToken)
8827 case ARM::tSTMIA_UPD: {
8832 bool listContainsBase;
8842 bool listContainsBase;
8856 bool listContainsBase;
8873 !HasWideQualifier) {
8894 !HasWideQualifier) {
8916 !HasWideQualifier) {
8920 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
8921 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
8922 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
8923 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
8967 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
8968 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
8969 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
8970 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
8971 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
8972 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
8999 assert(!inITBlock() &&
"nested IT blocks?!");
9000 startExplicitITBlock(Cond, Mask);
9001 MO.
setImm(getITMaskEncoding());
9015 !HasWideQualifier) {
9019 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
9020 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
9021 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
9022 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
9023 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
9024 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
9051 !HasWideQualifier) {
9055 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
9056 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
9057 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
9058 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
9081 unsigned ARMAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
9088 "optionally flag setting instruction missing optional def operand");
9090 "operand count mismatch!");
9099 return Match_RequiresFlagSetting;
9104 return Match_RequiresITBlock;
9107 return Match_RequiresNotITBlock;
9110 return Match_RequiresNotITBlock;
9111 }
else if (isThumbOne()) {
9114 if (Opc == ARM::tADDhirr && !hasV6MOps() &&
9117 return Match_RequiresThumb2;
9119 else if (Opc == ARM::tMOVr && !hasV6Ops() &&
9122 return Match_RequiresV6;
9128 if (Opc == ARM::t2MOVr && !hasV8Ops())
9133 return Match_RequiresV8;
9138 return Match_RequiresV8;
9145 return Match_InvalidOperand;
9151 return Match_RequiresV8;
9153 return Match_InvalidOperand;
9156 return Match_Success;
9169 bool ARMAsmParser::isITBlockTerminator(
MCInst &Inst)
const {
9188 bool MatchingInlineAsm,
9189 bool &EmitInITBlock,
9192 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
9193 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
9197 if (inImplicitITBlock()) {
9198 extendImplicitITBlock(ITState.Cond);
9199 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
9209 if (InstCond == ITCond) {
9210 EmitInITBlock =
true;
9211 return Match_Success;
9213 invertCurrentITCondition();
9214 EmitInITBlock =
true;
9215 return Match_Success;
9219 rewindImplicitITPosition();
9223 flushPendingInstructions(Out);
9224 unsigned PlainMatchResult =
9225 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
9226 if (PlainMatchResult == Match_Success) {
9235 EmitInITBlock =
false;
9236 return Match_Success;
9239 EmitInITBlock =
false;
9240 return Match_Success;
9243 EmitInITBlock =
false;
9244 return Match_Success;
9251 startImplicitITBlock();
9252 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
9259 EmitInITBlock =
true;
9260 return Match_Success;
9263 discardImplicitITBlock();
9267 EmitInITBlock =
false;
9268 return PlainMatchResult;
9272 unsigned VariantID = 0);
9275 bool ARMAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
9278 bool MatchingInlineAsm) {
9280 unsigned MatchResult;
9281 bool PendConditionalInstruction =
false;
9284 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
9285 PendConditionalInstruction, Out);
9287 switch (MatchResult) {
9295 if (validateInstruction(Inst, Operands)) {
9298 forwardITPosition();
9303 bool wasInITBlock = inITBlock();
9309 while (processInstruction(Inst, Operands, Out))
9315 if (wasInITBlock && hasV8Ops() &&
isThumb() &&
9317 Warning(IDLoc,
"deprecated instruction in IT block");
9324 forwardITPosition();
9332 if (PendConditionalInstruction) {
9333 PendingConditionalInsts.push_back(Inst);
9334 if (isITBlockFull() || isITBlockTerminator(Inst))
9335 flushPendingInstructions(Out);
9340 case Match_NearMisses:
9341 ReportNearMisses(NearMisses, IDLoc, Operands);
9343 case Match_MnemonicFail: {
9344 uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
9346 ((ARMOperand &)*Operands[0]).
getToken(), FBS);
9347 return Error(IDLoc,
"invalid instruction" + Suggestion,
9348 ((ARMOperand &)*Operands[0]).getLocRange());
9356 bool ARMAsmParser::ParseDirective(
AsmToken DirectiveID) {
9358 getContext().getObjectFileInfo()->getObjectFileType();
9363 if (IDVal ==
".word")
9364 parseLiteralValues(4, DirectiveID.
getLoc());
9365 else if (IDVal ==
".short" || IDVal ==
".hword")
9366 parseLiteralValues(2, DirectiveID.
getLoc());
9367 else if (IDVal ==
".thumb")
9368 parseDirectiveThumb(DirectiveID.
getLoc());
9369 else if (IDVal ==
".arm")
9370 parseDirectiveARM(DirectiveID.
getLoc());
9371 else if (IDVal ==
".thumb_func")
9372 parseDirectiveThumbFunc(DirectiveID.
getLoc());
9373 else if (IDVal ==
".code")
9374 parseDirectiveCode(DirectiveID.
getLoc());
9375 else if (IDVal ==
".syntax")
9376 parseDirectiveSyntax(DirectiveID.
getLoc());
9377 else if (IDVal ==
".unreq")
9378 parseDirectiveUnreq(DirectiveID.
getLoc());
9379 else if (IDVal ==
".fnend")
9380 parseDirectiveFnEnd(DirectiveID.
getLoc());
9381 else if (IDVal ==
".cantunwind")
9382 parseDirectiveCantUnwind(DirectiveID.
getLoc());
9383 else if (IDVal ==
".personality")
9384 parseDirectivePersonality(DirectiveID.
getLoc());
9385 else if (IDVal ==
".handlerdata")
9386 parseDirectiveHandlerData(DirectiveID.
getLoc());
9387 else if (IDVal ==
".setfp")
9388 parseDirectiveSetFP(DirectiveID.
getLoc());
9389 else if (IDVal ==
".pad")
9390 parseDirectivePad(DirectiveID.
getLoc());
9391 else if (IDVal ==
".save")
9392 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
9393 else if (IDVal ==
".vsave")
9394 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
9395 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
9396 parseDirectiveLtorg(DirectiveID.
getLoc());
9397 else if (IDVal ==
".even")
9398 parseDirectiveEven(DirectiveID.
getLoc());
9399 else if (IDVal ==
".personalityindex")
9400 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
9401 else if (IDVal ==
".unwind_raw")
9402 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
9403 else if (IDVal ==
".movsp")
9404 parseDirectiveMovSP(DirectiveID.
getLoc());
9405 else if (IDVal ==
".arch_extension")
9406 parseDirectiveArchExtension(DirectiveID.
getLoc());
9407 else if (IDVal ==
".align")
9408 return parseDirectiveAlign(DirectiveID.
getLoc());
9409 else if (IDVal ==
".thumb_set")
9410 parseDirectiveThumbSet(DirectiveID.
getLoc());
9411 else if (IDVal ==
".inst")
9412 parseDirectiveInst(DirectiveID.
getLoc());
9413 else if (IDVal ==
".inst.n")
9414 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
9415 else if (IDVal ==
".inst.w")
9416 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
9417 else if (!IsMachO && !IsCOFF) {
9418 if (IDVal ==
".arch")
9419 parseDirectiveArch(DirectiveID.
getLoc());
9420 else if (IDVal ==
".cpu")
9421 parseDirectiveCPU(DirectiveID.
getLoc());
9422 else if (IDVal ==
".eabi_attribute")
9423 parseDirectiveEabiAttr(DirectiveID.
getLoc());
9424 else if (IDVal ==
".fpu")
9425 parseDirectiveFPU(DirectiveID.
getLoc());
9426 else if (IDVal ==
".fnstart")
9427 parseDirectiveFnStart(DirectiveID.
getLoc());
9428 else if (IDVal ==
".object_arch")
9429 parseDirectiveObjectArch(DirectiveID.
getLoc());
9430 else if (IDVal ==
".tlsdescseq")
9431 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
9443 bool ARMAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
9444 auto parseOne = [&]() ->
bool {
9446 if (getParser().parseExpression(Value))
9448 getParser().getStreamer().EmitValue(Value, Size, L);
9451 return (parseMany(parseOne));
9456 bool ARMAsmParser::parseDirectiveThumb(
SMLoc L) {
9458 check(!hasThumb(), L,
"target does not support Thumb mode"))
9464 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
9470 bool ARMAsmParser::parseDirectiveARM(
SMLoc L) {
9472 check(!hasARM(), L,
"target does not support ARM mode"))
9477 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
9484 flushPendingInstructions(getStreamer());
9487 void ARMAsmParser::onLabelParsed(
MCSymbol *Symbol) {
9488 if (NextSymbolIsThumb) {
9489 getParser().getStreamer().EmitThumbFunc(Symbol);
9490 NextSymbolIsThumb =
false;
9496 bool ARMAsmParser::parseDirectiveThumbFunc(
SMLoc L) {
9498 const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
9507 MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
9509 getParser().getStreamer().EmitThumbFunc(Func);
9512 "unexpected token in '.thumb_func' directive"))
9519 "unexpected token in '.thumb_func' directive"))
9522 NextSymbolIsThumb =
true;
9528 bool ARMAsmParser::parseDirectiveSyntax(
SMLoc L) {
9532 Error(L,
"unexpected token in .syntax directive");
9538 if (check(Mode ==
"divided" || Mode ==
"DIVIDED", L,
9539 "'.syntax divided' arm assembly not supported") ||
9540 check(Mode !=
"unified" && Mode !=
"UNIFIED", L,
9541 "unrecognized syntax mode in .syntax directive") ||
9552 bool ARMAsmParser::parseDirectiveCode(
SMLoc L) {
9556 return Error(L,
"unexpected token in .code directive");
9558 if (Val != 16 && Val != 32) {
9559 Error(L,
"invalid operand to .code directive");
9569 return Error(L,
"target does not support Thumb mode");
9573 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code16);
9576 return Error(L,
"target does not support ARM mode");
9580 getParser().getStreamer().EmitAssemblerFlag(
MCAF_Code32);
9592 SMLoc SRegLoc, ERegLoc;
9593 if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc,
9594 "register name expected") ||
9596 "unexpected input in .req directive."))
9599 if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second !=
Reg)
9600 return Error(SRegLoc,
9601 "redefinition of '" + Name +
"' does not match original.");
9608 bool ARMAsmParser::parseDirectiveUnreq(
SMLoc L) {
9611 return Error(L,
"unexpected input in .unreq directive.");
9615 "unexpected input in '.unreq' directive"))
9623 void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc) {
9625 if (WasThumb && hasThumb()) {
9628 }
else if (!WasThumb && hasARM()) {
9639 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
9640 (!WasThumb ?
"thumb" :
"arm") +
" mode");
9647 bool ARMAsmParser::parseDirectiveArch(
SMLoc L) {
9648 StringRef Arch = getParser().parseStringToEndOfStatement().
trim();
9652 return Error(L,
"Unknown arch name");
9658 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9659 FixModeAfterArchChange(WasThumb, L);
9661 getTargetStreamer().emitArch(ID);
9668 bool ARMAsmParser::parseDirectiveEabiAttr(
SMLoc L) {
9677 Error(TagLoc,
"attribute name not recognised: " + Name);
9689 if (check(!CE, TagLoc,
"expected numeric constant"))
9699 bool IsStringValue =
false;
9701 int64_t IntegerValue = 0;
9702 bool IsIntegerValue =
false;
9705 IsStringValue =
true;
9707 IsStringValue =
true;
9708 IsIntegerValue =
true;
9709 }
else if (Tag < 32 || Tag % 2 == 0)
9710 IsIntegerValue =
true;
9711 else if (Tag % 2 == 1)
9712 IsStringValue =
true;
9716 if (IsIntegerValue) {
9724 return Error(ValueExprLoc,
"expected numeric constant");
9733 if (IsStringValue) {
9742 "unexpected token in '.eabi_attribute' directive"))
9745 if (IsIntegerValue && IsStringValue) {
9747 getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
9748 }
else if (IsIntegerValue)
9749 getTargetStreamer().emitAttribute(Tag, IntegerValue);
9750 else if (IsStringValue)
9751 getTargetStreamer().emitTextAttribute(Tag, StringValue);
9757 bool ARMAsmParser::parseDirectiveCPU(
SMLoc L) {
9758 StringRef CPU = getParser().parseStringToEndOfStatement().
trim();
9763 if (!getSTI().isCPUStringValid(CPU))
9764 return Error(L,
"Unknown CPU name");
9769 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9770 FixModeAfterArchChange(WasThumb, L);
9777 bool ARMAsmParser::parseDirectiveFPU(
SMLoc L) {
9778 SMLoc FPUNameLoc = getTok().getLoc();
9779 StringRef FPU = getParser().parseStringToEndOfStatement().
trim();
9784 return Error(FPUNameLoc,
"Unknown FPU name");
9787 for (
auto Feature : Features)
9789 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
9791 getTargetStreamer().emitFPU(ID);
9797 bool ARMAsmParser::parseDirectiveFnStart(
SMLoc L) {
9799 "unexpected token in '.fnstart' directive"))
9802 if (UC.hasFnStart()) {
9803 Error(L,
".fnstart starts before the end of previous one");
9804 UC.emitFnStartLocNotes();
9811 getTargetStreamer().emitFnStart();
9813 UC.recordFnStart(L);
9819 bool ARMAsmParser::parseDirectiveFnEnd(
SMLoc L) {
9821 "unexpected token in '.fnend' directive"))
9824 if (!UC.hasFnStart())
9825 return Error(L,
".fnstart must precede .fnend directive");
9828 getTargetStreamer().emitFnEnd();
9836 bool ARMAsmParser::parseDirectiveCantUnwind(
SMLoc L) {
9838 "unexpected token in '.cantunwind' directive"))
9841 UC.recordCantUnwind(L);
9843 if (check(!UC.hasFnStart(), L,
".fnstart must precede .cantunwind directive"))
9846 if (UC.hasHandlerData()) {
9847 Error(L,
".cantunwind can't be used with .handlerdata directive");
9848 UC.emitHandlerDataLocNotes();
9851 if (UC.hasPersonality()) {
9852 Error(L,
".cantunwind can't be used with .personality directive");
9853 UC.emitPersonalityLocNotes();
9857 getTargetStreamer().emitCantUnwind();
9863 bool ARMAsmParser::parseDirectivePersonality(
SMLoc L) {
9865 bool HasExistingPersonality = UC.hasPersonality();
9869 return Error(L,
"unexpected input in .personality directive.");
9874 "unexpected token in '.personality' directive"))
9877 UC.recordPersonality(L);
9880 if (!UC.hasFnStart())
9881 return Error(L,
".fnstart must precede .personality directive");
9882 if (UC.cantUnwind()) {
9883 Error(L,
".personality can't be used with .cantunwind directive");
9884 UC.emitCantUnwindLocNotes();
9887 if (UC.hasHandlerData()) {
9888 Error(L,
".personality must precede .handlerdata directive");
9889 UC.emitHandlerDataLocNotes();
9892 if (HasExistingPersonality) {
9893 Error(L,
"multiple personality directives");
9894 UC.emitPersonalityLocNotes();
9898 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
9899 getTargetStreamer().emitPersonality(PR);
9905 bool ARMAsmParser::parseDirectiveHandlerData(
SMLoc L) {
9907 "unexpected token in '.handlerdata' directive"))
9910 UC.recordHandlerData(L);
9912 if (!UC.hasFnStart())
9913 return Error(L,
".fnstart must precede .personality directive");
9914 if (UC.cantUnwind()) {
9915 Error(L,
".handlerdata can't be used with .cantunwind directive");
9916 UC.emitCantUnwindLocNotes();
9920 getTargetStreamer().emitHandlerData();
9926 bool ARMAsmParser::parseDirectiveSetFP(
SMLoc L) {
9929 if (check(!UC.hasFnStart(), L,
".fnstart must precede .setfp directive") ||
9930 check(UC.hasHandlerData(), L,
9931 ".setfp must precede .handlerdata directive"))
9936 int FPReg = tryParseRegister();
9938 if (check(FPReg == -1, FPRegLoc,
"frame pointer register expected") ||
9944 int SPReg = tryParseRegister();
9945 if (check(SPReg == -1, SPRegLoc,
"stack pointer register expected") ||
9946 check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
9947 "register should be either $sp or the latest fp register"))
9951 UC.saveFPReg(FPReg);
9961 const MCExpr *OffsetExpr;
9964 if (getParser().parseExpression(OffsetExpr, EndLoc))
9965 return Error(ExLoc,
"malformed setfp offset");
9967 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
9975 getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg),
9976 static_cast<unsigned>(SPReg), Offset);
9982 bool ARMAsmParser::parseDirectivePad(
SMLoc L) {
9985 if (!UC.hasFnStart())
9986 return Error(L,
".fnstart must precede .pad directive");
9987 if (UC.hasHandlerData())
9988 return Error(L,
".pad must precede .handlerdata directive");
9996 const MCExpr *OffsetExpr;
9999 if (getParser().parseExpression(OffsetExpr, EndLoc))
10000 return Error(ExLoc,
"malformed pad offset");
10003 return Error(ExLoc,
"pad offset must be an immediate");
10006 "unexpected token in '.pad' directive"))
10009 getTargetStreamer().emitPad(CE->
getValue());
10016 bool ARMAsmParser::parseDirectiveRegSave(
SMLoc L,
bool IsVector) {
10018 if (!UC.hasFnStart())
10019 return Error(L,
".fnstart must precede .save or .vsave directives");
10020 if (UC.hasHandlerData())
10021 return Error(L,
".save or .vsave must precede .handlerdata directive");
10027 if (parseRegisterList(Operands) ||
10030 ARMOperand &Op = (ARMOperand &)*Operands[0];
10031 if (!IsVector && !Op.isRegList())
10032 return Error(L,
".save expects GPR registers");
10033 if (IsVector && !Op.isDPRRegList())
10034 return Error(L,
".vsave expects DPR registers");
10036 getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
10044 bool ARMAsmParser::parseDirectiveInst(
SMLoc Loc,
char Suffix) {
10060 return Error(Loc,
"width suffixes are invalid in ARM mode");
10063 auto parseOne = [&]() ->
bool {
10065 if (getParser().parseExpression(Expr))
10069 return Error(Loc,
"expected constant expression");
10072 char CurSuffix = Suffix;
10076 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
10079 if (Value->
getValue() > 0xffffffff)
10081 " operand is too big");
10087 else if (Value->
getValue() >= 0xe8000000)
10090 return Error(Loc,
"cannot determine Thumb instruction size, " 10091 "use inst.n/inst.w instead");
10097 getTargetStreamer().emitInst(Value->
getValue(), CurSuffix);
10102 return Error(Loc,
"expected expression following directive");
10103 if (parseMany(parseOne))
10110 bool ARMAsmParser::parseDirectiveLtorg(
SMLoc L) {
10113 getTargetStreamer().emitCurrentConstantPool();
10117 bool ARMAsmParser::parseDirectiveEven(
SMLoc L) {
10124 getStreamer().InitSections(
false);
10125 Section = getStreamer().getCurrentSectionOnly();
10128 assert(Section &&
"must have section to emit alignment");
10130 getStreamer().EmitCodeAlignment(2);
10132 getStreamer().EmitValueToAlignment(2);
10139 bool ARMAsmParser::parseDirectivePersonalityIndex(
SMLoc L) {
10141 bool HasExistingPersonality = UC.hasPersonality();
10143 const MCExpr *IndexExpression;
10147 "unexpected token in '.personalityindex' directive")) {
10151 UC.recordPersonalityIndex(L);
10153 if (!UC.hasFnStart()) {
10154 return Error(L,
".fnstart must precede .personalityindex directive");
10156 if (UC.cantUnwind()) {
10157 Error(L,
".personalityindex cannot be used with .cantunwind");
10158 UC.emitCantUnwindLocNotes();
10161 if (UC.hasHandlerData()) {
10162 Error(L,
".personalityindex must precede .handlerdata directive");
10163 UC.emitHandlerDataLocNotes();
10166 if (HasExistingPersonality) {
10167 Error(L,
"multiple personality directives");
10168 UC.emitPersonalityLocNotes();
10174 return Error(IndexLoc,
"index must be a constant number");
10176 return Error(IndexLoc,
10177 "personality routine index should be in range [0-3]");
10179 getTargetStreamer().emitPersonalityIndex(CE->
getValue());
10185 bool ARMAsmParser::parseDirectiveUnwindRaw(
SMLoc L) {
10187 int64_t StackOffset;
10188 const MCExpr *OffsetExpr;
10189 SMLoc OffsetLoc = getLexer().getLoc();
10191 if (!UC.hasFnStart())
10192 return Error(L,
".fnstart must precede .unwind_raw directives");
10193 if (getParser().parseExpression(OffsetExpr))
10194 return Error(OffsetLoc,
"expected expression");
10198 return Error(OffsetLoc,
"offset must be a constant");
10207 auto parseOne = [&]() ->
bool {
10209 SMLoc OpcodeLoc = getLexer().getLoc();
10212 OpcodeLoc,
"expected opcode expression"))
10216 return Error(OpcodeLoc,
"opcode value must be a constant");
10217 const int64_t Opcode = OC->
getValue();
10218 if (Opcode & ~0xff)
10219 return Error(OpcodeLoc,
"invalid opcode");
10225 SMLoc OpcodeLoc = getLexer().getLoc();
10227 return Error(OpcodeLoc,
"expected opcode expression");
10228 if (parseMany(parseOne))
10231 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
10237 bool ARMAsmParser::parseDirectiveTLSDescSeq(
SMLoc L) {
10241 return TokError(
"expected variable after '.tlsdescseq' directive");
10249 "unexpected token in '.tlsdescseq' directive"))
10252 getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
10258 bool ARMAsmParser::parseDirectiveMovSP(
SMLoc L) {
10260 if (!UC.hasFnStart())
10261 return Error(L,
".fnstart must precede .movsp directives");
10262 if (UC.getFPReg() != ARM::SP)
10263 return Error(L,
"unexpected .movsp directive");
10266 int SPReg = tryParseRegister();
10268 return Error(SPRegLoc,
"register expected");
10269 if (SPReg == ARM::SP || SPReg == ARM::PC)
10270 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
10277 const MCExpr *OffsetExpr;
10281 return Error(OffsetLoc,
"malformed offset expression");
10285 return Error(OffsetLoc,
"offset must be an immediate constant");
10291 "unexpected token in '.movsp' directive"))
10294 getTargetStreamer().emitMovSP(SPReg, Offset);
10295 UC.saveFPReg(SPReg);
10302 bool ARMAsmParser::parseDirectiveObjectArch(
SMLoc L) {
10305 return Error(getLexer().getLoc(),
"unexpected token");
10314 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
10318 getTargetStreamer().emitObjectArch(ID);
10324 bool ARMAsmParser::parseDirectiveAlign(
SMLoc L) {
10330 assert(Section &&
"must have section to emit alignment");
10332 getStreamer().EmitCodeAlignment(4, 0);
10334 getStreamer().EmitValueToAlignment(4, 0, 1, 0);
10342 bool ARMAsmParser::parseDirectiveThumbSet(
SMLoc L) {
10347 "expected identifier after '.thumb_set'") ||
10348 parseToken(
AsmToken::Comma,
"expected comma after name '" + Name +
"'"))
10354 Parser, Sym, Value))
10357 getTargetStreamer().emitThumbSet(Sym, Value);
10369 #define GET_REGISTER_MATCHER 10370 #define GET_SUBTARGET_FEATURE_NAME 10371 #define GET_MATCHER_IMPLEMENTATION 10372 #define GET_MNEMONIC_SPELL_CHECKER 10373 #include "ARMGenAsmMatcher.inc" 10379 ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
10380 switch (MatchError) {
10383 return hasV8Ops() ?
"operand must be a register in range [r0, r14]" 10384 :
"operand must be a register in range [r0, r12] or r14";
10387 return hasD16() ?
"operand must be a register in range [d0, d15]" 10388 :
"operand must be a register in range [d0, d31]";
10389 case Match_DPR_RegList:
10390 return hasD16() ?
"operand must be a list of registers in range [d0, d15]" 10391 :
"operand must be a list of registers in range [d0, d31]";
10395 return getMatchKindDiag(MatchError);
10418 std::multimap<unsigned, unsigned> OperandMissesSeen;
10420 bool ReportedTooFewOperands =
false;
10425 switch (
I.getKind()) {
10428 ((ARMOperand &)*Operands[
I.getOperandIndex()]).getStartLoc();
10429 const char *OperandDiag =
10430 getCustomOperandDiag((ARMMatchResultTy)
I.getOperandError());
10437 unsigned DupCheckMatchClass = OperandDiag ?
I.getOperandClass() : ~0U;
10438 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
10439 if (
std::any_of(PrevReports.first, PrevReports.second,
10440 [DupCheckMatchClass](
10441 const std::pair<unsigned, unsigned> Pair) {
10442 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
10443 return Pair.second == DupCheckMatchClass;
10445 return isSubclass((MatchClassKind)DupCheckMatchClass,
10446 (MatchClassKind)Pair.second);
10449 OperandMissesSeen.insert(
10450 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
10452 NearMissMessage Message;
10453 Message.Loc = OperandLoc;
10455 Message.Message = OperandDiag;
10456 }
else if (
I.getOperandClass() == InvalidMatchClass) {
10457 Message.Message =
"too many operands for instruction";
10459 Message.Message =
"invalid operand for instruction";
10461 dbgs() <<
"Missing diagnostic string for operand class " 10462 << getMatchClassName((MatchClassKind)
I.getOperandClass())
10463 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
10464 <<
", opcode " << MII.getName(
I.getOpcode()) <<
"\n");
10470 uint64_t MissingFeatures =
I.getFeatures();
10472 if (FeatureMissesSeen.
count(MissingFeatures))
10474 FeatureMissesSeen.
insert(MissingFeatures);
10478 if ((MissingFeatures & Feature_IsARM) && !hasARM())
10482 if (
isThumb() && (MissingFeatures & Feature_IsARM) &&
10483 (MissingFeatures & ~Feature_IsARM))
10485 if (!
isThumb() && (MissingFeatures & Feature_IsThumb) &&
10486 (MissingFeatures & ~Feature_IsThumb))
10488 if (!
isThumb() && (MissingFeatures & Feature_IsThumb2) &&
10489 (MissingFeatures & ~(Feature_IsThumb2 | Feature_IsThumb)))
10491 if (isMClass() && (MissingFeatures & Feature_HasNEON))
10494 NearMissMessage Message;
10495 Message.Loc = IDLoc;
10498 OS <<
"instruction requires:";
10500 for (
unsigned MaskPos = 0; MaskPos < (
sizeof(MissingFeatures) * 8 - 1);
10502 if (MissingFeatures & Mask) {
10512 NearMissMessage Message;
10513 Message.Loc = IDLoc;
10514 switch (
I.getPredicateError()) {
10515 case Match_RequiresNotITBlock:
10516 Message.Message =
"flag setting instruction only valid outside IT block";
10518 case Match_RequiresITBlock:
10519 Message.Message =
"instruction only valid inside IT block";
10521 case Match_RequiresV6:
10522 Message.Message =
"instruction variant requires ARMv6 or later";
10524 case Match_RequiresThumb2:
10525 Message.Message =
"instruction variant requires Thumb2";
10527 case Match_RequiresV8:
10528 Message.Message =
"instruction variant requires ARMv8 or later";
10530 case Match_RequiresFlagSetting:
10531 Message.Message =
"no flag-preserving variant of this instruction available";
10533 case Match_InvalidOperand:
10534 Message.Message =
"invalid operand for instruction";
10544 if (!ReportedTooFewOperands) {
10545 SMLoc EndLoc = ((ARMOperand &)*Operands.
back()).getEndLoc();
10547 EndLoc,
StringRef(
"too few operands for instruction")});
10548 ReportedTooFewOperands =
true;
10563 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
10565 if (Messages.
size() == 0) {
10568 Error(IDLoc,
"invalid instruction");
10569 }
else if (Messages.
size() == 1) {
10571 Error(Messages[0].Loc, Messages[0].Message);
10575 Error(IDLoc,
"invalid instruction, any one of the following would fix this:");
10576 for (
auto &M : Messages) {
10577 Note(M.Loc, M.Message);
10585 static const struct {
10592 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10593 {
ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
10595 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
10596 {
ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
10597 {
ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10598 {
ARM::AEK_SEC, Feature_HasV6K, {ARM::FeatureTrustZone} },
10600 {
ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
10601 {
ARM::AEK_FP16, Feature_HasV8_2a, {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
10613 bool ARMAsmParser::parseDirectiveArchExtension(
SMLoc L) {
10617 return Error(getLexer().getLoc(),
"expected architecture extension name");
10624 "unexpected token in '.arch_extension' directive"))
10627 bool EnableFeature =
true;
10629 EnableFeature =
false;
10634 return Error(ExtLoc,
"unknown architectural extension: " + Name);
10641 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
10644 return Error(ExtLoc,
"architectural extension '" + Name +
10646 "allowed for the current base architecture");
10654 ComputeAvailableFeatures(STI.
ToggleFeature(ToggleFeatures));
10655 setAvailableFeatures(Features);
10659 return Error(ExtLoc,
"unknown architectural extension: " + Name);
10666 ARMOperand &Op =
static_cast<ARMOperand &
>(AsmOp);
10674 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
10675 if (CE->getValue() == 0)
10676 return Match_Success;
10680 const MCExpr *SOExpr = Op.getImm();
10682 if (!SOExpr->evaluateAsAbsolute(Value))
10683 return Match_Success;
10684 assert((Value >= std::numeric_limits<int32_t>::min() &&
10686 "expression value must be representable in 32 bits");
10690 if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
10691 return Match_Success;
10695 MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg()))
10696 return Match_Success;
10699 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
Represents a range in source code.
Instances of this class represent a uniqued identifier for a section in the current translation unit...
const_iterator end(StringRef path)
Get end iterator over path.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static MSP430CC::CondCodes getCondCode(unsigned Cond)
unsigned encodeNEONi16splat(unsigned Value)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool isNEONi32splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
This class represents lattice values for constants.
VariantKind getKind() const
getOpcode - Get the kind of this expression.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
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.
class llvm::RegisterBankInfo GPR
static MCOperand createExpr(const MCExpr *Val)
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...
void push_back(const T &Elt)
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
static const ARMMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Describe properties that are true of each instruction in the target description file.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Target specific streamer interface.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
bool isNot(TokenKind K) const
bool isV8EligibleForIT(const InstrType *Instr)
const FeatureBitset Features
iterator find(StringRef Key)
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
A raw_ostream that writes to an SmallVector or SmallString.
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Target & getTheThumbLETarget()
static bool isThumb(const MCSubtargetInfo &STI)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool isReturn() const
Return true if the instruction is a return.
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
static bool instIsBreakpoint(const MCInst &Inst)
const char * getShiftOpcStr(ShiftOpc Op)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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...
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
const FeatureBitset & getFeatureBits() const
Generic assembler lexer interface, for use by target specific assembly lexers.
static std::string ARMMnemonicSpellCheck(StringRef S, uint64_t FBS, unsigned VariantID=0)
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 bool isLoad(int Opcode)
StringRef getArchName(ArchKind AK)
static unsigned MatchRegisterName(StringRef Name)
Base class for the full range of assembler expressions which are needed for parsing.
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Target & getTheARMBETarget()
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
unsigned getReg() const
Returns the register number.
Context object for machine code objects.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
.code16 (X86) / .code 16 (ARM)
Target & getTheThumbBETarget()
float getFPImmFloat(unsigned Imm)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
const MCExpr * getExpr() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static const char * getRegisterName(unsigned RegNo)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, unsigned Reg)
MCRegisterClass - Base class of TargetRegisterClass.
iterator insert(iterator I, const MCOperand &Op)
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Analysis containing CSE Info
Instances of this class represent a single low-level machine instruction.
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...
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
const char * getPointer() const
A switch()-like statement whose cases are string literals.
initializer< Ty > init(const Ty &Val)
Streaming machine code generation interface.
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
MCTargetStreamer * getTargetStreamer()
Container class for subtarget features.
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)
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
static unsigned getFPReg(const RISCVSubtarget &STI)
bool isOptionalDef() const
Set if this operand is a optional def.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
unsigned getSORegOffset(unsigned Op)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Interface to description of machine instruction set.
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
This file declares a class to represent arbitrary precision floating point values and provide a varie...
FeatureBitset ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
static const char * TraceSyncBOptToString(unsigned val)
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
int64_t getIntVal() const
static const struct @395 Extensions[]
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
unsigned getNumOperands() const
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features, unsigned VariantID)
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
virtual bool UseCodeAlign() const =0
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
iterator erase(const_iterator CI)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isNEONi16splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
Triple - Helper class for working with autoconf configuration names.
static unsigned getNextRegister(unsigned Reg)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
static const fltSemantics & IEEEsingle() LLVM_READNONE
MCStreamer & getStreamer()
void setOpcode(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
ArchKind parseArch(StringRef Arch)
unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
static bool isDataTypeToken(StringRef Tok)
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const MCOperand & getOperand(unsigned i) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
LLVM_NODISCARD T pop_back_val()
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
const FeatureBitset Features
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool is(TokenKind K) const
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static const char * MemBOptToString(unsigned val, bool HasV8)
Base class for user error types.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
iterator insert(iterator I, T &&Elt)
static const char * IFlagsToString(unsigned val)
ShiftOpc getSORegShOp(unsigned Op)
.code32 (X86) / .code 32 (ARM)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static SMLoc getFromPointer(const char *Ptr)
static unsigned ARMCondCodeFromString(StringRef CC)
int AttrTypeFromString(StringRef Tag)
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static CondCodes getOppositeCondition(CondCodes CC)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void emplace_back(ArgTypes &&... Args)
void LLVMInitializeARMAsmParser()
Force static initialization.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
unsigned parseArchExt(StringRef ArchExt)
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool isCall() const
Return true if the instruction is a call.
Generic base class for all target subtargets.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range=None)=0
Emit a note at the location L, with the message Msg.
static const char * getSubtargetFeatureName(uint64_t Val)
LLVM_NODISCARD std::string lower() const
bool getFPUFeatures(unsigned FPUKind, std::vector< StringRef > &Features)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
LLVM Value Representation.
const MCOperandInfo * OpInfo
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
This class implements an extremely fast bulk output stream that can only output to a stream...
unsigned parseFPU(StringRef FPU)
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
Represents a location in source code.
Target & getTheARMLETarget()
unsigned getOpcode() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
bool IsCPSRDead< MCInst >(const MCInst *Instr)
void setDefaultFeatures(StringRef CPU, StringRef FS)
Set the features to the default for the given CPU with an appended feature string.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.