70#define DEBUG_TYPE "asm-parser"
77enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
80 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
81 cl::desc(
"Allow conditional instructions outside of an IT block"),
83 "Accept in both ISAs, emit implicit ITs in Thumb"),
85 "Warn in ARM, reject in Thumb"),
87 "Accept in ARM, reject in Thumb"),
88 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
89 "Warn in ARM, emit implicit ITs in Thumb")));
94enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
96static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
103 return (Mask >> (5 - Position) & 1);
112 Locs PersonalityLocs;
113 Locs PersonalityIndexLocs;
114 Locs HandlerDataLocs;
120 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
121 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
122 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
124 bool hasPersonality()
const {
125 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
128 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
129 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
130 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
131 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
132 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
137 void emitFnStartLocNotes()
const {
139 Parser.
Note(
Loc,
".fnstart was specified here");
142 void emitCantUnwindLocNotes()
const {
144 Parser.
Note(
Loc,
".cantunwind was specified here");
147 void emitHandlerDataLocNotes()
const {
149 Parser.
Note(
Loc,
".handlerdata was specified here");
152 void emitPersonalityLocNotes()
const {
154 PE = PersonalityLocs.end(),
155 PII = PersonalityIndexLocs.begin(),
156 PIE = PersonalityIndexLocs.end();
157 PI != PE || PII != PIE;) {
158 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
159 Parser.
Note(*PI++,
".personality was specified here");
160 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
161 Parser.
Note(*PII++,
".personalityindex was specified here");
164 "at the same location");
169 FnStartLocs = Locs();
170 CantUnwindLocs = Locs();
171 PersonalityLocs = Locs();
172 HandlerDataLocs = Locs();
173 PersonalityIndexLocs = Locs();
179class ARMMnemonicSets {
190 return CDE.
count(Mnemonic);
195 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
198 return CDEWithVPTSuffix.
count(Mnemonic);
203 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
213 bool isCDEDualRegInstr(
StringRef Mnemonic) {
216 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
217 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
218 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
223 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
224 "cx2",
"cx2a",
"cx2d",
"cx2da",
225 "cx3",
"cx3a",
"cx3d",
"cx3da", })
228 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
230 CDEWithVPTSuffix.
insert(Mnemonic);
231 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"t");
232 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"e");
242 assert(getParser().getStreamer().getTargetStreamer() &&
243 "do not have a target streamer");
251 bool NextSymbolIsThumb;
253 bool useImplicitITThumb()
const {
254 return ImplicitItMode == ImplicitItModeTy::Always ||
255 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
258 bool useImplicitITARM()
const {
259 return ImplicitItMode == ImplicitItModeTy::Always ||
260 ImplicitItMode == ImplicitItModeTy::ARMOnly;
275 unsigned CurPosition;
290 void onEndOfFile()
override {
291 flushPendingInstructions(getParser().getStreamer());
294 void flushPendingInstructions(
MCStreamer &Out)
override {
295 if (!inImplicitITBlock()) {
309 for (
const MCInst &Inst : PendingConditionalInsts) {
312 PendingConditionalInsts.clear();
316 ITState.CurPosition = ~0U;
319 bool inITBlock() {
return ITState.CurPosition != ~0U; }
320 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
321 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
323 bool lastInITBlock() {
327 void forwardITPosition() {
328 if (!inITBlock())
return;
333 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
334 ITState.CurPosition = ~0U;
338 void rewindImplicitITPosition() {
339 assert(inImplicitITBlock());
340 assert(ITState.CurPosition > 1);
341 ITState.CurPosition--;
343 unsigned NewMask = 0;
344 NewMask |= ITState.Mask & (0xC << TZ);
345 NewMask |= 0x2 << TZ;
346 ITState.Mask = NewMask;
351 void discardImplicitITBlock() {
352 assert(inImplicitITBlock());
353 assert(ITState.CurPosition == 1);
354 ITState.CurPosition = ~0U;
359 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
365 void invertCurrentITCondition() {
366 if (ITState.CurPosition == 1) {
369 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
374 bool isITBlockFull() {
375 return inITBlock() && (ITState.Mask & 1);
381 assert(inImplicitITBlock());
386 unsigned NewMask = 0;
388 NewMask |= ITState.Mask & (0xE << TZ);
390 NewMask |= (
Cond != ITState.Cond) << TZ;
392 NewMask |= 1 << (TZ - 1);
393 ITState.Mask = NewMask;
397 void startImplicitITBlock() {
401 ITState.CurPosition = 1;
402 ITState.IsExplicit =
false;
413 ITState.CurPosition = 0;
414 ITState.IsExplicit =
true;
419 unsigned CurPosition;
421 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
422 void forwardVPTPosition() {
423 if (!inVPTBlock())
return;
425 if (++VPTState.CurPosition == 5 - TZ)
426 VPTState.CurPosition = ~0U;
430 return getParser().Note(L, Msg,
Range);
434 return getParser().Warning(L, Msg,
Range);
438 return getParser().Error(L, Msg,
Range);
442 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
443 bool IsARPop =
false);
445 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
447 MCRegister tryParseRegister(
bool AllowOutofBoundReg =
false);
450 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
451 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
452 bool AllowRAAC =
false,
bool IsLazyLoadStore =
false,
453 bool IsVSCCLRM =
false);
456 bool parseImmExpr(int64_t &Out);
459 unsigned &ShiftAmount);
460 bool parseLiteralValues(
unsigned Size,
SMLoc L);
461 bool parseDirectiveThumb(
SMLoc L);
462 bool parseDirectiveARM(
SMLoc L);
463 bool parseDirectiveThumbFunc(
SMLoc L);
464 bool parseDirectiveCode(
SMLoc L);
465 bool parseDirectiveSyntax(
SMLoc L);
467 bool parseDirectiveUnreq(
SMLoc L);
468 bool parseDirectiveArch(
SMLoc L);
469 bool parseDirectiveEabiAttr(
SMLoc L);
470 bool parseDirectiveCPU(
SMLoc L);
471 bool parseDirectiveFPU(
SMLoc L);
472 bool parseDirectiveFnStart(
SMLoc L);
473 bool parseDirectiveFnEnd(
SMLoc L);
474 bool parseDirectiveCantUnwind(
SMLoc L);
475 bool parseDirectivePersonality(
SMLoc L);
476 bool parseDirectiveHandlerData(
SMLoc L);
477 bool parseDirectiveSetFP(
SMLoc L);
478 bool parseDirectivePad(
SMLoc L);
479 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
480 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
481 bool parseDirectiveLtorg(
SMLoc L);
482 bool parseDirectiveEven(
SMLoc L);
483 bool parseDirectivePersonalityIndex(
SMLoc L);
484 bool parseDirectiveUnwindRaw(
SMLoc L);
485 bool parseDirectiveTLSDescSeq(
SMLoc L);
486 bool parseDirectiveMovSP(
SMLoc L);
487 bool parseDirectiveObjectArch(
SMLoc L);
488 bool parseDirectiveArchExtension(
SMLoc L);
489 bool parseDirectiveAlign(
SMLoc L);
490 bool parseDirectiveThumbSet(
SMLoc L);
492 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
493 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
494 bool parseDirectiveSEHSaveSP(
SMLoc L);
495 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
496 bool parseDirectiveSEHSaveLR(
SMLoc L);
497 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
498 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
499 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
500 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
501 bool parseDirectiveSEHCustom(
SMLoc L);
503 std::unique_ptr<ARMOperand> defaultCondCodeOp();
504 std::unique_ptr<ARMOperand> defaultCCOutOp();
505 std::unique_ptr<ARMOperand> defaultVPTPredOp();
511 bool &CarrySetting,
unsigned &ProcessorIMod,
514 StringRef FullInst,
bool &CanAcceptCarrySet,
515 bool &CanAcceptPredicationCode,
516 bool &CanAcceptVPTPredicationCode);
519 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
522 unsigned MnemonicOpsEndInd);
525 unsigned MnemonicOpsEndInd);
529 return getSTI().hasFeature(ARM::ModeThumb);
532 bool isThumbOne()
const {
533 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
536 bool isThumbTwo()
const {
537 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
540 bool hasThumb()
const {
541 return getSTI().hasFeature(ARM::HasV4TOps);
544 bool hasThumb2()
const {
545 return getSTI().hasFeature(ARM::FeatureThumb2);
548 bool hasV6Ops()
const {
549 return getSTI().hasFeature(ARM::HasV6Ops);
552 bool hasV6T2Ops()
const {
553 return getSTI().hasFeature(ARM::HasV6T2Ops);
556 bool hasV6MOps()
const {
557 return getSTI().hasFeature(ARM::HasV6MOps);
560 bool hasV7Ops()
const {
561 return getSTI().hasFeature(ARM::HasV7Ops);
564 bool hasV8Ops()
const {
565 return getSTI().hasFeature(ARM::HasV8Ops);
568 bool hasV8MBaseline()
const {
569 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
572 bool hasV8MMainline()
const {
573 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
575 bool hasV8_1MMainline()
const {
576 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
578 bool hasMVEFloat()
const {
579 return getSTI().hasFeature(ARM::HasMVEFloatOps);
581 bool hasCDE()
const {
582 return getSTI().hasFeature(ARM::HasCDEOps);
584 bool has8MSecExt()
const {
585 return getSTI().hasFeature(ARM::Feature8MSecExt);
588 bool hasARM()
const {
589 return !getSTI().hasFeature(ARM::FeatureNoARM);
592 bool hasDSP()
const {
593 return getSTI().hasFeature(ARM::FeatureDSP);
596 bool hasD32()
const {
597 return getSTI().hasFeature(ARM::FeatureD32);
600 bool hasV8_1aOps()
const {
601 return getSTI().hasFeature(ARM::HasV8_1aOps);
604 bool hasRAS()
const {
605 return getSTI().hasFeature(ARM::FeatureRAS);
610 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
611 setAvailableFeatures(FB);
614 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
616 bool isMClass()
const {
617 return getSTI().hasFeature(ARM::FeatureMClass);
623#define GET_ASSEMBLER_HEADER
624#include "ARMGenAsmMatcher.inc"
655 ParseStatus parseVectorLane(VectorLaneTy &LaneKind,
unsigned &Index,
664 unsigned MnemonicOpsEndInd);
666 unsigned MnemonicOpsEndInd, MCStreamer &Out);
667 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
669 unsigned MnemonicOpsEndInd);
670 bool isITBlockTerminator(MCInst &Inst)
const;
672 void fixupGNULDRDAlias(StringRef Mnemonic,
OperandVector &Operands,
673 unsigned MnemonicOpsEndInd);
674 bool validateLDRDSTRD(MCInst &Inst,
const OperandVector &Operands,
bool Load,
675 bool ARMMode,
bool Writeback,
676 unsigned MnemonicOpsEndInd);
679 enum ARMMatchResultTy {
680 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
681 Match_RequiresNotITBlock,
683 Match_RequiresThumb2,
685 Match_RequiresFlagSetting,
686#define GET_OPERAND_DIAGNOSTIC_TYPES
687#include "ARMGenAsmMatcher.inc"
691 ARMAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
692 const MCInstrInfo &MII)
693 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
700 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
704 getTargetStreamer().emitTargetAttributes(STI);
707 ITState.CurPosition = ~0
U;
709 VPTState.CurPosition = ~0
U;
711 NextSymbolIsThumb =
false;
715 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
716 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
717 SMLoc &EndLoc)
override;
718 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
720 bool ParseDirective(AsmToken DirectiveID)
override;
722 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
723 unsigned Kind)
override;
724 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
726 checkEarlyTargetMatchPredicate(MCInst &Inst,
729 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
732 bool MatchingInlineAsm)
override;
733 unsigned MatchInstruction(
OperandVector &Operands, MCInst &Inst,
734 SmallVectorImpl<NearMissInfo> &NearMisses,
735 bool MatchingInlineAsm,
bool &EmitInITBlock,
738 struct NearMissMessage {
740 SmallString<128> Message;
743 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
745 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
746 SmallVectorImpl<NearMissMessage> &NearMissesOut,
748 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
751 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
753 void onLabelParsed(MCSymbol *Symbol)
override;
755 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
756 return MII.get(Opcode);
759 bool hasMVE()
const {
return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
762 MCRegister getDRegFromQReg(MCRegister QReg)
const {
763 return MRI->
getSubReg(QReg, ARM::dsub_0);
766 const MCRegisterInfo *getMRI()
const {
return MRI; }
771class ARMOperand :
public MCParsedAsmOperand {
782 k_InstSyncBarrierOpt,
783 k_TraceSyncBarrierOpt,
792 k_RegisterListWithAPSR,
795 k_FPSRegisterListWithVPR,
796 k_FPDRegisterListWithVPR,
798 k_VectorListAllLanes,
805 k_ConstantPoolImmediate,
806 k_BitfieldDescriptor,
810 SMLoc StartLoc, EndLoc, AlignmentLoc;
813 ARMAsmParser *Parser;
827 struct CoprocOptionOp {
869 struct VectorListOp {
876 struct VectorIndexOp {
886 MCRegister BaseRegNum;
889 const MCExpr *OffsetImm;
890 MCRegister OffsetRegNum;
895 unsigned isNegative : 1;
898 struct PostIdxRegOp {
905 struct ShifterImmOp {
910 struct RegShiftedRegOp {
917 struct RegShiftedImmOp {
941 struct CoprocOptionOp CoprocOption;
942 struct MBOptOp MBOpt;
943 struct ISBOptOp ISBOpt;
944 struct TSBOptOp TSBOpt;
945 struct ITMaskOp ITMask;
947 struct MMaskOp MMask;
948 struct BankedRegOp BankedReg;
951 struct VectorListOp VectorList;
952 struct VectorIndexOp VectorIndex;
954 struct MemoryOp Memory;
955 struct PostIdxRegOp PostIdxReg;
956 struct ShifterImmOp ShifterImm;
957 struct RegShiftedRegOp RegShiftedReg;
958 struct RegShiftedImmOp RegShiftedImm;
959 struct RotImmOp RotImm;
960 struct ModImmOp ModImm;
965 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(
K), Parser(&Parser) {}
968 SMLoc getStartLoc()
const override {
return StartLoc; }
971 SMLoc getEndLoc()
const override {
return EndLoc; }
975 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
978 SMLoc getAlignmentLoc()
const {
979 assert(Kind == k_Memory &&
"Invalid access!");
984 assert(Kind == k_CondCode &&
"Invalid access!");
989 assert(isVPTPred() &&
"Invalid access!");
993 unsigned getCoproc()
const {
994 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
999 assert(Kind == k_Token &&
"Invalid access!");
1000 return StringRef(Tok.Data, Tok.Length);
1003 MCRegister
getReg()
const override {
1004 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1008 const SmallVectorImpl<MCRegister> &getRegList()
const {
1009 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1010 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1011 Kind == k_FPSRegisterListWithVPR ||
1012 Kind == k_FPDRegisterListWithVPR) &&
1017 const MCExpr *
getImm()
const {
1018 assert(isImm() &&
"Invalid access!");
1022 const MCExpr *getConstantPoolImm()
const {
1023 assert(isConstantPoolImm() &&
"Invalid access!");
1027 unsigned getVectorIndex()
const {
1028 assert(Kind == k_VectorIndex &&
"Invalid access!");
1029 return VectorIndex.Val;
1033 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1038 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1043 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1048 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1052 unsigned getMSRMask()
const {
1053 assert(Kind == k_MSRMask &&
"Invalid access!");
1057 unsigned getBankedReg()
const {
1058 assert(Kind == k_BankedReg &&
"Invalid access!");
1059 return BankedReg.Val;
1062 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1063 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1064 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1066 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1067 bool isCCOut()
const {
return Kind == k_CCOut; }
1068 bool isITMask()
const {
return Kind == k_ITCondMask; }
1069 bool isITCondCode()
const {
return Kind == k_CondCode; }
1070 bool isImm()
const override {
1071 return Kind == k_Immediate;
1074 bool isARMBranchTarget()
const {
1075 if (!isImm())
return false;
1078 return CE->getValue() % 4 == 0;
1083 bool isThumbBranchTarget()
const {
1084 if (!isImm())
return false;
1087 return CE->getValue() % 2 == 0;
1093 template<
unsigned w
idth,
unsigned scale>
1094 bool isUnsignedOffset()
const {
1095 if (!isImm())
return false;
1098 int64_t Val =
CE->getValue();
1100 int64_t
Max =
Align * ((1LL << width) - 1);
1101 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1108 template<
unsigned w
idth,
unsigned scale>
1109 bool isSignedOffset()
const {
1110 if (!isImm())
return false;
1113 int64_t Val =
CE->getValue();
1115 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1116 int64_t Min = -
Align * (1LL << (width-1));
1117 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1124 bool isLEOffset()
const {
1125 if (!isImm())
return false;
1128 int64_t Val =
CE->getValue();
1129 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1138 bool isThumbMemPC()
const {
1143 if (!CE)
return false;
1144 Val =
CE->getValue();
1146 else if (isGPRMem()) {
1147 if(!Memory.OffsetImm || Memory.OffsetRegNum)
return false;
1148 if(Memory.BaseRegNum != ARM::PC)
return false;
1150 Val =
CE->getValue();
1155 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1158 bool isFPImm()
const {
1159 if (!isImm())
return false;
1167 template<
int64_t N,
int64_t M>
1168 bool isImmediate()
const {
1169 if (!isImm())
return false;
1171 if (!CE)
return false;
1172 int64_t
Value =
CE->getValue();
1176 template<
int64_t N,
int64_t M>
1177 bool isImmediateS4()
const {
1178 if (!isImm())
return false;
1180 if (!CE)
return false;
1181 int64_t
Value =
CE->getValue();
1187 Value == std::numeric_limits<int32_t>::min();
1189 template<
int64_t N,
int64_t M>
1190 bool isImmediateS2()
const {
1191 if (!isImm())
return false;
1193 if (!CE)
return false;
1194 int64_t
Value =
CE->getValue();
1197 bool isFBits16()
const {
1198 return isImmediate<0, 17>();
1200 bool isFBits32()
const {
1201 return isImmediate<1, 33>();
1203 bool isImm8s4()
const {
1204 return isImmediateS4<-1020, 1020>();
1206 bool isImm7s4()
const {
1207 return isImmediateS4<-508, 508>();
1209 bool isImm7Shift0()
const {
1210 return isImmediate<-127, 127>();
1212 bool isImm7Shift1()
const {
1213 return isImmediateS2<-255, 255>();
1215 bool isImm7Shift2()
const {
1216 return isImmediateS4<-511, 511>();
1218 bool isImm7()
const {
1219 return isImmediate<-127, 127>();
1221 bool isImm0_1020s4()
const {
1222 return isImmediateS4<0, 1020>();
1224 bool isImm0_508s4()
const {
1225 return isImmediateS4<0, 508>();
1227 bool isImm0_508s4Neg()
const {
1228 if (!isImm())
return false;
1230 if (!CE)
return false;
1231 int64_t
Value = -
CE->getValue();
1236 bool isImm0_4095Neg()
const {
1237 if (!isImm())
return false;
1239 if (!CE)
return false;
1244 if ((
CE->getValue() >> 32) > 0)
return false;
1245 uint32_t
Value = -
static_cast<uint32_t
>(
CE->getValue());
1249 bool isImm0_7()
const {
1250 return isImmediate<0, 7>();
1253 bool isImm1_16()
const {
1254 return isImmediate<1, 16>();
1257 bool isImm1_32()
const {
1258 return isImmediate<1, 32>();
1261 bool isImm8_255()
const {
1262 return isImmediate<8, 255>();
1265 bool isImm0_255Expr()
const {
1273 int64_t
Value =
CE->getValue();
1277 bool isImm256_65535Expr()
const {
1278 if (!isImm())
return false;
1282 if (!CE)
return true;
1283 int64_t
Value =
CE->getValue();
1287 bool isImm0_65535Expr()
const {
1288 if (!isImm())
return false;
1292 if (!CE)
return true;
1293 int64_t
Value =
CE->getValue();
1297 bool isImm24bit()
const {
1298 return isImmediate<0, 0xffffff + 1>();
1301 bool isImmThumbSR()
const {
1302 return isImmediate<1, 33>();
1305 bool isPKHLSLImm()
const {
1306 return isImmediate<0, 32>();
1309 bool isPKHASRImm()
const {
1310 return isImmediate<0, 33>();
1313 bool isAdrLabel()
const {
1320 if (!isImm())
return false;
1322 if (!CE)
return false;
1323 int64_t
Value =
CE->getValue();
1328 bool isT2SOImm()
const {
1335 return (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
1338 if (!isImm())
return false;
1340 if (!CE)
return false;
1341 int64_t
Value =
CE->getValue();
1345 bool isT2SOImmNot()
const {
1346 if (!isImm())
return false;
1348 if (!CE)
return false;
1349 int64_t
Value =
CE->getValue();
1354 bool isT2SOImmNeg()
const {
1355 if (!isImm())
return false;
1357 if (!CE)
return false;
1358 int64_t
Value =
CE->getValue();
1364 bool isSetEndImm()
const {
1365 if (!isImm())
return false;
1367 if (!CE)
return false;
1368 int64_t
Value =
CE->getValue();
1372 bool isReg()
const override {
return Kind == k_Register; }
1373 bool isRegList()
const {
return Kind == k_RegisterList; }
1374 bool isRegListWithAPSR()
const {
1375 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1377 bool isDReg()
const {
1379 getARMMCRegisterClass(ARM::DPRRegClassID).contains(
Reg.RegNum);
1381 bool isQReg()
const {
1383 getARMMCRegisterClass(ARM::QPRRegClassID).contains(
Reg.RegNum);
1385 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1386 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1387 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1388 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1389 bool isToken()
const override {
return Kind == k_Token; }
1390 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1391 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1392 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1393 bool isMem()
const override {
1394 return isGPRMem() || isMVEMem();
1396 bool isMVEMem()
const {
1397 if (Kind != k_Memory)
1399 if (Memory.BaseRegNum &&
1400 !getARMMCRegisterClass(ARM::GPRRegClassID)
1402 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1404 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1409 bool isGPRMem()
const {
1410 if (Kind != k_Memory)
1412 if (Memory.BaseRegNum &&
1413 !getARMMCRegisterClass(ARM::GPRRegClassID).
contains(Memory.BaseRegNum))
1415 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1420 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg()
const {
1422 return Kind == k_ShiftedRegister &&
1423 getARMMCRegisterClass(ARM::GPRRegClassID)
1424 .contains(RegShiftedReg.SrcReg) &&
1425 getARMMCRegisterClass(ARM::GPRRegClassID)
1426 .contains(RegShiftedReg.ShiftReg);
1428 bool isRegShiftedImm()
const {
1429 return Kind == k_ShiftedImmediate &&
1430 getARMMCRegisterClass(ARM::GPRRegClassID)
1431 .contains(RegShiftedImm.SrcReg);
1433 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1435 template<
unsigned Min,
unsigned Max>
1436 bool isPowerTwoInRange()
const {
1437 if (!isImm())
return false;
1439 if (!CE)
return false;
1440 int64_t
Value =
CE->getValue();
1444 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1446 bool isModImmNot()
const {
1447 if (!isImm())
return false;
1449 if (!CE)
return false;
1450 int64_t
Value =
CE->getValue();
1454 bool isModImmNeg()
const {
1455 if (!isImm())
return false;
1457 if (!CE)
return false;
1458 int64_t
Value =
CE->getValue();
1463 bool isThumbModImmNeg1_7()
const {
1464 if (!isImm())
return false;
1466 if (!CE)
return false;
1467 int32_t
Value = -(int32_t)
CE->getValue();
1471 bool isThumbModImmNeg8_255()
const {
1472 if (!isImm())
return false;
1474 if (!CE)
return false;
1475 int32_t
Value = -(int32_t)
CE->getValue();
1479 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1480 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1481 bool isPostIdxRegShifted()
const {
1482 return Kind == k_PostIndexRegister &&
1483 getARMMCRegisterClass(ARM::GPRRegClassID)
1484 .contains(PostIdxReg.RegNum);
1486 bool isPostIdxReg()
const {
1489 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1493 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1494 (alignOK || Memory.Alignment == Alignment);
1496 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1500 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1505 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1506 (alignOK || Memory.Alignment == Alignment);
1508 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1512 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).
contains(Memory.BaseRegNum))
1516 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1517 (alignOK || Memory.Alignment == Alignment);
1519 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1523 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).
contains(Memory.BaseRegNum))
1527 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1528 (alignOK || Memory.Alignment == Alignment);
1530 bool isMemPCRelImm12()
const {
1531 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1534 if (Memory.BaseRegNum != ARM::PC)
1537 if (!Memory.OffsetImm)
return true;
1539 int64_t Val =
CE->getValue();
1540 return (Val > -4096 && Val < 4096) ||
1541 (Val == std::numeric_limits<int32_t>::min());
1546 bool isAlignedMemory()
const {
1547 return isMemNoOffset(
true);
1550 bool isAlignedMemoryNone()
const {
1551 return isMemNoOffset(
false, 0);
1554 bool isDupAlignedMemoryNone()
const {
1555 return isMemNoOffset(
false, 0);
1558 bool isAlignedMemory16()
const {
1559 if (isMemNoOffset(
false, 2))
1561 return isMemNoOffset(
false, 0);
1564 bool isDupAlignedMemory16()
const {
1565 if (isMemNoOffset(
false, 2))
1567 return isMemNoOffset(
false, 0);
1570 bool isAlignedMemory32()
const {
1571 if (isMemNoOffset(
false, 4))
1573 return isMemNoOffset(
false, 0);
1576 bool isDupAlignedMemory32()
const {
1577 if (isMemNoOffset(
false, 4))
1579 return isMemNoOffset(
false, 0);
1582 bool isAlignedMemory64()
const {
1583 if (isMemNoOffset(
false, 8))
1585 return isMemNoOffset(
false, 0);
1588 bool isDupAlignedMemory64()
const {
1589 if (isMemNoOffset(
false, 8))
1591 return isMemNoOffset(
false, 0);
1594 bool isAlignedMemory64or128()
const {
1595 if (isMemNoOffset(
false, 8))
1597 if (isMemNoOffset(
false, 16))
1599 return isMemNoOffset(
false, 0);
1602 bool isDupAlignedMemory64or128()
const {
1603 if (isMemNoOffset(
false, 8))
1605 if (isMemNoOffset(
false, 16))
1607 return isMemNoOffset(
false, 0);
1610 bool isAlignedMemory64or128or256()
const {
1611 if (isMemNoOffset(
false, 8))
1613 if (isMemNoOffset(
false, 16))
1615 if (isMemNoOffset(
false, 32))
1617 return isMemNoOffset(
false, 0);
1620 bool isAddrMode2()
const {
1621 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1623 if (Memory.OffsetRegNum)
return true;
1625 if (!Memory.OffsetImm)
return true;
1627 int64_t Val =
CE->getValue();
1628 return Val > -4096 && Val < 4096;
1633 bool isAM2OffsetImm()
const {
1634 if (!isImm())
return false;
1637 if (!CE)
return false;
1638 int64_t Val =
CE->getValue();
1639 return (Val == std::numeric_limits<int32_t>::min()) ||
1640 (Val > -4096 && Val < 4096);
1643 bool isAddrMode3()
const {
1649 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1653 if (Memory.OffsetRegNum)
return true;
1655 if (!Memory.OffsetImm)
return true;
1657 int64_t Val =
CE->getValue();
1660 return (Val > -256 && Val < 256) ||
1661 Val == std::numeric_limits<int32_t>::min();
1666 bool isAM3Offset()
const {
1673 if (!CE)
return false;
1674 int64_t Val =
CE->getValue();
1676 return (Val > -256 && Val < 256) ||
1677 Val == std::numeric_limits<int32_t>::min();
1680 bool isAddrMode5()
const {
1686 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1688 if (Memory.OffsetRegNum)
return false;
1690 if (!Memory.OffsetImm)
return true;
1692 int64_t Val =
CE->getValue();
1693 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1694 Val == std::numeric_limits<int32_t>::min();
1699 bool isAddrMode5FP16()
const {
1705 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1707 if (Memory.OffsetRegNum)
return false;
1709 if (!Memory.OffsetImm)
return true;
1711 int64_t Val =
CE->getValue();
1712 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1713 Val == std::numeric_limits<int32_t>::min();
1718 bool isMemTBB()
const {
1719 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1725 bool isMemTBH()
const {
1726 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1727 Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm != 1 ||
1728 Memory.Alignment != 0 )
1733 bool isMemRegOffset()
const {
1734 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1739 bool isT2MemRegOffset()
const {
1740 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1741 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1746 if (Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm > 3)
1751 bool isMemThumbRR()
const {
1754 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1761 bool isMemThumbRIs4()
const {
1762 if (!isGPRMem() || Memory.OffsetRegNum ||
1766 if (!Memory.OffsetImm)
return true;
1768 int64_t Val =
CE->getValue();
1769 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1774 bool isMemThumbRIs2()
const {
1775 if (!isGPRMem() || Memory.OffsetRegNum ||
1779 if (!Memory.OffsetImm)
return true;
1781 int64_t Val =
CE->getValue();
1782 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1787 bool isMemThumbRIs1()
const {
1788 if (!isGPRMem() || Memory.OffsetRegNum ||
1792 if (!Memory.OffsetImm)
return true;
1794 int64_t Val =
CE->getValue();
1795 return Val >= 0 && Val <= 31;
1800 bool isMemThumbSPI()
const {
1801 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1802 Memory.Alignment != 0)
1805 if (!Memory.OffsetImm)
return true;
1807 int64_t Val =
CE->getValue();
1808 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1813 bool isMemImm8s4Offset()
const {
1819 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1822 if (!Memory.OffsetImm)
return true;
1824 int64_t Val =
CE->getValue();
1826 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1827 Val == std::numeric_limits<int32_t>::min();
1832 bool isMemImm7s4Offset()
const {
1838 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1839 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1843 if (!Memory.OffsetImm)
return true;
1845 int64_t Val =
CE->getValue();
1847 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1852 bool isMemImm0_1020s4Offset()
const {
1853 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1856 if (!Memory.OffsetImm)
return true;
1858 int64_t Val =
CE->getValue();
1859 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1864 bool isMemImm8Offset()
const {
1865 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1868 if (Memory.BaseRegNum == ARM::PC)
return false;
1870 if (!Memory.OffsetImm)
return true;
1872 int64_t Val =
CE->getValue();
1873 return (Val == std::numeric_limits<int32_t>::min()) ||
1874 (Val > -256 && Val < 256);
1879 template<
unsigned Bits,
unsigned RegClassID>
1880 bool isMemImm7ShiftedOffset()
const {
1881 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1882 !getARMMCRegisterClass(RegClassID).
contains(Memory.BaseRegNum))
1888 if (!Memory.OffsetImm)
return true;
1890 int64_t Val =
CE->getValue();
1894 if (Val == INT32_MIN)
1897 unsigned Divisor = 1U <<
Bits;
1900 if (Val % Divisor != 0)
1905 return (Val >= -127 && Val <= 127);
1910 template <
int shift>
bool isMemRegRQOffset()
const {
1911 if (!isMVEMem() || Memory.OffsetImm !=
nullptr || Memory.Alignment != 0)
1914 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1917 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1925 (Memory.ShiftType !=
ARM_AM::uxtw || Memory.ShiftImm != shift))
1931 template <
int shift>
bool isMemRegQOffset()
const {
1932 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1935 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1938 if (!Memory.OffsetImm)
1940 static_assert(shift < 56,
1941 "Such that we dont shift by a value higher than 62");
1943 int64_t Val =
CE->getValue();
1946 if ((Val & ((1U << shift) - 1)) != 0)
1952 int64_t
Range = (1U << (7 + shift)) - 1;
1953 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1958 bool isMemPosImm8Offset()
const {
1959 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1962 if (!Memory.OffsetImm)
return true;
1964 int64_t Val =
CE->getValue();
1965 return Val >= 0 && Val < 256;
1970 bool isMemNegImm8Offset()
const {
1971 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1974 if (Memory.BaseRegNum == ARM::PC)
return false;
1976 if (!Memory.OffsetImm)
return false;
1978 int64_t Val =
CE->getValue();
1979 return (Val == std::numeric_limits<int32_t>::min()) ||
1980 (Val > -256 && Val < 0);
1985 bool isMemUImm12Offset()
const {
1986 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1989 if (!Memory.OffsetImm)
return true;
1991 int64_t Val =
CE->getValue();
1992 return (Val >= 0 && Val < 4096);
1997 bool isMemImm12Offset()
const {
2005 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2008 if (!Memory.OffsetImm)
return true;
2010 int64_t Val =
CE->getValue();
2011 return (Val > -4096 && Val < 4096) ||
2012 (Val == std::numeric_limits<int32_t>::min());
2019 bool isConstPoolAsmImm()
const {
2022 return (isConstantPoolImm());
2025 bool isPostIdxImm8()
const {
2026 if (!isImm())
return false;
2028 if (!CE)
return false;
2029 int64_t Val =
CE->getValue();
2030 return (Val > -256 && Val < 256) ||
2031 (Val == std::numeric_limits<int32_t>::min());
2034 bool isPostIdxImm8s4()
const {
2035 if (!isImm())
return false;
2037 if (!CE)
return false;
2038 int64_t Val =
CE->getValue();
2039 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2040 (Val == std::numeric_limits<int32_t>::min());
2043 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2044 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2045 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2048 bool isAnyVectorList()
const {
2049 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2050 Kind == k_VectorListIndexed;
2053 bool isVectorList()
const {
return Kind == k_VectorList; }
2055 bool isSingleSpacedVectorList()
const {
2056 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2059 bool isDoubleSpacedVectorList()
const {
2060 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2063 bool isVecListOneD()
const {
2065 if (isDReg() && !Parser->hasMVE())
2067 if (!isSingleSpacedVectorList())
return false;
2068 return VectorList.Count == 1;
2071 bool isVecListTwoMQ()
const {
2072 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2073 getARMMCRegisterClass(ARM::MQPRRegClassID)
2074 .contains(VectorList.RegNum);
2077 bool isVecListDPair()
const {
2080 if (isQReg() && !Parser->hasMVE())
2082 if (!isSingleSpacedVectorList())
return false;
2083 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2087 bool isVecListThreeD()
const {
2088 if (!isSingleSpacedVectorList())
return false;
2089 return VectorList.Count == 3;
2092 bool isVecListFourD()
const {
2093 if (!isSingleSpacedVectorList())
return false;
2094 return VectorList.Count == 4;
2097 bool isVecListDPairSpaced()
const {
2098 if (Kind != k_VectorList)
return false;
2099 if (isSingleSpacedVectorList())
return false;
2100 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2104 bool isVecListThreeQ()
const {
2105 if (!isDoubleSpacedVectorList())
return false;
2106 return VectorList.Count == 3;
2109 bool isVecListFourQ()
const {
2110 if (!isDoubleSpacedVectorList())
return false;
2111 return VectorList.Count == 4;
2114 bool isVecListFourMQ()
const {
2115 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2116 getARMMCRegisterClass(ARM::MQPRRegClassID)
2117 .contains(VectorList.RegNum);
2120 bool isSingleSpacedVectorAllLanes()
const {
2121 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2124 bool isDoubleSpacedVectorAllLanes()
const {
2125 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2128 bool isVecListOneDAllLanes()
const {
2129 if (!isSingleSpacedVectorAllLanes())
return false;
2130 return VectorList.Count == 1;
2133 bool isVecListDPairAllLanes()
const {
2134 if (!isSingleSpacedVectorAllLanes())
return false;
2135 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2139 bool isVecListDPairSpacedAllLanes()
const {
2140 if (!isDoubleSpacedVectorAllLanes())
return false;
2141 return VectorList.Count == 2;
2144 bool isVecListThreeDAllLanes()
const {
2145 if (!isSingleSpacedVectorAllLanes())
return false;
2146 return VectorList.Count == 3;
2149 bool isVecListThreeQAllLanes()
const {
2150 if (!isDoubleSpacedVectorAllLanes())
return false;
2151 return VectorList.Count == 3;
2154 bool isVecListFourDAllLanes()
const {
2155 if (!isSingleSpacedVectorAllLanes())
return false;
2156 return VectorList.Count == 4;
2159 bool isVecListFourQAllLanes()
const {
2160 if (!isDoubleSpacedVectorAllLanes())
return false;
2161 return VectorList.Count == 4;
2164 bool isSingleSpacedVectorIndexed()
const {
2165 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2168 bool isDoubleSpacedVectorIndexed()
const {
2169 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2172 bool isVecListOneDByteIndexed()
const {
2173 if (!isSingleSpacedVectorIndexed())
return false;
2174 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2177 bool isVecListOneDHWordIndexed()
const {
2178 if (!isSingleSpacedVectorIndexed())
return false;
2179 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2182 bool isVecListOneDWordIndexed()
const {
2183 if (!isSingleSpacedVectorIndexed())
return false;
2184 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2187 bool isVecListTwoDByteIndexed()
const {
2188 if (!isSingleSpacedVectorIndexed())
return false;
2189 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2192 bool isVecListTwoDHWordIndexed()
const {
2193 if (!isSingleSpacedVectorIndexed())
return false;
2194 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2197 bool isVecListTwoQWordIndexed()
const {
2198 if (!isDoubleSpacedVectorIndexed())
return false;
2199 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2202 bool isVecListTwoQHWordIndexed()
const {
2203 if (!isDoubleSpacedVectorIndexed())
return false;
2204 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2207 bool isVecListTwoDWordIndexed()
const {
2208 if (!isSingleSpacedVectorIndexed())
return false;
2209 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2212 bool isVecListThreeDByteIndexed()
const {
2213 if (!isSingleSpacedVectorIndexed())
return false;
2214 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2217 bool isVecListThreeDHWordIndexed()
const {
2218 if (!isSingleSpacedVectorIndexed())
return false;
2219 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2222 bool isVecListThreeQWordIndexed()
const {
2223 if (!isDoubleSpacedVectorIndexed())
return false;
2224 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2227 bool isVecListThreeQHWordIndexed()
const {
2228 if (!isDoubleSpacedVectorIndexed())
return false;
2229 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2232 bool isVecListThreeDWordIndexed()
const {
2233 if (!isSingleSpacedVectorIndexed())
return false;
2234 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2237 bool isVecListFourDByteIndexed()
const {
2238 if (!isSingleSpacedVectorIndexed())
return false;
2239 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2242 bool isVecListFourDHWordIndexed()
const {
2243 if (!isSingleSpacedVectorIndexed())
return false;
2244 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2247 bool isVecListFourQWordIndexed()
const {
2248 if (!isDoubleSpacedVectorIndexed())
return false;
2249 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2252 bool isVecListFourQHWordIndexed()
const {
2253 if (!isDoubleSpacedVectorIndexed())
return false;
2254 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2257 bool isVecListFourDWordIndexed()
const {
2258 if (!isSingleSpacedVectorIndexed())
return false;
2259 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2262 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2264 template <
unsigned NumLanes>
2265 bool isVectorIndexInRange()
const {
2266 if (Kind != k_VectorIndex)
return false;
2267 return VectorIndex.Val < NumLanes;
2270 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2271 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2272 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2273 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2275 template<
int PermittedValue,
int OtherPermittedValue>
2276 bool isMVEPairVectorIndex()
const {
2277 if (Kind != k_VectorIndex)
return false;
2278 return VectorIndex.Val == PermittedValue ||
2279 VectorIndex.Val == OtherPermittedValue;
2282 bool isNEONi8splat()
const {
2283 if (!isImm())
return false;
2286 if (!CE)
return false;
2287 int64_t
Value =
CE->getValue();
2294 if (isNEONByteReplicate(2))
2300 if (!CE)
return false;
2301 unsigned Value =
CE->getValue();
2305 bool isNEONi16splatNot()
const {
2310 if (!CE)
return false;
2311 unsigned Value =
CE->getValue();
2316 if (isNEONByteReplicate(4))
2322 if (!CE)
return false;
2323 unsigned Value =
CE->getValue();
2327 bool isNEONi32splatNot()
const {
2332 if (!CE)
return false;
2333 unsigned Value =
CE->getValue();
2337 static bool isValidNEONi32vmovImm(int64_t
Value) {
2340 return ((
Value & 0xffffffffffffff00) == 0) ||
2341 ((
Value & 0xffffffffffff00ff) == 0) ||
2342 ((
Value & 0xffffffffff00ffff) == 0) ||
2343 ((
Value & 0xffffffff00ffffff) == 0) ||
2344 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2345 ((
Value & 0xffffffffff00ffff) == 0xffff);
2348 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2349 assert((Width == 8 || Width == 16 || Width == 32) &&
2350 "Invalid element width");
2351 assert(NumElems * Width <= 64 &&
"Invalid result width");
2359 int64_t
Value =
CE->getValue();
2365 uint64_t
Mask = (1ull << Width) - 1;
2367 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2369 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2372 for (
unsigned i = 1; i < NumElems; ++i) {
2374 if ((
Value & Mask) != Elem)
2380 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2381 return isNEONReplicate(8, NumBytes,
false);
2384 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2385 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2386 "Invalid source width");
2387 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2388 "Invalid destination width");
2389 assert(FromW < ToW &&
"ToW is not less than FromW");
2392 template<
unsigned FromW,
unsigned ToW>
2393 bool isNEONmovReplicate()
const {
2394 checkNeonReplicateArgs(FromW, ToW);
2395 if (ToW == 64 && isNEONi64splat())
2397 return isNEONReplicate(FromW, ToW / FromW,
false);
2400 template<
unsigned FromW,
unsigned ToW>
2401 bool isNEONinvReplicate()
const {
2402 checkNeonReplicateArgs(FromW, ToW);
2403 return isNEONReplicate(FromW, ToW / FromW,
true);
2406 bool isNEONi32vmov()
const {
2407 if (isNEONByteReplicate(4))
2415 return isValidNEONi32vmovImm(
CE->getValue());
2418 bool isNEONi32vmovNeg()
const {
2419 if (!isImm())
return false;
2422 if (!CE)
return false;
2423 return isValidNEONi32vmovImm(~
CE->getValue());
2426 bool isNEONi64splat()
const {
2427 if (!isImm())
return false;
2430 if (!CE)
return false;
2431 uint64_t
Value =
CE->getValue();
2433 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2434 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2438 template<
int64_t Angle,
int64_t Remainder>
2439 bool isComplexRotation()
const {
2440 if (!isImm())
return false;
2443 if (!CE)
return false;
2444 uint64_t
Value =
CE->getValue();
2446 return (
Value % Angle == Remainder &&
Value <= 270);
2449 bool isMVELongShift()
const {
2450 if (!isImm())
return false;
2453 if (!CE)
return false;
2454 uint64_t
Value =
CE->getValue();
2458 bool isMveSaturateOp()
const {
2459 if (!isImm())
return false;
2461 if (!CE)
return false;
2462 uint64_t
Value =
CE->getValue();
2466 bool isITCondCodeNoAL()
const {
2467 if (!isITCondCode())
return false;
2472 bool isITCondCodeRestrictedI()
const {
2473 if (!isITCondCode())
2479 bool isITCondCodeRestrictedS()
const {
2480 if (!isITCondCode())
2487 bool isITCondCodeRestrictedU()
const {
2488 if (!isITCondCode())
2494 bool isITCondCodeRestrictedFP()
const {
2495 if (!isITCondCode())
2502 void setVecListDPair(
unsigned int DPair) {
2503 Kind = k_VectorList;
2504 VectorList.RegNum = DPair;
2505 VectorList.Count = 2;
2506 VectorList.isDoubleSpaced =
false;
2509 void setVecListOneD(
unsigned int DReg) {
2510 Kind = k_VectorList;
2511 VectorList.RegNum =
DReg;
2512 VectorList.Count = 1;
2513 VectorList.isDoubleSpaced =
false;
2516 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
2526 void addARMBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2527 assert(
N == 1 &&
"Invalid number of operands!");
2531 void addThumbBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2532 assert(
N == 1 &&
"Invalid number of operands!");
2536 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2537 assert(
N == 2 &&
"Invalid number of operands!");
2543 void addVPTPredNOperands(MCInst &Inst,
unsigned N)
const {
2544 assert(
N == 3 &&
"Invalid number of operands!");
2546 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2551 void addVPTPredROperands(MCInst &Inst,
unsigned N)
const {
2552 assert(
N == 4 &&
"Invalid number of operands!");
2553 addVPTPredNOperands(Inst,
N-1);
2556 RegNum = ARM::NoRegister;
2559 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2560 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2562 "Inactive register in vpred_r is not tied to an output!");
2568 void addCoprocNumOperands(MCInst &Inst,
unsigned N)
const {
2569 assert(
N == 1 &&
"Invalid number of operands!");
2573 void addCoprocRegOperands(MCInst &Inst,
unsigned N)
const {
2574 assert(
N == 1 &&
"Invalid number of operands!");
2578 void addCoprocOptionOperands(MCInst &Inst,
unsigned N)
const {
2579 assert(
N == 1 &&
"Invalid number of operands!");
2583 void addITMaskOperands(MCInst &Inst,
unsigned N)
const {
2584 assert(
N == 1 &&
"Invalid number of operands!");
2588 void addITCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2589 assert(
N == 1 &&
"Invalid number of operands!");
2593 void addITCondCodeInvOperands(MCInst &Inst,
unsigned N)
const {
2594 assert(
N == 1 &&
"Invalid number of operands!");
2598 void addCCOutOperands(MCInst &Inst,
unsigned N)
const {
2599 assert(
N == 1 &&
"Invalid number of operands!");
2603 void addRegOperands(MCInst &Inst,
unsigned N)
const {
2604 assert(
N == 1 &&
"Invalid number of operands!");
2608 void addRegShiftedRegOperands(MCInst &Inst,
unsigned N)
const {
2609 assert(
N == 3 &&
"Invalid number of operands!");
2610 assert(isRegShiftedReg() &&
2611 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2618 void addRegShiftedImmOperands(MCInst &Inst,
unsigned N)
const {
2619 assert(
N == 2 &&
"Invalid number of operands!");
2620 assert(isRegShiftedImm() &&
2621 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2624 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2629 void addShifterImmOperands(MCInst &Inst,
unsigned N)
const {
2630 assert(
N == 1 &&
"Invalid number of operands!");
2635 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
2636 assert(
N == 1 &&
"Invalid number of operands!");
2637 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2638 for (MCRegister
Reg : RegList)
2642 void addRegListWithAPSROperands(MCInst &Inst,
unsigned N)
const {
2643 assert(
N == 1 &&
"Invalid number of operands!");
2644 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2645 for (MCRegister
Reg : RegList)
2649 void addDPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2650 addRegListOperands(Inst,
N);
2653 void addSPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2654 addRegListOperands(Inst,
N);
2657 void addFPSRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2658 addRegListOperands(Inst,
N);
2661 void addFPDRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2662 addRegListOperands(Inst,
N);
2665 void addRotImmOperands(MCInst &Inst,
unsigned N)
const {
2666 assert(
N == 1 &&
"Invalid number of operands!");
2671 void addModImmOperands(MCInst &Inst,
unsigned N)
const {
2672 assert(
N == 1 &&
"Invalid number of operands!");
2676 return addImmOperands(Inst,
N);
2681 void addModImmNotOperands(MCInst &Inst,
unsigned N)
const {
2682 assert(
N == 1 &&
"Invalid number of operands!");
2688 void addModImmNegOperands(MCInst &Inst,
unsigned N)
const {
2689 assert(
N == 1 &&
"Invalid number of operands!");
2695 void addThumbModImmNeg8_255Operands(MCInst &Inst,
unsigned N)
const {
2696 assert(
N == 1 &&
"Invalid number of operands!");
2698 uint32_t Val = -
CE->getValue();
2702 void addThumbModImmNeg1_7Operands(MCInst &Inst,
unsigned N)
const {
2703 assert(
N == 1 &&
"Invalid number of operands!");
2705 uint32_t Val = -
CE->getValue();
2709 void addBitfieldOperands(MCInst &Inst,
unsigned N)
const {
2710 assert(
N == 1 &&
"Invalid number of operands!");
2715 uint32_t
Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2716 (32 - (lsb + width)));
2720 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2721 assert(
N == 1 &&
"Invalid number of operands!");
2725 void addFBits16Operands(MCInst &Inst,
unsigned N)
const {
2726 assert(
N == 1 &&
"Invalid number of operands!");
2731 void addFBits32Operands(MCInst &Inst,
unsigned N)
const {
2732 assert(
N == 1 &&
"Invalid number of operands!");
2737 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2738 assert(
N == 1 &&
"Invalid number of operands!");
2744 void addImm8s4Operands(MCInst &Inst,
unsigned N)
const {
2745 assert(
N == 1 &&
"Invalid number of operands!");
2752 void addImm7s4Operands(MCInst &Inst,
unsigned N)
const {
2753 assert(
N == 1 &&
"Invalid number of operands!");
2760 void addImm7Shift0Operands(MCInst &Inst,
unsigned N)
const {
2761 assert(
N == 1 &&
"Invalid number of operands!");
2766 void addImm7Shift1Operands(MCInst &Inst,
unsigned N)
const {
2767 assert(
N == 1 &&
"Invalid number of operands!");
2772 void addImm7Shift2Operands(MCInst &Inst,
unsigned N)
const {
2773 assert(
N == 1 &&
"Invalid number of operands!");
2778 void addImm7Operands(MCInst &Inst,
unsigned N)
const {
2779 assert(
N == 1 &&
"Invalid number of operands!");
2784 void addImm0_1020s4Operands(MCInst &Inst,
unsigned N)
const {
2785 assert(
N == 1 &&
"Invalid number of operands!");
2792 void addImm0_508s4NegOperands(MCInst &Inst,
unsigned N)
const {
2793 assert(
N == 1 &&
"Invalid number of operands!");
2800 void addImm0_508s4Operands(MCInst &Inst,
unsigned N)
const {
2801 assert(
N == 1 &&
"Invalid number of operands!");
2808 void addImm1_16Operands(MCInst &Inst,
unsigned N)
const {
2809 assert(
N == 1 &&
"Invalid number of operands!");
2816 void addImm1_32Operands(MCInst &Inst,
unsigned N)
const {
2817 assert(
N == 1 &&
"Invalid number of operands!");
2824 void addImmThumbSROperands(MCInst &Inst,
unsigned N)
const {
2825 assert(
N == 1 &&
"Invalid number of operands!");
2829 unsigned Imm =
CE->getValue();
2833 void addPKHASRImmOperands(MCInst &Inst,
unsigned N)
const {
2834 assert(
N == 1 &&
"Invalid number of operands!");
2838 int Val =
CE->getValue();
2842 void addT2SOImmNotOperands(MCInst &Inst,
unsigned N)
const {
2843 assert(
N == 1 &&
"Invalid number of operands!");
2850 void addT2SOImmNegOperands(MCInst &Inst,
unsigned N)
const {
2851 assert(
N == 1 &&
"Invalid number of operands!");
2858 void addImm0_4095NegOperands(MCInst &Inst,
unsigned N)
const {
2859 assert(
N == 1 &&
"Invalid number of operands!");
2866 void addUnsignedOffset_b8s2Operands(MCInst &Inst,
unsigned N)
const {
2875 void addThumbMemPCOperands(MCInst &Inst,
unsigned N)
const {
2876 assert(
N == 1 &&
"Invalid number of operands!");
2888 assert(isGPRMem() &&
"Unknown value type!");
2896 void addMemBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2897 assert(
N == 1 &&
"Invalid number of operands!");
2901 void addInstSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2902 assert(
N == 1 &&
"Invalid number of operands!");
2906 void addTraceSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2907 assert(
N == 1 &&
"Invalid number of operands!");
2911 void addMemNoOffsetOperands(MCInst &Inst,
unsigned N)
const {
2912 assert(
N == 1 &&
"Invalid number of operands!");
2916 void addMemNoOffsetT2Operands(MCInst &Inst,
unsigned N)
const {
2917 assert(
N == 1 &&
"Invalid number of operands!");
2921 void addMemNoOffsetT2NoSpOperands(MCInst &Inst,
unsigned N)
const {
2922 assert(
N == 1 &&
"Invalid number of operands!");
2926 void addMemNoOffsetTOperands(MCInst &Inst,
unsigned N)
const {
2927 assert(
N == 1 &&
"Invalid number of operands!");
2931 void addMemPCRelImm12Operands(MCInst &Inst,
unsigned N)
const {
2932 assert(
N == 1 &&
"Invalid number of operands!");
2939 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2940 assert(
N == 1 &&
"Invalid number of operands!");
2941 assert(isImm() &&
"Not an immediate!");
2951 int Val =
CE->getValue();
2955 void addAlignedMemoryOperands(MCInst &Inst,
unsigned N)
const {
2956 assert(
N == 2 &&
"Invalid number of operands!");
2961 void addDupAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2962 addAlignedMemoryOperands(Inst,
N);
2965 void addAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2966 addAlignedMemoryOperands(Inst,
N);
2969 void addAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2970 addAlignedMemoryOperands(Inst,
N);
2973 void addDupAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2974 addAlignedMemoryOperands(Inst,
N);
2977 void addAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2978 addAlignedMemoryOperands(Inst,
N);
2981 void addDupAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2982 addAlignedMemoryOperands(Inst,
N);
2985 void addAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2986 addAlignedMemoryOperands(Inst,
N);
2989 void addDupAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2990 addAlignedMemoryOperands(Inst,
N);
2993 void addAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2994 addAlignedMemoryOperands(Inst,
N);
2997 void addDupAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2998 addAlignedMemoryOperands(Inst,
N);
3001 void addAlignedMemory64or128or256Operands(MCInst &Inst,
unsigned N)
const {
3002 addAlignedMemoryOperands(Inst,
N);
3005 void addAddrMode2Operands(MCInst &Inst,
unsigned N)
const {
3006 assert(
N == 3 &&
"Invalid number of operands!");
3009 if (!Memory.OffsetRegNum) {
3010 if (!Memory.OffsetImm)
3013 int32_t Val =
CE->getValue();
3016 if (Val == std::numeric_limits<int32_t>::min())
3029 Memory.ShiftImm, Memory.ShiftType);
3034 void addAM2OffsetImmOperands(MCInst &Inst,
unsigned N)
const {
3035 assert(
N == 2 &&
"Invalid number of operands!");
3037 assert(CE &&
"non-constant AM2OffsetImm operand!");
3038 int32_t Val =
CE->getValue();
3041 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3042 if (Val < 0) Val = -Val;
3048 void addAddrMode3Operands(MCInst &Inst,
unsigned N)
const {
3049 assert(
N == 3 &&
"Invalid number of operands!");
3062 if (!Memory.OffsetRegNum) {
3063 if (!Memory.OffsetImm)
3066 int32_t Val =
CE->getValue();
3069 if (Val == std::numeric_limits<int32_t>::min())
3086 void addAM3OffsetOperands(MCInst &Inst,
unsigned N)
const {
3087 assert(
N == 2 &&
"Invalid number of operands!");
3088 if (Kind == k_PostIndexRegister) {
3097 const MCConstantExpr *
CE =
static_cast<const MCConstantExpr*
>(
getImm());
3098 int32_t Val =
CE->getValue();
3101 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3102 if (Val < 0) Val = -Val;
3108 void addAddrMode5Operands(MCInst &Inst,
unsigned N)
const {
3109 assert(
N == 2 &&
"Invalid number of operands!");
3120 if (!Memory.OffsetImm)
3124 int32_t Val =
CE->getValue() / 4;
3127 if (Val == std::numeric_limits<int32_t>::min())
3137 void addAddrMode5FP16Operands(MCInst &Inst,
unsigned N)
const {
3138 assert(
N == 2 &&
"Invalid number of operands!");
3150 if (!Memory.OffsetImm)
3153 int32_t Val =
CE->getValue() / 2;
3156 if (Val == std::numeric_limits<int32_t>::min())
3166 void addMemImm8s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3167 assert(
N == 2 &&
"Invalid number of operands!");
3178 addExpr(Inst, Memory.OffsetImm);
3181 void addMemImm7s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3182 assert(
N == 2 &&
"Invalid number of operands!");
3193 addExpr(Inst, Memory.OffsetImm);
3196 void addMemImm0_1020s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3197 assert(
N == 2 &&
"Invalid number of operands!");
3199 if (!Memory.OffsetImm)
3208 void addMemImmOffsetOperands(MCInst &Inst,
unsigned N)
const {
3209 assert(
N == 2 &&
"Invalid number of operands!");
3211 addExpr(Inst, Memory.OffsetImm);
3214 void addMemRegRQOffsetOperands(MCInst &Inst,
unsigned N)
const {
3215 assert(
N == 2 &&
"Invalid number of operands!");
3220 void addMemUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3221 assert(
N == 2 &&
"Invalid number of operands!");
3231 addExpr(Inst, Memory.OffsetImm);
3234 void addMemImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3235 assert(
N == 2 &&
"Invalid number of operands!");
3245 addExpr(Inst, Memory.OffsetImm);
3248 void addConstPoolAsmImmOperands(MCInst &Inst,
unsigned N)
const {
3249 assert(
N == 1 &&
"Invalid number of operands!");
3252 addExpr(Inst, getConstantPoolImm());
3255 void addMemTBBOperands(MCInst &Inst,
unsigned N)
const {
3256 assert(
N == 2 &&
"Invalid number of operands!");
3261 void addMemTBHOperands(MCInst &Inst,
unsigned N)
const {
3262 assert(
N == 2 &&
"Invalid number of operands!");
3267 void addMemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3268 assert(
N == 3 &&
"Invalid number of operands!");
3271 Memory.ShiftImm, Memory.ShiftType);
3277 void addT2MemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3278 assert(
N == 3 &&
"Invalid number of operands!");
3284 void addMemThumbRROperands(MCInst &Inst,
unsigned N)
const {
3285 assert(
N == 2 &&
"Invalid number of operands!");
3290 void addMemThumbRIs4Operands(MCInst &Inst,
unsigned N)
const {
3291 assert(
N == 2 &&
"Invalid number of operands!");
3293 if (!Memory.OffsetImm)
3302 void addMemThumbRIs2Operands(MCInst &Inst,
unsigned N)
const {
3303 assert(
N == 2 &&
"Invalid number of operands!");
3305 if (!Memory.OffsetImm)
3313 void addMemThumbRIs1Operands(MCInst &Inst,
unsigned N)
const {
3314 assert(
N == 2 &&
"Invalid number of operands!");
3316 addExpr(Inst, Memory.OffsetImm);
3319 void addMemThumbSPIOperands(MCInst &Inst,
unsigned N)
const {
3320 assert(
N == 2 &&
"Invalid number of operands!");
3322 if (!Memory.OffsetImm)
3331 void addPostIdxImm8Operands(MCInst &Inst,
unsigned N)
const {
3332 assert(
N == 1 &&
"Invalid number of operands!");
3334 assert(CE &&
"non-constant post-idx-imm8 operand!");
3335 int Imm =
CE->getValue();
3336 bool isAdd =
Imm >= 0;
3337 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3342 void addPostIdxImm8s4Operands(MCInst &Inst,
unsigned N)
const {
3343 assert(
N == 1 &&
"Invalid number of operands!");
3345 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3346 int Imm =
CE->getValue();
3347 bool isAdd =
Imm >= 0;
3348 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3354 void addPostIdxRegOperands(MCInst &Inst,
unsigned N)
const {
3355 assert(
N == 2 &&
"Invalid number of operands!");
3360 void addPostIdxRegShiftedOperands(MCInst &Inst,
unsigned N)
const {
3361 assert(
N == 2 &&
"Invalid number of operands!");
3367 PostIdxReg.ShiftTy);
3371 void addPowerTwoOperands(MCInst &Inst,
unsigned N)
const {
3372 assert(
N == 1 &&
"Invalid number of operands!");
3377 void addMSRMaskOperands(MCInst &Inst,
unsigned N)
const {
3378 assert(
N == 1 &&
"Invalid number of operands!");
3382 void addBankedRegOperands(MCInst &Inst,
unsigned N)
const {
3383 assert(
N == 1 &&
"Invalid number of operands!");
3387 void addProcIFlagsOperands(MCInst &Inst,
unsigned N)
const {
3388 assert(
N == 1 &&
"Invalid number of operands!");
3392 void addVecListOperands(MCInst &Inst,
unsigned N)
const {
3393 assert(
N == 1 &&
"Invalid number of operands!");
3395 if (isAnyVectorList())
3397 else if (isDReg() && !Parser->hasMVE()) {
3399 }
else if (isQReg() && !Parser->hasMVE()) {
3400 MCRegister DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3401 DPair = Parser->getMRI()->getMatchingSuperReg(
3402 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3407 "attempted to add a vector list register with wrong type!");
3411 void addMVEVecListOperands(MCInst &Inst,
unsigned N)
const {
3412 assert(
N == 1 &&
"Invalid number of operands!");
3428 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3429 const MCRegisterClass *RC_out =
3430 (VectorList.Count == 2)
3431 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3432 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3435 for (
I = 0;
I <
E;
I++)
3438 assert(
I <
E &&
"Invalid vector list start register!");
3443 void addVecListIndexedOperands(MCInst &Inst,
unsigned N)
const {
3444 assert(
N == 2 &&
"Invalid number of operands!");
3449 void addVectorIndex8Operands(MCInst &Inst,
unsigned N)
const {
3450 assert(
N == 1 &&
"Invalid number of operands!");
3454 void addVectorIndex16Operands(MCInst &Inst,
unsigned N)
const {
3455 assert(
N == 1 &&
"Invalid number of operands!");
3459 void addVectorIndex32Operands(MCInst &Inst,
unsigned N)
const {
3460 assert(
N == 1 &&
"Invalid number of operands!");
3464 void addVectorIndex64Operands(MCInst &Inst,
unsigned N)
const {
3465 assert(
N == 1 &&
"Invalid number of operands!");
3469 void addMVEVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3470 assert(
N == 1 &&
"Invalid number of operands!");
3474 void addMVEPairVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3475 assert(
N == 1 &&
"Invalid number of operands!");
3479 void addNEONi8splatOperands(MCInst &Inst,
unsigned N)
const {
3480 assert(
N == 1 &&
"Invalid number of operands!");
3487 void addNEONi16splatOperands(MCInst &Inst,
unsigned N)
const {
3488 assert(
N == 1 &&
"Invalid number of operands!");
3491 unsigned Value =
CE->getValue();
3496 void addNEONi16splatNotOperands(MCInst &Inst,
unsigned N)
const {
3497 assert(
N == 1 &&
"Invalid number of operands!");
3500 unsigned Value =
CE->getValue();
3505 void addNEONi32splatOperands(MCInst &Inst,
unsigned N)
const {
3506 assert(
N == 1 &&
"Invalid number of operands!");
3509 unsigned Value =
CE->getValue();
3514 void addNEONi32splatNotOperands(MCInst &Inst,
unsigned N)
const {
3515 assert(
N == 1 &&
"Invalid number of operands!");
3518 unsigned Value =
CE->getValue();
3523 void addNEONi8ReplicateOperands(MCInst &Inst,
bool Inv)
const {
3528 "All instructions that wants to replicate non-zero byte "
3529 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3530 unsigned Value =
CE->getValue();
3533 unsigned B =
Value & 0xff;
3538 void addNEONinvi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3539 assert(
N == 1 &&
"Invalid number of operands!");
3540 addNEONi8ReplicateOperands(Inst,
true);
3543 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3546 else if (
Value > 0xffff &&
Value <= 0xffffff)
3548 else if (
Value > 0xffffff)
3553 void addNEONi32vmovOperands(MCInst &Inst,
unsigned N)
const {
3554 assert(
N == 1 &&
"Invalid number of operands!");
3557 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3561 void addNEONvmovi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3562 assert(
N == 1 &&
"Invalid number of operands!");
3563 addNEONi8ReplicateOperands(Inst,
false);
3566 void addNEONvmovi16ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3567 assert(
N == 1 &&
"Invalid number of operands!");
3573 "All instructions that want to replicate non-zero half-word "
3574 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3575 uint64_t
Value =
CE->getValue();
3576 unsigned Elem =
Value & 0xffff;
3578 Elem = (Elem >> 8) | 0x200;
3582 void addNEONi32vmovNegOperands(MCInst &Inst,
unsigned N)
const {
3583 assert(
N == 1 &&
"Invalid number of operands!");
3586 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3590 void addNEONvmovi32ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3591 assert(
N == 1 &&
"Invalid number of operands!");
3597 "All instructions that want to replicate non-zero word "
3598 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3599 uint64_t
Value =
CE->getValue();
3600 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3604 void addNEONi64splatOperands(MCInst &Inst,
unsigned N)
const {
3605 assert(
N == 1 &&
"Invalid number of operands!");
3608 uint64_t
Value =
CE->getValue();
3610 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3616 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
3617 assert(
N == 1 &&
"Invalid number of operands!");
3622 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
3623 assert(
N == 1 &&
"Invalid number of operands!");
3628 void addMveSaturateOperands(MCInst &Inst,
unsigned N)
const {
3629 assert(
N == 1 &&
"Invalid number of operands!");
3631 unsigned Imm =
CE->getValue();
3632 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3636 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
3638 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask, SMLoc S,
3639 ARMAsmParser &Parser) {
3640 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3647 static std::unique_ptr<ARMOperand>
3649 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3656 static std::unique_ptr<ARMOperand> CreateVPTPred(
ARMVCC::VPTCodes CC, SMLoc S,
3657 ARMAsmParser &Parser) {
3658 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3665 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal, SMLoc S,
3666 ARMAsmParser &Parser) {
3667 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3668 Op->Cop.Val = CopVal;
3674 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal, SMLoc S,
3675 ARMAsmParser &Parser) {
3676 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3677 Op->Cop.Val = CopVal;
3683 static std::unique_ptr<ARMOperand>
3684 CreateCoprocOption(
unsigned Val, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3685 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3692 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister
Reg, SMLoc S,
3693 ARMAsmParser &Parser) {
3694 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3695 Op->Reg.RegNum =
Reg;
3701 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3702 ARMAsmParser &Parser) {
3703 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3704 Op->Tok.Data = Str.data();
3705 Op->Tok.Length = Str.size();
3711 static std::unique_ptr<ARMOperand> CreateReg(MCRegister
Reg, SMLoc S, SMLoc
E,
3712 ARMAsmParser &Parser) {
3713 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3714 Op->Reg.RegNum =
Reg;
3720 static std::unique_ptr<ARMOperand>
3722 MCRegister ShiftReg,
unsigned ShiftImm, SMLoc S,
3723 SMLoc
E, ARMAsmParser &Parser) {
3724 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3725 Op->RegShiftedReg.ShiftTy = ShTy;
3726 Op->RegShiftedReg.SrcReg = SrcReg;
3727 Op->RegShiftedReg.ShiftReg = ShiftReg;
3728 Op->RegShiftedReg.ShiftImm = ShiftImm;
3734 static std::unique_ptr<ARMOperand>
3736 unsigned ShiftImm, SMLoc S, SMLoc
E,
3737 ARMAsmParser &Parser) {
3738 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3739 Op->RegShiftedImm.ShiftTy = ShTy;
3740 Op->RegShiftedImm.SrcReg = SrcReg;
3741 Op->RegShiftedImm.ShiftImm = ShiftImm;
3747 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3749 ARMAsmParser &Parser) {
3750 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3751 Op->ShifterImm.isASR = isASR;
3752 Op->ShifterImm.Imm =
Imm;
3758 static std::unique_ptr<ARMOperand>
3759 CreateRotImm(
unsigned Imm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3760 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3761 Op->RotImm.Imm =
Imm;
3767 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3769 ARMAsmParser &Parser) {
3770 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3772 Op->ModImm.Rot = Rot;
3778 static std::unique_ptr<ARMOperand>
3779 CreateConstantPoolImm(
const MCExpr *Val, SMLoc S, SMLoc
E,
3780 ARMAsmParser &Parser) {
3781 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3788 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3789 unsigned Width, SMLoc S,
3791 ARMAsmParser &Parser) {
3792 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3793 Op->Bitfield.LSB = LSB;
3794 Op->Bitfield.Width = Width;
3800 static std::unique_ptr<ARMOperand>
3801 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3802 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3803 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3804 KindTy Kind = k_RegisterList;
3806 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3808 if (Regs.back().second == ARM::VPR)
3809 Kind = k_FPDRegisterListWithVPR;
3811 Kind = k_DPRRegisterList;
3812 }
else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3814 if (Regs.back().second == ARM::VPR)
3815 Kind = k_FPSRegisterListWithVPR;
3817 Kind = k_SPRRegisterList;
3818 }
else if (Regs.front().second == ARM::VPR) {
3819 assert(Regs.size() == 1 &&
3820 "Register list starting with VPR expected to only contain VPR");
3821 Kind = k_FPSRegisterListWithVPR;
3824 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3825 Kind = k_RegisterListWithAPSR;
3829 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3830 for (
const auto &
P : Regs)
3831 Op->Registers.push_back(
P.second);
3833 Op->StartLoc = StartLoc;
3834 Op->EndLoc = EndLoc;
3838 static std::unique_ptr<ARMOperand>
3839 CreateVectorList(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced, SMLoc S,
3840 SMLoc
E, ARMAsmParser &Parser) {
3841 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3842 Op->VectorList.RegNum =
Reg;
3844 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3850 static std::unique_ptr<ARMOperand>
3851 CreateVectorListAllLanes(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced,
3852 SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3853 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3854 Op->VectorList.RegNum =
Reg;
3856 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3862 static std::unique_ptr<ARMOperand>
3863 CreateVectorListIndexed(MCRegister
Reg,
unsigned Count,
unsigned Index,
3864 bool isDoubleSpaced, SMLoc S, SMLoc
E,
3865 ARMAsmParser &Parser) {
3866 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3867 Op->VectorList.RegNum =
Reg;
3869 Op->VectorList.LaneIndex =
Index;
3870 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3876 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx, SMLoc S,
3877 SMLoc
E, MCContext &Ctx,
3878 ARMAsmParser &Parser) {
3879 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3880 Op->VectorIndex.Val = Idx;
3886 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val, SMLoc S,
3887 SMLoc
E, ARMAsmParser &Parser) {
3888 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3895 static std::unique_ptr<ARMOperand>
3896 CreateMem(MCRegister BaseReg,
const MCExpr *OffsetImm, MCRegister OffsetReg,
3898 bool isNegative, SMLoc S, SMLoc
E, ARMAsmParser &Parser,
3899 SMLoc AlignmentLoc = SMLoc()) {
3900 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3902 Op->Memory.OffsetImm = OffsetImm;
3903 Op->Memory.OffsetRegNum = OffsetReg;
3904 Op->Memory.ShiftType = ShiftType;
3905 Op->Memory.ShiftImm = ShiftImm;
3906 Op->Memory.Alignment = Alignment;
3907 Op->Memory.isNegative = isNegative;
3910 Op->AlignmentLoc = AlignmentLoc;
3914 static std::unique_ptr<ARMOperand>
3916 unsigned ShiftImm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3917 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3918 Op->PostIdxReg.RegNum =
Reg;
3919 Op->PostIdxReg.isAdd = isAdd;
3920 Op->PostIdxReg.ShiftTy = ShiftTy;
3921 Op->PostIdxReg.ShiftImm = ShiftImm;
3927 static std::unique_ptr<ARMOperand>
3928 CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3929 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3930 Op->MBOpt.Val = Opt;
3936 static std::unique_ptr<ARMOperand>
3938 ARMAsmParser &Parser) {
3939 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3940 Op->ISBOpt.Val = Opt;
3946 static std::unique_ptr<ARMOperand>
3948 ARMAsmParser &Parser) {
3949 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3950 Op->TSBOpt.Val = Opt;
3956 static std::unique_ptr<ARMOperand>
3958 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3965 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask, SMLoc S,
3966 ARMAsmParser &Parser) {
3967 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3968 Op->MMask.Val = MMask;
3974 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg, SMLoc S,
3975 ARMAsmParser &Parser) {
3976 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3977 Op->BankedReg.Val =
Reg;
3986void ARMOperand::print(raw_ostream &OS,
const MCAsmInfo &MAI)
const {
4004 case k_ITCondMask: {
4005 static const char *
const MaskStr[] = {
4006 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4007 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4008 "(t)",
"(tett)",
"(tet)",
"(tete)",
4009 "(te)",
"(teet)",
"(tee)",
"(teee)",
4011 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4012 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4016 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4019 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4021 case k_CoprocOption:
4022 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4025 OS <<
"<mask: " << getMSRMask() <<
">";
4028 OS <<
"<banked reg: " << getBankedReg() <<
">";
4033 case k_MemBarrierOpt:
4034 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4036 case k_InstSyncBarrierOpt:
4037 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4039 case k_TraceSyncBarrierOpt:
4040 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4044 if (Memory.BaseRegNum)
4045 OS <<
" base:" <<
RegName(Memory.BaseRegNum);
4046 if (Memory.OffsetImm) {
4047 OS <<
" offset-imm:";
4050 if (Memory.OffsetRegNum)
4051 OS <<
" offset-reg:" << (Memory.isNegative ?
"-" :
"")
4052 <<
RegName(Memory.OffsetRegNum);
4055 OS <<
" shift-imm:" << Memory.ShiftImm;
4057 if (Memory.Alignment)
4058 OS <<
" alignment:" << Memory.Alignment;
4061 case k_PostIndexRegister:
4062 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4063 <<
RegName(PostIdxReg.RegNum);
4066 << PostIdxReg.ShiftImm;
4069 case k_ProcIFlags: {
4070 OS <<
"<ARM_PROC::";
4071 unsigned IFlags = getProcIFlags();
4072 for (
int i=2; i >= 0; --i)
4073 if (IFlags & (1 << i))
4081 case k_ShifterImmediate:
4082 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4083 <<
" #" << ShifterImm.Imm <<
">";
4085 case k_ShiftedRegister:
4086 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4088 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4090 case k_ShiftedImmediate:
4091 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4093 << RegShiftedImm.ShiftImm <<
">";
4095 case k_RotateImmediate:
4096 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4098 case k_ModifiedImmediate:
4099 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4100 << ModImm.Rot <<
")>";
4102 case k_ConstantPoolImmediate:
4103 OS <<
"<constant_pool_imm #";
4104 MAI.
printExpr(OS, *getConstantPoolImm());
4106 case k_BitfieldDescriptor:
4107 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4108 <<
", width: " <<
Bitfield.Width <<
">";
4110 case k_RegisterList:
4111 case k_RegisterListWithAPSR:
4112 case k_DPRRegisterList:
4113 case k_SPRRegisterList:
4114 case k_FPSRegisterListWithVPR:
4115 case k_FPDRegisterListWithVPR: {
4116 OS <<
"<register_list ";
4118 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4119 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4121 if (++
I <
E) OS <<
", ";
4128 OS <<
"<vector_list " << VectorList.Count <<
" * "
4129 <<
RegName(VectorList.RegNum) <<
">";
4131 case k_VectorListAllLanes:
4132 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4133 <<
RegName(VectorList.RegNum) <<
">";
4135 case k_VectorListIndexed:
4136 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4137 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4143 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4157 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4158 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4159 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4164 unsigned MnemonicOpsEndInd = 1;
4167 if (Operands[0]->isToken() &&
4168 static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"cps") {
4169 if (Operands.
size() > 1 && Operands[1]->isImm() &&
4170 static_cast<ARMOperand &
>(*Operands[1]).getImm()->getKind() ==
4173 static_cast<ARMOperand &
>(*Operands[1]).getImm())
4176 static_cast<ARMOperand &
>(*Operands[1]).getImm())
4178 ++MnemonicOpsEndInd;
4182 bool RHSCondCode =
false;
4183 while (MnemonicOpsEndInd < Operands.
size()) {
4184 auto Op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
4186 if (
Op.isITMask()) {
4188 MnemonicOpsEndInd++;
4189 }
else if (
Op.isToken() &&
4193 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4194 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4200 MnemonicOpsEndInd++;
4203 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4204 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4205 MnemonicOpsEndInd++;
4209 return MnemonicOpsEndInd;
4212bool ARMAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4214 const AsmToken &Tok = getParser().getTok();
4217 Reg = tryParseRegister();
4222ParseStatus ARMAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4224 if (parseRegister(
Reg, StartLoc, EndLoc))
4232MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4233 MCAsmParser &Parser = getParser();
4234 const AsmToken &Tok = Parser.
getTok();
4236 return MCRegister();
4241 Reg = StringSwitch<MCRegister>(lowerCase)
4242 .Case(
"r13", ARM::SP)
4243 .Case(
"r14", ARM::LR)
4244 .Case(
"r15", ARM::PC)
4245 .Case(
"ip", ARM::R12)
4247 .Case(
"a1", ARM::R0)
4248 .Case(
"a2", ARM::R1)
4249 .Case(
"a3", ARM::R2)
4250 .Case(
"a4", ARM::R3)
4251 .Case(
"v1", ARM::R4)
4252 .Case(
"v2", ARM::R5)
4253 .Case(
"v3", ARM::R6)
4254 .Case(
"v4", ARM::R7)
4255 .Case(
"v5", ARM::R8)
4256 .Case(
"v6", ARM::R9)
4257 .Case(
"v7", ARM::R10)
4258 .Case(
"v8", ARM::R11)
4259 .Case(
"sb", ARM::R9)
4260 .Case(
"sl", ARM::R10)
4261 .Case(
"fp", ARM::R11)
4262 .Default(MCRegister());
4268 auto Entry = RegisterReqs.
find(lowerCase);
4270 if (Entry == RegisterReqs.
end())
4271 return MCRegister();
4273 return Entry->getValue();
4277 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4278 return MCRegister();
4285std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4286 MCAsmParser &Parser = getParser();
4287 const AsmToken &Tok = Parser.
getTok();
4289 return std::nullopt;
4292 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4299 .Default(std::nullopt);
4307int ARMAsmParser::tryParseShiftRegister(
OperandVector &Operands) {
4308 MCAsmParser &Parser = getParser();
4311 auto ShiftTyOpt = tryParseShiftToken();
4312 if (ShiftTyOpt == std::nullopt)
4314 auto ShiftTy = ShiftTyOpt.value();
4321 std::unique_ptr<ARMOperand> PrevOp(
4323 if (!PrevOp->isReg())
4324 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4325 MCRegister SrcReg = PrevOp->getReg();
4329 MCRegister ShiftReg;
4341 const MCExpr *ShiftExpr =
nullptr;
4342 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4343 Error(ImmLoc,
"invalid immediate shift value");
4349 Error(ImmLoc,
"invalid immediate shift value");
4355 Imm =
CE->getValue();
4359 Error(ImmLoc,
"immediate shift value out of range");
4369 ShiftReg = tryParseRegister();
4371 Error(L,
"expected immediate or register in shift operand");
4376 "expected immediate or register in shift operand");
4382 Operands.
push_back(ARMOperand::CreateShiftedRegister(
4383 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *
this));
4385 Operands.
push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4397bool ARMAsmParser::tryParseRegisterWithWriteBack(
OperandVector &Operands) {
4398 MCAsmParser &Parser = getParser();
4401 MCRegister
Reg = tryParseRegister();
4405 Operands.
push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4407 const AsmToken &ExclaimTok = Parser.
getTok();
4410 ExclaimTok.
getLoc(), *
this));
4422 const MCExpr *ImmVal;
4423 if (getParser().parseExpression(ImmVal))
4427 return TokError(
"immediate value expected for vector index");
4454 if (Name.size() < 2 || Name[0] != CoprocOp)
4456 Name = (Name[1] ==
'r') ? Name.drop_front(2) : Name.drop_front();
4458 switch (Name.size()) {
4481 case '0':
return 10;
4482 case '1':
return 11;
4483 case '2':
return 12;
4484 case '3':
return 13;
4485 case '4':
return 14;
4486 case '5':
return 15;
4492ParseStatus ARMAsmParser::parseITCondCode(
OperandVector &Operands) {
4493 MCAsmParser &Parser = getParser();
4495 const AsmToken &Tok = Parser.
getTok();
4512ParseStatus ARMAsmParser::parseCoprocNumOperand(
OperandVector &Operands) {
4513 MCAsmParser &Parser = getParser();
4515 const AsmToken &Tok = Parser.
getTok();
4526 Operands.
push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4533ParseStatus ARMAsmParser::parseCoprocRegOperand(
OperandVector &Operands) {
4534 MCAsmParser &Parser = getParser();
4536 const AsmToken &Tok = Parser.
getTok();
4545 Operands.
push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4551ParseStatus ARMAsmParser::parseCoprocOptionOperand(
OperandVector &Operands) {
4552 MCAsmParser &Parser = getParser();
4562 if (getParser().parseExpression(Expr))
4563 return Error(Loc,
"illegal expression");
4565 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4567 "coprocessor option must be an immediate in range [0, 255]");
4568 int Val =
CE->getValue();
4576 Operands.
push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4587 if (!getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4591 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4592 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4593 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4594 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4595 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4596 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4597 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4598 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4607 Regs.emplace_back(Enc,
Reg);
4608 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4609 if (J->first == Enc) {
4610 Regs.erase(J.base());
4621bool ARMAsmParser::parseRegisterList(
OperandVector &Operands,
bool EnforceOrder,
4622 bool AllowRAAC,
bool IsLazyLoadStore,
4624 MCAsmParser &Parser = getParser();
4626 return TokError(
"Token is not a Left Curly Brace");
4633 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4634 MCRegister
Reg = tryParseRegister(AllowOutOfBoundReg);
4636 return Error(RegLoc,
"register expected");
4637 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4638 return Error(RegLoc,
"pseudo-register not allowed");
4649 bool VSCCLRMAdjustEncoding =
false;
4652 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4653 Reg = getDRegFromQReg(
Reg);
4658 const MCRegisterClass *RC;
4659 if (
Reg == ARM::RA_AUTH_CODE ||
4660 getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4661 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4662 else if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg))
4663 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4664 else if (getARMMCRegisterClass(ARM::SPRRegClassID).
contains(
Reg))
4665 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4666 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg))
4667 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4668 else if (
Reg == ARM::VPR)
4669 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4671 return Error(RegLoc,
"invalid register in register list");
4683 if (
Reg == ARM::RA_AUTH_CODE)
4684 return Error(RegLoc,
"pseudo-register not allowed");
4687 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4689 return Error(AfterMinusLoc,
"register expected");
4690 if (EndReg == ARM::RA_AUTH_CODE)
4691 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4693 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4694 EndReg = getDRegFromQReg(EndReg) + 1;
4701 return Error(AfterMinusLoc,
"invalid register in register list");
4704 return Error(AfterMinusLoc,
"bad range in register list");
4707 while (
Reg != EndReg) {
4710 if (VSCCLRMAdjustEncoding)
4713 Warning(AfterMinusLoc, StringRef(
"duplicated register (") +
4715 ") in register list");
4722 MCRegister OldReg =
Reg;
4724 const AsmToken RegTok = Parser.
getTok();
4725 Reg = tryParseRegister(AllowOutOfBoundReg);
4727 return Error(RegLoc,
"register expected");
4728 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4729 return Error(RegLoc,
"pseudo-register not allowed");
4731 bool isQReg =
false;
4732 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4733 Reg = getDRegFromQReg(
Reg);
4737 RC->
getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4738 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg)) {
4741 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4743 if (
Reg == ARM::VPR &&
4744 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4746 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4747 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4751 ") in register list");
4757 if (IsVSCCLRM && OldReg == ARM::S31 &&
Reg ==
ARM::D16) {
4758 VSCCLRMAdjustEncoding =
true;
4759 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4762 if ((
Reg == ARM::RA_AUTH_CODE &&
4763 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4765 return Error(RegLoc,
"invalid register in register list");
4771 if (VSCCLRMAdjustEncoding)
4773 if (EnforceOrder && EReg < EOldReg) {
4774 if (getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4775 Warning(RegLoc,
"register list not in ascending order");
4776 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4778 return Error(RegLoc,
"register list not in ascending order");
4781 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4782 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4783 EReg != EOldReg + 1)
4784 return Error(RegLoc,
"non-contiguous register range");
4788 ") in register list");
4808 ARMOperand::CreateToken(
"^", Parser.
getTok().
getLoc(), *
this));
4816ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4817 unsigned &Index, SMLoc &EndLoc) {
4818 MCAsmParser &Parser = getParser();
4824 LaneKind = AllLanes;
4835 const MCExpr *LaneIndex;
4837 if (getParser().parseExpression(LaneIndex))
4838 return Error(Loc,
"illegal expression");
4841 return Error(Loc,
"lane index must be empty or an integer");
4846 int64_t Val =
CE->getValue();
4849 if (Val < 0 || Val > 7)
4852 LaneKind = IndexedLane;
4860ParseStatus ARMAsmParser::parseVectorList(
OperandVector &Operands) {
4861 MCAsmParser &Parser = getParser();
4862 VectorLaneTy LaneKind;
4872 MCRegister
Reg = tryParseRegister();
4875 if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg)) {
4876 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4881 Operands.
push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4885 ARMOperand::CreateVectorListAllLanes(
Reg, 1,
false, S,
E, *
this));
4888 Operands.
push_back(ARMOperand::CreateVectorListIndexed(
4889 Reg, 1, LaneIndex,
false, S,
E, *
this));
4894 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4895 Reg = getDRegFromQReg(
Reg);
4896 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4901 Operands.
push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4905 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4907 ARMOperand::CreateVectorListAllLanes(
Reg, 2,
false, S,
E, *
this));
4910 Operands.
push_back(ARMOperand::CreateVectorListIndexed(
4911 Reg, 2, LaneIndex,
false, S,
E, *
this));
4916 Operands.
push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4926 MCRegister
Reg = tryParseRegister();
4928 return Error(RegLoc,
"register expected");
4931 MCRegister FirstReg =
Reg;
4933 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
4935 "vector register in range Q0-Q7 expected");
4938 else if (!hasMVE() &&
4939 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4940 FirstReg =
Reg = getDRegFromQReg(
Reg);
4948 if (!parseVectorLane(LaneKind, LaneIndex,
E).isSuccess())
4956 else if (Spacing == 2)
4958 "sequential registers in double spaced list");
4961 MCRegister EndReg = tryParseRegister();
4963 return Error(AfterMinusLoc,
"register expected");
4966 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4967 EndReg = getDRegFromQReg(EndReg) + 1;
4974 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(EndReg)) ||
4976 !getARMMCRegisterClass(ARM::DPRRegClassID).
contains(EndReg)))
4977 return Error(AfterMinusLoc,
"invalid register in register list");
4980 return Error(AfterMinusLoc,
"bad range in register list");
4982 VectorLaneTy NextLaneKind;
4983 unsigned NextLaneIndex;
4984 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
4986 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4987 return Error(AfterMinusLoc,
"mismatched lane index in register list");
4996 MCRegister OldReg =
Reg;
4997 Reg = tryParseRegister();
4999 return Error(RegLoc,
"register expected");
5002 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
5003 return Error(RegLoc,
"vector register in range Q0-Q7 expected");
5012 else if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
5015 else if (Spacing == 2)
5018 "invalid register in double-spaced list (must be 'D' register')");
5019 Reg = getDRegFromQReg(
Reg);
5020 if (
Reg != OldReg + 1)
5021 return Error(RegLoc,
"non-contiguous register range");
5025 VectorLaneTy NextLaneKind;
5026 unsigned NextLaneIndex;
5028 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5030 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5031 return Error(LaneLoc,
"mismatched lane index in register list");
5038 Spacing = 1 + (
Reg == OldReg + 2);
5041 if (
Reg != OldReg + Spacing)
5042 return Error(RegLoc,
"non-contiguous register range");
5045 VectorLaneTy NextLaneKind;
5046 unsigned NextLaneIndex;
5048 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5050 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5051 return Error(EndLoc,
"mismatched lane index in register list");
5064 if (
Count == 2 && !hasMVE()) {
5065 const MCRegisterClass *RC =
5066 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5067 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5070 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5071 ARMOperand::CreateVectorListAllLanes);
5072 Operands.
push_back(Create(FirstReg,
Count, (Spacing == 2), S,
E, *
this));
5076 Operands.
push_back(ARMOperand::CreateVectorListIndexed(
5077 FirstReg,
Count, LaneIndex, (Spacing == 2), S,
E, *
this));
5084ParseStatus ARMAsmParser::parseMemBarrierOptOperand(
OperandVector &Operands) {
5085 MCAsmParser &Parser = getParser();
5087 const AsmToken &Tok = Parser.
getTok();
5093 Opt = StringSwitch<unsigned>(OptStr.
lower())
5128 const MCExpr *MemBarrierID;
5129 if (getParser().parseExpression(MemBarrierID))
5130 return Error(Loc,
"illegal expression");
5134 return Error(Loc,
"constant expression expected");
5136 int Val =
CE->getValue();
5138 return Error(Loc,
"immediate value out of range");
5143 "expected an immediate or barrier type");
5151ARMAsmParser::parseTraceSyncBarrierOptOperand(
OperandVector &Operands) {
5152 MCAsmParser &Parser = getParser();
5154 const AsmToken &Tok = Parser.
getTok();
5165 ARMOperand::CreateTraceSyncBarrierOpt(
ARM_TSB::CSYNC, S, *
this));
5171ARMAsmParser::parseInstSyncBarrierOptOperand(
OperandVector &Operands) {
5172 MCAsmParser &Parser = getParser();
5174 const AsmToken &Tok = Parser.
getTok();
5193 const MCExpr *ISBarrierID;
5194 if (getParser().parseExpression(ISBarrierID))
5195 return Error(Loc,
"illegal expression");
5199 return Error(Loc,
"constant expression expected");
5201 int Val =
CE->getValue();
5203 return Error(Loc,
"immediate value out of range");
5208 "expected an immediate or barrier type");
5210 Operands.
push_back(ARMOperand::CreateInstSyncBarrierOpt(
5216ParseStatus ARMAsmParser::parseProcIFlagsOperand(
OperandVector &Operands) {
5217 MCAsmParser &Parser = getParser();
5219 const AsmToken &Tok = Parser.
getTok();
5227 if (IFlagsStr !=
"none") {
5228 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
5229 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.
substr(i, 1).
lower())
5237 if (Flag == ~0U || (IFlags & Flag))
5251ParseStatus ARMAsmParser::parseMSRMaskOperand(
OperandVector &Operands) {
5253 if (
static_cast<ARMOperand &
>(*Operands.
back()).isMSRMask() ||
5254 static_cast<ARMOperand &
>(*Operands.
back()).isBankedReg())
5256 MCAsmParser &Parser = getParser();
5258 const AsmToken &Tok = Parser.
getTok();
5262 if (Val > 255 || Val < 0) {
5265 unsigned SYSmvalue = Val & 0xFF;
5267 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5276 auto TheReg = ARMSysReg::lookupMClassSysRegByName(
Mask.lower());
5277 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5280 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5283 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5289 StringRef
Flags =
"";
5290 std::string SpecReg =
Mask.slice(Start,
Next).lower();
5297 unsigned FlagsVal = 0;
5299 if (SpecReg ==
"apsr") {
5300 FlagsVal = StringSwitch<unsigned>(Flags)
5303 .Case(
"nzcvqg", 0xc)
5306 if (FlagsVal == ~0U) {
5312 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
5314 if (Flags ==
"all" || Flags ==
"")
5316 for (
int i = 0, e =
Flags.size(); i != e; ++i) {
5317 unsigned Flag = StringSwitch<unsigned>(
Flags.substr(i, 1))
5326 if (Flag == ~0U || (FlagsVal & Flag))
5342 if (SpecReg ==
"spsr")
5346 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *
this));
5352ParseStatus ARMAsmParser::parseBankedRegOperand(
OperandVector &Operands) {
5354 if (
static_cast<ARMOperand &
>(*Operands.
back()).isBankedReg() ||
5355 static_cast<ARMOperand &
>(*Operands.
back()).isMSRMask())
5357 MCAsmParser &Parser = getParser();
5359 const AsmToken &Tok = Parser.
getTok();
5364 auto TheReg = ARMBankedReg::lookupBankedRegByName(
RegName.lower());
5367 unsigned Encoding = TheReg->Encoding;
5370 Operands.
push_back(ARMOperand::CreateBankedReg(Encoding, S, *
this));
5377ParseStatus ARMAsmParser::parsePKHImm(
OperandVector &Operands,
5379 MCAsmParser &Parser = getParser();
5380 auto ShiftCodeOpt = tryParseShiftToken();
5382 if (!ShiftCodeOpt.has_value())
5384 auto ShiftCode = ShiftCodeOpt.value();
5388 if (ShiftCode !=
Op)
5400 const MCExpr *ShiftAmount;
5403 if (getParser().parseExpression(ShiftAmount, EndLoc))
5404 return Error(Loc,
"illegal expression");
5407 return Error(Loc,
"constant expression expected");
5408 int Val =
CE->getValue();
5409 if (Val < Low || Val >
High)
5410 return Error(Loc,
"immediate value out of range");
5412 Operands.
push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *
this));
5417ParseStatus ARMAsmParser::parseSetEndImm(
OperandVector &Operands) {
5418 MCAsmParser &Parser = getParser();
5419 const AsmToken &Tok = Parser.
getTok();
5422 return Error(S,
"'be' or 'le' operand expected");
5430 return Error(S,
"'be' or 'le' operand expected");
5431 Operands.
push_back(ARMOperand::CreateImm(
5441ParseStatus ARMAsmParser::parseShifterImm(
OperandVector &Operands) {
5442 MCAsmParser &Parser = getParser();
5443 const AsmToken &Tok = Parser.
getTok();
5449 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
5451 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5464 const MCExpr *ShiftAmount;
5466 if (getParser().parseExpression(ShiftAmount, EndLoc))
5467 return Error(ExLoc,
"malformed shift expression");
5470 return Error(ExLoc,
"shift amount must be an immediate");
5472 int64_t Val =
CE->getValue();
5475 if (Val < 1 || Val > 32)
5476 return Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
5479 return Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
5480 if (Val == 32) Val = 0;
5483 if (Val < 0 || Val > 31)
5484 return Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
5488 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *
this));
5496ParseStatus ARMAsmParser::parseRotImm(
OperandVector &Operands) {
5497 MCAsmParser &Parser = getParser();
5498 const AsmToken &Tok = Parser.
getTok();
5503 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
5514 const MCExpr *ShiftAmount;
5516 if (getParser().parseExpression(ShiftAmount, EndLoc))
5517 return Error(ExLoc,
"malformed rotate expression");
5520 return Error(ExLoc,
"rotate amount must be an immediate");
5522 int64_t Val =
CE->getValue();
5526 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5527 return Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
5529 Operands.
push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *
this));
5534ParseStatus ARMAsmParser::parseModImm(
OperandVector &Operands) {
5535 MCAsmParser &Parser = getParser();
5536 AsmLexer &Lexer = getLexer();
5567 const MCExpr *Imm1Exp;
5568 if (getParser().parseExpression(Imm1Exp, Ex1))
5569 return Error(Sx1,
"malformed expression");
5575 Imm1 =
CE->getValue();
5579 Operands.
push_back(ARMOperand::CreateModImm(
5580 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *
this));
5591 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5597 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5604 "expected modified immediate operand: #[0, 255], #even[0-30]");
5607 return Error(Sx1,
"immediate operand must a number in the range [0, 255]");
5621 const MCExpr *Imm2Exp;
5622 if (getParser().parseExpression(Imm2Exp, Ex2))
5623 return Error(Sx2,
"malformed expression");
5628 Imm2 =
CE->getValue();
5629 if (!(Imm2 & ~0x1E)) {
5631 Operands.
push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *
this));
5635 "immediate operand must an even number in the range [0, 30]");
5637 return Error(Sx2,
"constant expression expected");
5641ParseStatus ARMAsmParser::parseBitfield(
OperandVector &Operands) {
5642 MCAsmParser &Parser = getParser();
5650 const MCExpr *LSBExpr;
5652 if (getParser().parseExpression(LSBExpr))
5653 return Error(
E,
"malformed immediate expression");
5656 return Error(
E,
"'lsb' operand must be an immediate");
5658 int64_t LSB =
CE->getValue();
5660 if (LSB < 0 || LSB > 31)
5661 return Error(
E,
"'lsb' operand must be in the range [0,31]");
5673 const MCExpr *WidthExpr;
5675 if (getParser().parseExpression(WidthExpr, EndLoc))
5676 return Error(
E,
"malformed immediate expression");
5679 return Error(
E,
"'width' operand must be an immediate");
5681 int64_t Width =
CE->getValue();
5683 if (Width < 1 || Width > 32 - LSB)
5684 return Error(
E,
"'width' operand must be in the range [1,32-lsb]");
5686 Operands.
push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *
this));
5691ParseStatus ARMAsmParser::parsePostIdxReg(
OperandVector &Operands) {
5700 MCAsmParser &Parser = getParser();
5701 AsmToken Tok = Parser.
getTok();
5703 bool haveEaten =
false;
5715 MCRegister
Reg = tryParseRegister();
5723 unsigned ShiftImm = 0;
5726 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5734 ARMOperand::CreatePostIdxReg(
Reg, isAdd, ShiftTy, ShiftImm, S,
E, *
this));
5739ParseStatus ARMAsmParser::parseAM3Offset(
OperandVector &Operands) {
5751 MCAsmParser &Parser = getParser();
5752 AsmToken Tok = Parser.
getTok();
5764 if (getParser().parseExpression(
Offset,
E))
5768 return Error(S,
"constant expression expected");
5771 int32_t Val =
CE->getValue();
5772 if (isNegative && Val == 0)
5773 Val = std::numeric_limits<int32_t>::min();
5775 Operands.
push_back(ARMOperand::CreateImm(
5781 bool haveEaten =
false;
5793 MCRegister
Reg = tryParseRegister();
5800 Operands.
push_back(ARMOperand::CreatePostIdxReg(
5808 unsigned MnemonicOpsEndInd) {
5809 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5810 auto Op =
static_cast<ARMOperand &
>(*Operands[
I]);
5811 if (
Op.isCondCode())
5818 unsigned MnemonicOpsEndInd) {
5819 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5820 auto Op =
static_cast<ARMOperand &
>(*Operands[
I]);
5830void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5834 unsigned CondOutI =
findCCOutInd(Operands, MnemonicOpsEndInd);
5837 unsigned RegRd = MnemonicOpsEndInd;
5838 unsigned RegRn = MnemonicOpsEndInd + 1;
5839 unsigned RegRm = MnemonicOpsEndInd;
5841 if (Operands.
size() == MnemonicOpsEndInd + 3) {
5844 if (((ARMOperand &)*Operands[RegRd]).
getReg() ==
5845 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).
getReg()) {
5846 RegRn = MnemonicOpsEndInd + 2;
5847 RegRm = MnemonicOpsEndInd + 1;
5849 RegRn = MnemonicOpsEndInd + 1;
5850 RegRm = MnemonicOpsEndInd + 2;
5855 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5857 if (CondOutI != 0) {
5858 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5861 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *
this);
5862 Op.addCCOutOperands(Inst, 1);
5865 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5867 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5871 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5873 ARMOperand
Op = *ARMOperand::CreateCondCode(
5875 Op.addCondCodeOperands(Inst, 2);
5879void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5885 :
static_cast<ARMOperand &
>(*Operands[CondI]).getCondCode());
5893 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5894 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5913 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
5914 if (!
op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5920 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
5921 if (!
op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5926 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5928 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5930 ARMOperand
Op = *ARMOperand::CreateCondCode(
5932 Op.addCondCodeOperands(Inst, 2);
5936void ARMAsmParser::cvtMVEVMOVQtoDReg(
5943 assert(Operands.
size() == MnemonicOpsEndInd + 6);
5945 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1);
5946 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5947 .addRegOperands(Inst, 1);
5948 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5949 .addRegOperands(Inst, 1);
5950 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5951 .addMVEPairVectorIndexOperands(Inst, 1);
5953 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5954 .addMVEPairVectorIndexOperands(Inst, 1);
5956 ((ARMOperand &)*Operands[CondI])
5957 .addCondCodeOperands(Inst, 2);
5960 *ARMOperand::CreateCondCode(
ARMCC::AL, Operands[0]->getEndLoc(), *
this);
5961 Op.addCondCodeOperands(Inst, 2);
5968 MCAsmParser &Parser = getParser();
5971 return TokError(
"Token is not a Left Bracket");
5975 const AsmToken &BaseRegTok = Parser.
getTok();
5976 MCRegister
BaseReg = tryParseRegister();
5978 return Error(BaseRegTok.
getLoc(),
"register expected");
5981 const AsmToken &Tok = Parser.
getTok();
5984 return Error(Tok.
getLoc(),
"malformed memory operand");
5990 Operands.
push_back(ARMOperand::CreateMem(
5997 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6005 "Lost colon or comma in memory operand?!");
6014 SMLoc AlignmentLoc = Tok.
getLoc();
6017 if (getParser().parseExpression(Expr))
6025 return Error (
E,
"constant expression expected");
6028 switch (
CE->getValue()) {
6031 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6032 case 16:
Align = 2;
break;
6033 case 32:
Align = 4;
break;
6034 case 64:
Align = 8;
break;
6035 case 128:
Align = 16;
break;
6036 case 256:
Align = 32;
break;
6047 Operands.
push_back(ARMOperand::CreateMem(BaseReg,
nullptr, 0,
6049 S,
E, *
this, AlignmentLoc));
6055 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6075 const MCExpr *
Offset, *AdjustedOffset;
6076 if (getParser().parseExpression(
Offset))
6082 int32_t Val =
CE->getValue();
6083 if (isNegative && Val == 0)
6088 AdjustedOffset =
CE;
6091 Operands.
push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6105 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6113 bool isNegative =
false;
6123 MCRegister OffsetReg = tryParseRegister();
6125 return Error(
E,
"register expected");
6129 unsigned ShiftImm = 0;
6132 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6142 Operands.
push_back(ARMOperand::CreateMem(BaseReg,
nullptr, OffsetReg,
6143 ShiftType, ShiftImm, 0, isNegative,
6150 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6163 MCAsmParser &Parser = getParser();
6165 const AsmToken &Tok = Parser.
getTok();
6167 return Error(Loc,
"illegal shift operator");
6169 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
6170 ShiftName ==
"asl" || ShiftName ==
"ASL")
6172 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
6174 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
6176 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
6178 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
6180 else if (ShiftName ==
"uxtw" || ShiftName ==
"UXTW")
6183 return Error(Loc,
"illegal shift operator");
6191 const AsmToken &HashTok = Parser.
getTok();
6198 if (getParser().parseExpression(Expr))
6205 return Error(Loc,
"shift amount must be an immediate");
6206 int64_t
Imm =
CE->getValue();
6210 return Error(Loc,
"immediate shift value out of range");
6224ParseStatus ARMAsmParser::parseFPImm(
OperandVector &Operands) {
6227 MCAsmParser &Parser = getParser();
6254 bool isVmovf =
false;
6256 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
6257 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*Operands[
I]);
6258 if (TyOp.isToken() &&
6259 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
6260 TyOp.getToken() ==
".f16")) {
6266 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*Operands[0]);
6267 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
6268 Mnemonic.getToken() ==
"fconsts");
6269 if (!(isVmovf || isFconst))
6275 bool isNegative =
false;
6280 const AsmToken &Tok = Parser.
getTok();
6281 SMLoc Loc = Tok.
getLoc();
6284 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
6286 IntVal ^= (uint64_t)isNegative << 31;
6298 if (Val > 255 || Val < 0)
6299 return Error(Loc,
"encoded floating point value out of range");
6301 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
6309 return Error(Loc,
"invalid floating point immediate");
6314bool ARMAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6315 MCAsmParser &Parser = getParser();
6320 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6329 switch (getLexer().getKind()) {
6337 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
6339 if (!tryParseRegisterWithWriteBack(Operands))
6341 int Res = tryParseShiftRegister(Operands);
6347 if (Mnemonic ==
"vmrs" &&
6351 Operands.
push_back(ARMOperand::CreateToken(
"APSR_nzcv", S, *
this));
6366 const MCExpr *IdVal;
6368 if (getParser().parseExpression(IdVal))
6371 Operands.
push_back(ARMOperand::CreateImm(IdVal, S,
E, *
this));
6375 return parseMemory(Operands);
6377 bool IsLazyLoadStore = Mnemonic ==
"vlldm" || Mnemonic ==
"vlstm";
6378 bool IsVSCCLRM = Mnemonic ==
"vscclrm";
6379 return parseRegisterList(Operands, !Mnemonic.
starts_with(
"clr"),
false,
6380 IsLazyLoadStore, IsVSCCLRM);
6393 auto AdjacentToken = getLexer().peekTok(
false);
6397 if (!ExpectIdentifier) {
6405 const MCExpr *ImmVal;
6406 if (getParser().parseExpression(ImmVal))
6410 int32_t Val =
CE->getValue();
6411 if (IsNegative && Val == 0)
6416 Operands.
push_back(ARMOperand::CreateImm(ImmVal, S,
E, *
this));
6422 Operands.
push_back(ARMOperand::CreateToken(
6438 if (parsePrefix(Spec))
6441 const MCExpr *SubExprVal;
6442 if (getParser().parseExpression(SubExprVal))
6445 const auto *ExprVal =
6448 Operands.
push_back(ARMOperand::CreateImm(ExprVal, S,
E, *
this));
6453 if (Mnemonic !=
"ldr")
6454 return Error(S,
"unexpected token in operand");
6456 const MCExpr *SubExprVal;
6457 if (getParser().parseExpression(SubExprVal))
6464 ARMOperand::CreateConstantPoolImm(SubExprVal, S,
E, *
this));
6470bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6471 const MCExpr *Expr =
nullptr;
6472 SMLoc
L = getParser().getTok().getLoc();
6473 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
6476 if (check(!
Value, L,
"expected constant expression"))
6478 Out =
Value->getValue();
6486 MCAsmParser &Parser = getParser();
6507 static const struct PrefixEntry {
6508 const char *Spelling;
6510 uint8_t SupportedFormats;
6511 } PrefixEntries[] = {
6523 llvm::find_if(PrefixEntries, [&IDVal](
const PrefixEntry &PE) {
6524 return PE.Spelling == IDVal;
6526 if (Prefix == std::end(PrefixEntries)) {
6531 uint8_t CurrentFormat;
6534 CurrentFormat = MACHO;
6537 CurrentFormat =
ELF;
6540 CurrentFormat =
COFF;
6543 CurrentFormat = WASM;
6553 if (~
Prefix->SupportedFormats & CurrentFormat) {
6555 "cannot represent relocation in the current file format");
6579StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6583 unsigned &ProcessorIMod,
6584 StringRef &ITMask) {
6587 CarrySetting =
false;
6593 if ((Mnemonic ==
"movs" &&
isThumb()) || Mnemonic ==
"teq" ||
6594 Mnemonic ==
"vceq" || Mnemonic ==
"svc" || Mnemonic ==
"mls" ||
6595 Mnemonic ==
"smmls" || Mnemonic ==
"vcls" || Mnemonic ==
"vmls" ||
6596 Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" || Mnemonic ==
"vcge" ||
6597 Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" || Mnemonic ==
"vaclt" ||
6598 Mnemonic ==
"vacle" || Mnemonic ==
"hlt" || Mnemonic ==
"vcgt" ||
6599 Mnemonic ==
"vcle" || Mnemonic ==
"smlal" || Mnemonic ==
"umaal" ||
6600 Mnemonic ==
"umlal" || Mnemonic ==
"vabal" || Mnemonic ==
"vmlal" ||
6601 Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" || Mnemonic ==
"fmuls" ||
6602 Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" ||
6603 Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" ||
6604 Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" ||
6605 Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
6606 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vins" ||
6607 Mnemonic ==
"vmovx" || Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
6608 Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" || Mnemonic ==
"vudot" ||
6609 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6610 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"wls" ||
6611 Mnemonic ==
"le" || Mnemonic ==
"dls" || Mnemonic ==
"csel" ||
6612 Mnemonic ==
"csinc" || Mnemonic ==
"csinv" || Mnemonic ==
"csneg" ||
6613 Mnemonic ==
"cinc" || Mnemonic ==
"cinv" || Mnemonic ==
"cneg" ||
6614 Mnemonic ==
"cset" || Mnemonic ==
"csetm" || Mnemonic ==
"aut" ||
6615 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"bti")
6620 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
6621 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
6622 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
6623 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs" &&
6625 (Mnemonic ==
"vmine" || Mnemonic ==
"vshle" || Mnemonic ==
"vshlt" ||
6626 Mnemonic ==
"vshllt" || Mnemonic ==
"vrshle" || Mnemonic ==
"vrshlt" ||
6627 Mnemonic ==
"vmvne" || Mnemonic ==
"vorne" || Mnemonic ==
"vnege" ||
6628 Mnemonic ==
"vnegt" || Mnemonic ==
"vmule" || Mnemonic ==
"vmult" ||
6629 Mnemonic ==
"vrintne" || Mnemonic ==
"vcmult" ||
6630 Mnemonic ==
"vcmule" || Mnemonic ==
"vpsele" || Mnemonic ==
"vpselt" ||
6634 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
6642 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" || Mnemonic ==
"mrs" ||
6643 Mnemonic ==
"smmls" || Mnemonic ==
"vabs" || Mnemonic ==
"vcls" ||
6644 Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" || Mnemonic ==
"vnmls" ||
6645 Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" || Mnemonic ==
"vrsqrts" ||
6646 Mnemonic ==
"srs" || Mnemonic ==
"flds" || Mnemonic ==
"fmrs" ||
6647 Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" || Mnemonic ==
"fsts" ||
6648 Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" || Mnemonic ==
"fmuls" ||
6649 Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" || Mnemonic ==
"vfms" ||
6650 Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" || Mnemonic ==
"bxns" ||
6651 Mnemonic ==
"blxns" || Mnemonic ==
"vfmas" || Mnemonic ==
"vmlas" ||
6652 (Mnemonic ==
"movs" &&
isThumb()))) {
6653 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
6654 CarrySetting =
true;
6662 StringSwitch<unsigned>(Mnemonic.
substr(Mnemonic.
size()-2, 2))
6667 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
6668 ProcessorIMod =
IMod;
6672 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic !=
"vmovlt" &&
6673 Mnemonic !=
"vshllt" && Mnemonic !=
"vrshrnt" && Mnemonic !=
"vshrnt" &&
6674 Mnemonic !=
"vqrshrunt" && Mnemonic !=
"vqshrunt" &&
6675 Mnemonic !=
"vqrshrnt" && Mnemonic !=
"vqshrnt" && Mnemonic !=
"vmullt" &&
6676 Mnemonic !=
"vqmovnt" && Mnemonic !=
"vqmovunt" && Mnemonic !=
"vmovnt" &&
6677 Mnemonic !=
"vqdmullt" && Mnemonic !=
"vpnot" && Mnemonic !=
"vcvtt" &&
6678 Mnemonic !=
"vcvt") {
6682 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-1);
6690 ITMask = Mnemonic.
substr(2);
6691 Mnemonic = Mnemonic.
slice(0, 2);
6695 ITMask = Mnemonic.
substr(4);
6696 Mnemonic = Mnemonic.
slice(0, 4);
6698 ITMask = Mnemonic.
substr(3);
6699 Mnemonic = Mnemonic.
slice(0, 3);
6709void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6710 StringRef ExtraToken,
6712 bool &CanAcceptCarrySet,
6713 bool &CanAcceptPredicationCode,
6714 bool &CanAcceptVPTPredicationCode) {
6715 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6718 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6719 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
6720 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
6721 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
6722 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
6723 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
6724 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
6726 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
6727 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
6729 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
6730 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
6731 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
6733 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vmaxnm" ||
6734 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
6735 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
6736 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
6737 Mnemonic.
starts_with(
"aes") || Mnemonic ==
"hvc" ||
6738 Mnemonic ==
"setpan" || Mnemonic.
starts_with(
"sha1") ||
6741 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" || Mnemonic ==
"vudot" ||
6742 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6743 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"vfmat" ||
6744 Mnemonic ==
"vfmab" || Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" ||
6745 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" || Mnemonic ==
"pssbb" ||
6746 Mnemonic ==
"vsmmla" || Mnemonic ==
"vummla" || Mnemonic ==
"vusmmla" ||
6747 Mnemonic ==
"vusdot" || Mnemonic ==
"vsudot" || Mnemonic ==
"bfcsel" ||
6748 Mnemonic ==
"wls" || Mnemonic ==
"dls" || Mnemonic ==
"le" ||
6749 Mnemonic ==
"csel" || Mnemonic ==
"csinc" || Mnemonic ==
"csinv" ||
6750 Mnemonic ==
"csneg" || Mnemonic ==
"cinc" || Mnemonic ==
"cinv" ||
6751 Mnemonic ==
"cneg" || Mnemonic ==
"cset" || Mnemonic ==
"csetm" ||
6752 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6753 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6755 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"aut" ||
6756 Mnemonic ==
"bti" ||
6763 CanAcceptPredicationCode =
false;
6766 CanAcceptPredicationCode =
6767 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
6768 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
6769 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
6770 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
6771 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
6772 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" && Mnemonic !=
"tsb" &&
6774 }
else if (isThumbOne()) {
6776 CanAcceptPredicationCode = Mnemonic !=
"movs";
6778 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
6780 CanAcceptPredicationCode =
true;
6784 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I) {
6785 auto &
Op =
static_cast<ARMOperand &
>(*Operands[
I]);
6786 if (
Op.isToken() &&
Op.getToken() ==
".w")
6796void ARMAsmParser::tryConvertingToTwoOperandForm(
6802 if (Operands.
size() != MnemonicOpsEndInd + 3)
6805 const auto &Op3 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
6806 auto &Op4 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
6807 if (!Op3.isReg() || !Op4.isReg())
6810 auto Op3Reg = Op3.getReg();
6811 auto Op4Reg = Op4.getReg();
6817 auto &Op5 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 2]);
6819 if (Mnemonic !=
"add")
6821 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6822 (Op5.isReg() && Op5.getReg() == ARM::PC);
6823 if (!TryTransform) {
6824 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6825 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6826 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6827 Op5.isImm() && !Op5.isImm0_508s4());
6831 }
else if (!isThumbOne())
6834 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
6835 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6836 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
6837 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
6843 bool Transform = Op3Reg == Op4Reg;
6848 const ARMOperand *LastOp = &Op5;
6850 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6851 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
6852 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
6853 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
6864 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
6870 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
6877 Operands.
erase(Operands.
begin() + MnemonicOpsEndInd);
6886 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
6896bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6897 StringRef Mnemonic,
OperandVector &Operands,
unsigned MnemonicOpsEndInd) {
6898 if (!hasMVE() || Operands.
size() <= MnemonicOpsEndInd)
6911 for (
auto &Operand : Operands) {
6912 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6913 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6915 getARMMCRegisterClass(ARM::DPRRegClassID)
6916 .
contains((*Operand).getReg())))) {
6922 for (
auto &Operand : Operands) {
6926 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6927 static_cast<ARMOperand &
>(*Operand).isQReg())
6943 unsigned VariantID);
6954void ARMAsmParser::fixupGNULDRDAlias(
StringRef Mnemonic,
6956 unsigned MnemonicOpsEndInd) {
6957 if (Mnemonic !=
"ldrd" && Mnemonic !=
"strd" && Mnemonic !=
"ldrexd" &&
6958 Mnemonic !=
"strexd" && Mnemonic !=
"ldaexd" && Mnemonic !=
"stlexd")
6961 unsigned IdX = Mnemonic ==
"strexd" || Mnemonic ==
"stlexd"
6962 ? MnemonicOpsEndInd + 1
6963 : MnemonicOpsEndInd;
6965 if (Operands.
size() < IdX + 2)
6968 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[IdX]);
6969 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*Operands[IdX + 1]);
6973 if (!Op3.isGPRMem())
6981 if (!
isThumb() && (RtEncoding & 1)) {
6986 if (Op2.getReg() == ARM::PC)
6988 MCRegister PairedReg = GPR.
getRegister(RtEncoding + 1);
6989 if (!PairedReg || PairedReg == ARM::PC ||
6990 (PairedReg == ARM::SP && !hasV8Ops()))
6994 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6995 Op2.getEndLoc(), *
this));
7003bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7005 unsigned MnemonicOpsEndInd) {
7006 assert(MS.isCDEDualRegInstr(Mnemonic));
7008 if (Operands.
size() < 3 + MnemonicOpsEndInd)
7012 "operand must be an even-numbered register in the range [r0, r10]");
7014 const MCParsedAsmOperand &Op2 = *Operands[MnemonicOpsEndInd + 1];
7045 RPair = ARM::R10_R11;
7049 const MCParsedAsmOperand &Op3 = *Operands[MnemonicOpsEndInd + 2];
7053 Operands.
erase(Operands.
begin() + MnemonicOpsEndInd + 2);
7054 Operands[MnemonicOpsEndInd + 1] =
7060 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7061 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCondCode()) {
7063 --MnemonicOpsEndInd;
7069 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7070 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCCOut()) {
7072 --MnemonicOpsEndInd;
7078 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7079 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred()) {
7081 --MnemonicOpsEndInd;
7087bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7089 MCAsmParser &Parser = getParser();
7096 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7097 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7103 parseDirectiveReq(Name, NameLoc);
7111 StringRef Mnemonic =
Name.slice(Start,
Next);
7117 unsigned ProcessorIMod;
7120 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7121 CarrySetting, ProcessorIMod, ITMask);
7124 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
7125 return Error(NameLoc,
"conditional execution not supported in Thumb1");
7128 Operands.
push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7141 if (Mnemonic ==
"it" || Mnemonic.
starts_with(
"vpt") ||
7144 Mnemonic ==
"vpt" ? SMLoc::getFromPointer(NameLoc.
getPointer() + 3) :
7145 SMLoc::getFromPointer(NameLoc.
getPointer() + 4);
7146 if (ITMask.
size() > 3) {
7147 if (Mnemonic ==
"it")
7148 return Error(Loc,
"too many conditions on IT instruction");
7149 return Error(Loc,
"too many conditions on VPT instruction");
7153 if (Pos !=
't' && Pos !=
'e') {
7154 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
7160 Operands.
push_back(ARMOperand::CreateITMask(Mask, Loc, *
this));
7173 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7174 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7175 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7179 if (!CanAcceptCarrySet && CarrySetting) {
7180 return Error(NameLoc,
"instruction '" + Mnemonic +
7181 "' can not set flags, but 's' suffix specified");
7185 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
7186 return Error(NameLoc,
"instruction '" + Mnemonic +
7187 "' is not predicable, but condition code specified");
7192 if (!CanAcceptVPTPredicationCode && VPTPredicationCode !=
ARMVCC::None) {
7193 return Error(NameLoc,
"instruction '" + Mnemonic +
7194 "' is not VPT predicable, but VPT code T/E is specified");
7198 if (CanAcceptCarrySet && CarrySetting) {
7200 Operands.
push_back(ARMOperand::CreateCCOut(
7201 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *
this));
7208 Operands.
push_back(ARMOperand::CreateCondCode(
7216 !(Mnemonic.
starts_with(
"vcvt") && Mnemonic !=
"vcvta" &&
7217 Mnemonic !=
"vcvtn" && Mnemonic !=
"vcvtp" && Mnemonic !=
"vcvtm")) {
7220 Operands.
push_back(ARMOperand::CreateVPTPred(
7225 if (ProcessorIMod) {
7226 Operands.
push_back(ARMOperand::CreateImm(
7229 }
else if (Mnemonic ==
"cps" && isMClass()) {
7230 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
7237 ExtraToken =
Name.slice(Start,
Next);
7246 if (ExtraToken ==
".n" && !
isThumb()) {
7248 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
7255 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
7257 Operands.
push_back(ARMOperand::CreateToken(ExtraToken, Loc, *
this));
7264 unsigned MnemonicOpsEndInd = Operands.
size();
7269 if (parseOperand(Operands, Mnemonic)) {
7275 if (parseOperand(Operands, Mnemonic)) {
7284 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7285 Operands, MnemonicOpsEndInd);
7287 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7295 if (MS.isCDEDualRegInstr(Mnemonic)) {
7297 CDEConvertDualRegOperand(Mnemonic, Operands, MnemonicOpsEndInd);
7304 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7305 MnemonicOpsEndInd) &&
7306 Mnemonic ==
"vmov" && PredicationCode ==
ARMCC::LT) {
7314 Mnemonic.
size() - 1 + CarrySetting);
7317 Operands.
insert(Operands.
begin(), ARMOperand::CreateToken(
7318 StringRef(
"vmovlt"), MLoc, *
this));
7319 }
else if (Mnemonic ==
"vcvt" && PredicationCode ==
ARMCC::NE &&
7320 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7321 MnemonicOpsEndInd)) {
7330 Mnemonic.
size() - 1 + CarrySetting);
7334 ARMOperand::CreateToken(StringRef(
"vcvtn"), MLoc, *
this));
7335 }
else if (Mnemonic ==
"vmul" && PredicationCode ==
ARMCC::LT &&
7336 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7337 MnemonicOpsEndInd)) {
7344 Operands.
insert(Operands.
begin(), ARMOperand::CreateToken(
7345 StringRef(
"vmullt"), MLoc, *
this));
7350 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7351 MnemonicOpsEndInd)) {
7358 if (Mnemonic.
starts_with(
"vcvtt") && MnemonicOpsEndInd > 2) {
7360 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd - 2]);
7362 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd - 1]);
7363 if (!(Sz1.isToken() && Sz1.getToken().starts_with(
".f") &&
7364 Sz2.isToken() && Sz2.getToken().starts_with(
".f"))) {
7369 Mnemonic = Mnemonic.
substr(0, 4);
7371 ARMOperand::CreateToken(Mnemonic, MLoc, *
this));
7375 Mnemonic.
size() + CarrySetting);
7378 ARMOperand::CreateVPTPred(
7380 ++MnemonicOpsEndInd;
7382 }
else if (CanAcceptVPTPredicationCode) {
7386 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7387 MnemonicOpsEndInd)) {
7394 bool usedVPTPredicationCode =
false;
7395 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7396 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred())
7397 usedVPTPredicationCode =
true;
7398 if (!usedVPTPredicationCode) {
7406 Mnemonic =
Name.slice(0, Mnemonic.
size() + 1);
7409 ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7418 if (!
isThumb() && Mnemonic ==
"blx" &&
7419 Operands.
size() == MnemonicOpsEndInd + 1 &&
7420 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).isImm())
7424 fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7433 bool IsLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
7434 if (!
isThumb() && Operands.
size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7435 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
7436 Mnemonic ==
"stlexd")) {
7437 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7438 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*Operands[Idx]);
7439 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[Idx + 1]);
7441 const MCRegisterClass &MRC = MRI->
getRegClass(ARM::GPRRegClassID);
7443 if (Op1.isReg() && MRC.
contains(Op1.getReg())) {
7444 MCRegister Reg1 = Op1.getReg();
7446 MCRegister Reg2 = Op2.getReg();
7450 return Error(Op2.getStartLoc(),
7451 IsLoad ?
"destination operands must be sequential"
7452 :
"source operands must be sequential");
7458 IsLoad ?
"destination operands must start start at an even register"
7459 :
"source operands must start start at an even register");
7462 Reg1, ARM::gsub_0, &(MRI->
getRegClass(ARM::GPRPairRegClassID)));
7463 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7464 Op2.getEndLoc(), *
this);
7474 if (isThumbTwo() && Mnemonic ==
"sub" && CarrySetting &&
7475 Operands.
size() == MnemonicOpsEndInd + 3 &&
7476 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).isReg() &&
7477 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).getReg() ==
7479 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]).isReg() &&
7480 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
7482 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
7483 Operands.
front() = ARMOperand::CreateToken(
"subs", NameLoc, *
this);
7523 return Inst.
getOpcode() == ARM::tBKPT ||
7530 unsigned MnemonicOpsEndInd) {
7531 for (
unsigned I = MnemonicOpsEndInd;
I < Operands.
size(); ++
I) {
7532 const ARMOperand &
Op =
static_cast<const ARMOperand &
>(*Operands[
I]);
7533 if (
Op.isRegList()) {
7540bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
7542 unsigned MnemonicOpsEndInd,
7543 unsigned ListIndex,
bool IsARPop) {
7548 if (!IsARPop && ListContainsSP)
7550 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7551 "SP may not be in the register list");
7552 if (ListContainsPC && ListContainsLR)
7554 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7555 "PC and LR may not be in the register list simultaneously");
7559bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
7561 unsigned MnemonicOpsEndInd,
7562 unsigned ListIndex) {
7566 if (ListContainsSP && ListContainsPC)
7568 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7569 "SP and PC may not be in the register list");
7572 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7573 "SP may not be in the register list");
7576 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7577 "PC may not be in the register list");
7581bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst,
const OperandVector &Operands,
7582 bool Load,
bool ARMMode,
bool Writeback,
7583 unsigned MnemonicOpsEndInd) {
7584 unsigned RtIndex =
Load || !Writeback ? 0 : 1;
7591 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7596 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7597 "Rt must be even-numbered");
7600 if (Rt2 != Rt + 1) {
7602 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7603 "destination operands must be sequential");
7605 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7606 "source operands must be sequential");
7613 if (!ARMMode && Load) {
7615 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7616 "destination operands can't be identical");
7622 if (Rn == Rt || Rn == Rt2) {
7624 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7625 "base register needs to be different from destination "
7628 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7629 "source register and base register can't be identical");
7640 for (
unsigned i = 0; i <
MCID.NumOperands; ++i) {
7652 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
7659bool ARMAsmParser::validateInstruction(MCInst &Inst,
7661 unsigned MnemonicOpsEndInd) {
7662 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
7663 SMLoc Loc = Operands[0]->getStartLoc();
7671 return Error(Loc,
"instructions in IT block must be predicable");
7674 if (
Cond != currentITCond()) {
7676 SMLoc CondLoc = Operands[0]->getEndLoc();
7677 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7678 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCondCode())
7679 CondLoc = Operands[
I]->getStartLoc();
7680 return Error(CondLoc,
"incorrect condition in IT block; got '" +
7682 "', but expected '" +
7691 return Error(Loc,
"predicated instructions must be in IT block");
7695 return Warning(Loc,
"predicated instructions should be in IT block");
7702 if (MCID.
operands()[i].isPredicate()) {
7704 return Error(Loc,
"instruction is not predicable");
7712 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7713 return Error(Loc,
"instruction must be outside of IT block or the last instruction in an IT block");
7717 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7719 return Error(Loc,
"instruction in VPT block must be predicable");
7722 if (Pred != VPTPred) {
7724 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7725 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred())
7726 PredLoc = Operands[
I]->getStartLoc();
7727 return Error(PredLoc,
"incorrect predication in VPT block; got '" +
7729 "', but expected '" +
7736 return Error(Loc,
"VPT predicated instructions must be in VPT block");
7738 const unsigned Opcode = Inst.
getOpcode();
7743 case ARM::VLSTM_T2: {
7746 if (Operands.
size() ==
7747 MnemonicOpsEndInd + 2) {
7748 ARMOperand &
Op =
static_cast<ARMOperand &
>(
7749 *Operands[MnemonicOpsEndInd + 1]);
7751 auto &RegList =
Op.getRegList();
7753 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7754 return Error(
Op.getEndLoc(),
"T2 version requires v8.1-M.Main");
7757 if (hasD32() && RegList.size() != 32) {
7758 return Error(
Op.getEndLoc(),
"operand must be exactly {d0-d31}");
7761 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7763 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7779 return Error(Loc,
"unpredictable IT predicate sequence");
7783 if (validateLDRDSTRD(Inst, Operands,
true,
true,
7784 false, MnemonicOpsEndInd))
7788 case ARM::LDRD_POST:
7789 if (validateLDRDSTRD(Inst, Operands,
true,
true,
7790 true, MnemonicOpsEndInd))
7794 if (validateLDRDSTRD(Inst, Operands,
true,
false,
7795 false, MnemonicOpsEndInd))
7798 case ARM::t2LDRD_PRE:
7799 case ARM::t2LDRD_POST:
7800 if (validateLDRDSTRD(Inst, Operands,
true,
false,
7801 true, MnemonicOpsEndInd))
7807 if (RmReg == ARM::SP && !hasV8Ops())
7808 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7809 "r13 (SP) is an unpredictable operand to BXJ");
7813 if (validateLDRDSTRD(Inst, Operands,
false,
true,
7814 false, MnemonicOpsEndInd))
7818 case ARM::STRD_POST:
7819 if (validateLDRDSTRD(Inst, Operands,
false,
true,
7820 true, MnemonicOpsEndInd))
7823 case ARM::t2STRD_PRE:
7824 case ARM::t2STRD_POST:
7825 if (validateLDRDSTRD(Inst, Operands,
false,
false,
7826 true, MnemonicOpsEndInd))
7829 case ARM::STR_PRE_IMM:
7830 case ARM::STR_PRE_REG:
7831 case ARM::t2STR_PRE:
7832 case ARM::STR_POST_IMM:
7833 case ARM::STR_POST_REG:
7834 case ARM::t2STR_POST:
7836 case ARM::t2STRH_PRE:
7837 case ARM::STRH_POST:
7838 case ARM::t2STRH_POST:
7839 case ARM::STRB_PRE_IMM:
7840 case ARM::STRB_PRE_REG:
7841 case ARM::t2STRB_PRE:
7842 case ARM::STRB_POST_IMM:
7843 case ARM::STRB_POST_REG:
7844 case ARM::t2STRB_POST: {
7850 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7851 "source register and base register can't be identical");
7854 case ARM::t2LDR_PRE_imm:
7855 case ARM::t2LDR_POST_imm:
7856 case ARM::t2STR_PRE_imm:
7857 case ARM::t2STR_POST_imm: {
7863 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7864 "destination register and base register can't be identical");
7865 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7866 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7868 if (Imm > 255 || Imm < -255)
7869 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7870 "operand must be in range [-255, 255]");
7872 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7873 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7875 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7876 "operand must be a register in range [r0, r14]");
7882 case ARM::t2LDRB_OFFSET_imm:
7883 case ARM::t2LDRB_PRE_imm:
7884 case ARM::t2LDRB_POST_imm:
7885 case ARM::t2STRB_OFFSET_imm:
7886 case ARM::t2STRB_PRE_imm:
7887 case ARM::t2STRB_POST_imm: {
7888 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7889 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7890 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7891 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7893 if (Imm > 255 || Imm < -255)
7894 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7895 "operand must be in range [-255, 255]");
7896 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7897 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7899 if (Imm > 0 || Imm < -255)
7900 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7901 "operand must be in range [0, 255] with a negative sign");
7904 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7905 "if operand is PC, should call the LDRB (literal)");
7910 case ARM::t2LDRH_OFFSET_imm:
7911 case ARM::t2LDRH_PRE_imm:
7912 case ARM::t2LDRH_POST_imm:
7913 case ARM::t2STRH_OFFSET_imm:
7914 case ARM::t2STRH_PRE_imm:
7915 case ARM::t2STRH_POST_imm: {
7916 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7917 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7918 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7919 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7921 if (Imm > 255 || Imm < -255)
7922 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7923 "operand must be in range [-255, 255]");
7924 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7925 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7927 if (Imm > 0 || Imm < -255)
7928 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7929 "operand must be in range [0, 255] with a negative sign");
7932 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7933 "if operand is PC, should call the LDRH (literal)");
7938 case ARM::t2LDRSB_OFFSET_imm:
7939 case ARM::t2LDRSB_PRE_imm:
7940 case ARM::t2LDRSB_POST_imm: {
7941 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7942 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7944 if (Imm > 255 || Imm < -255)
7945 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7946 "operand must be in range [-255, 255]");
7947 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7949 if (Imm > 0 || Imm < -255)
7950 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7951 "operand must be in range [0, 255] with a negative sign");
7954 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7955 "if operand is PC, should call the LDRH (literal)");
7960 case ARM::t2LDRSH_OFFSET_imm:
7961 case ARM::t2LDRSH_PRE_imm:
7962 case ARM::t2LDRSH_POST_imm: {
7963 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7964 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7966 if (Imm > 255 || Imm < -255)
7967 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7968 "operand must be in range [-255, 255]");
7969 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7971 if (Imm > 0 || Imm < -255)
7972 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7973 "operand must be in range [0, 255] with a negative sign");
7976 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7977 "if operand is PC, should call the LDRH (literal)");
7982 case ARM::LDR_PRE_IMM:
7983 case ARM::LDR_PRE_REG:
7984 case ARM::t2LDR_PRE:
7985 case ARM::LDR_POST_IMM:
7986 case ARM::LDR_POST_REG:
7987 case ARM::t2LDR_POST:
7989 case ARM::t2LDRH_PRE:
7990 case ARM::LDRH_POST:
7991 case ARM::t2LDRH_POST:
7992 case ARM::LDRSH_PRE:
7993 case ARM::t2LDRSH_PRE:
7994 case ARM::LDRSH_POST:
7995 case ARM::t2LDRSH_POST:
7996 case ARM::LDRB_PRE_IMM:
7997 case ARM::LDRB_PRE_REG:
7998 case ARM::t2LDRB_PRE:
7999 case ARM::LDRB_POST_IMM:
8000 case ARM::LDRB_POST_REG:
8001 case ARM::t2LDRB_POST:
8002 case ARM::LDRSB_PRE:
8003 case ARM::t2LDRSB_PRE:
8004 case ARM::LDRSB_POST:
8005 case ARM::t2LDRSB_POST: {
8011 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8012 "destination register and base register can't be identical");
8016 case ARM::MVE_VLDRBU8_rq:
8017 case ARM::MVE_VLDRBU16_rq:
8018 case ARM::MVE_VLDRBS16_rq:
8019 case ARM::MVE_VLDRBU32_rq:
8020 case ARM::MVE_VLDRBS32_rq:
8021 case ARM::MVE_VLDRHU16_rq:
8022 case ARM::MVE_VLDRHU16_rq_u:
8023 case ARM::MVE_VLDRHU32_rq:
8024 case ARM::MVE_VLDRHU32_rq_u:
8025 case ARM::MVE_VLDRHS32_rq:
8026 case ARM::MVE_VLDRHS32_rq_u:
8027 case ARM::MVE_VLDRWU32_rq:
8028 case ARM::MVE_VLDRWU32_rq_u:
8029 case ARM::MVE_VLDRDU64_rq:
8030 case ARM::MVE_VLDRDU64_rq_u:
8031 case ARM::MVE_VLDRWU32_qi:
8032 case ARM::MVE_VLDRWU32_qi_pre:
8033 case ARM::MVE_VLDRDU64_qi:
8034 case ARM::MVE_VLDRDU64_qi_pre: {
8036 unsigned QdIdx = 0, QmIdx = 2;
8037 bool QmIsPointer =
false;
8039 case ARM::MVE_VLDRWU32_qi:
8040 case ARM::MVE_VLDRDU64_qi:
8044 case ARM::MVE_VLDRWU32_qi_pre:
8045 case ARM::MVE_VLDRDU64_qi_pre:
8055 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8056 Twine(
"destination vector register and vector ") +
8057 (QmIsPointer ?
"pointer" :
"offset") +
8058 " register can't be identical");
8070 if (Widthm1 >= 32 - LSB)
8071 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8072 "bitfield width must be in range [1,32-lsb]");
8084 bool HasWritebackToken =
8085 (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8087 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8090 bool ListContainsBase;
8094 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8095 "registers must be in range r0-r7");
8097 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8099 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8100 "writeback operator '!' expected");
8103 if (ListContainsBase && HasWritebackToken)
8104 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8105 "writeback operator '!' not allowed when base register "
8106 "in register list");
8108 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8112 case ARM::LDMIA_UPD:
8113 case ARM::LDMDB_UPD:
8114 case ARM::LDMIB_UPD:
8115 case ARM::LDMDA_UPD:
8121 return Error(Operands.
back()->getStartLoc(),
8122 "writeback register not allowed in register list");
8126 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8131 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8134 case ARM::t2LDMIA_UPD:
8135 case ARM::t2LDMDB_UPD:
8136 case ARM::t2STMIA_UPD:
8137 case ARM::t2STMDB_UPD:
8139 return Error(Operands.
back()->getStartLoc(),
8140 "writeback register not allowed in register list");
8142 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8143 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8146 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8151 case ARM::sysLDMIA_UPD:
8152 case ARM::sysLDMDA_UPD:
8153 case ARM::sysLDMDB_UPD:
8154 case ARM::sysLDMIB_UPD:
8156 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8157 "writeback register only allowed on system LDM "
8158 "if PC in register-list");
8160 case ARM::sysSTMIA_UPD:
8161 case ARM::sysSTMDA_UPD:
8162 case ARM::sysSTMDB_UPD:
8163 case ARM::sysSTMIB_UPD:
8164 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8165 "system STM cannot have writeback register");
8170 bool ListContainsBase;
8172 ListContainsBase) &&
8174 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8175 "registers must be in range r0-r7 or pc");
8176 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8181 bool ListContainsBase;
8183 ListContainsBase) &&
8185 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8186 "registers must be in range r0-r7 or lr");
8187 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8191 case ARM::tSTMIA_UPD: {
8192 bool ListContainsBase, InvalidLowList;
8194 0, ListContainsBase);
8195 if (InvalidLowList && !isThumbTwo())
8196 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8197 "registers must be in range r0-r7");
8201 if (InvalidLowList && ListContainsBase)
8202 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8203 "writeback operator '!' not allowed when base register "
8204 "in register list");
8206 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8213 if (!isThumbTwo() &&
8215 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8216 "source register must be the same as destination");
8226 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8227 "source register must be sp if destination is sp");
8232 if (!(
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]))
8233 .isSignedOffset<11, 1>())
8234 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8235 "branch target out of range");
8238 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8239 : MnemonicOpsEndInd + 1;
8240 ARMOperand &Operand =
static_cast<ARMOperand &
>(*Operands[
op]);
8243 !Operand.isSignedOffset<24, 1>())
8244 return Error(Operands[
op]->getStartLoc(),
"branch target out of range");
8249 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8250 .isSignedOffset<8, 1>())
8251 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8252 "branch target out of range");
8255 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8256 : MnemonicOpsEndInd + 1;
8257 if (!
static_cast<ARMOperand &
>(*Operands[
Op]).isSignedOffset<20, 1>())
8258 return Error(Operands[
Op]->getStartLoc(),
"branch target out of range");
8263 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8264 .isUnsignedOffset<6, 1>())
8265 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8266 "branch target out of range");
8272 case ARM::t2MOVTi16:
8280 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8281 : MnemonicOpsEndInd + 1;
8282 ARMOperand &
Op =
static_cast<ARMOperand &
>(*Operands[i]);
8283 const MCExpr *
E =
Op.getImm();
8287 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8291 "immediate expression for mov requires :lower16: or :upper16");
8295 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8296 : MnemonicOpsEndInd + 2;
8297 MCParsedAsmOperand &
Op = *Operands[i];
8299 return Error(
Op.getStartLoc(),
8300 "Immediate expression for Thumb adds requires :lower0_7:,"
8301 " :lower8_15:, :upper0_7: or :upper8_15:");
8305 MCParsedAsmOperand &
Op = *Operands[MnemonicOpsEndInd + 1];
8307 return Error(
Op.getStartLoc(),
8308 "Immediate expression for Thumb movs requires :lower0_7:,"
8309 " :lower8_15:, :upper0_7: or :upper8_15:");
8318 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
8319 return Error(Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8320 "predicable, but condition "
8323 return Error(Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8324 "predicable, but condition "
8332 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8333 .isUnsignedOffset<4, 1>() ||
8335 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8336 "branch location out of range or not a multiple of 2");
8339 if (Opcode == ARM::t2BFi) {
8340 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8341 .isSignedOffset<16, 1>())
8342 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8343 "branch target out of range or not a multiple of 2");
8344 }
else if (Opcode == ARM::t2BFLi) {
8345 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8346 .isSignedOffset<18, 1>())
8347 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8348 "branch target out of range or not a multiple of 2");
8353 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8354 .isUnsignedOffset<4, 1>() ||
8356 return Error(Operands[1]->getStartLoc(),
8357 "branch location out of range or not a multiple of 2");
8359 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8360 .isSignedOffset<16, 1>())
8361 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8362 "branch target out of range or not a multiple of 2");
8365 "branch location and else branch target should either both be "
8366 "immediates or both labels");
8370 if (Diff != 4 && Diff != 2)
8372 Operands[3]->getStartLoc(),
8373 "else branch target must be 2 or 4 greater than the branch location");
8380 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8382 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8383 "invalid register in register list. Valid registers are "
8384 "r0-r12, lr/r14 and APSR.");
8400 return Error(Operands[1]->getStartLoc(),
8401 "instruction 'ssbb' is not predicable, but condition code "
8404 return Error(Operands[1]->getStartLoc(),
8405 "instruction 'pssbb' is not predicable, but condition code "
8409 case ARM::VMOVRRS: {
8414 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8415 "source operands must be sequential");
8418 case ARM::VMOVSRR: {
8423 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8424 "destination operands must be sequential");
8428 case ARM::VSTMDIA: {
8430 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
8431 auto &RegList =
Op.getRegList();
8432 if (RegList.size() < 1 || RegList.size() > 16)
8433 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8434 "list of registers must be at least 1 and at most 16");
8437 case ARM::MVE_VQDMULLs32bh:
8438 case ARM::MVE_VQDMULLs32th:
8439 case ARM::MVE_VCMULf32:
8440 case ARM::MVE_VMULLBs32:
8441 case ARM::MVE_VMULLTs32:
8442 case ARM::MVE_VMULLBu32:
8443 case ARM::MVE_VMULLTu32: {
8444 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8445 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8446 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8447 "Qd register and Qn register can't be identical");
8449 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8450 Operands[MnemonicOpsEndInd + 2]->
getReg()) {
8451 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8452 "Qd register and Qm register can't be identical");
8456 case ARM::MVE_VREV64_8:
8457 case ARM::MVE_VREV64_16:
8458 case ARM::MVE_VREV64_32:
8459 case ARM::MVE_VQDMULL_qr_s32bh:
8460 case ARM::MVE_VQDMULL_qr_s32th: {
8461 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8462 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8463 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8464 "Qd register and Qn register can't be identical");
8468 case ARM::MVE_VCADDi32:
8469 case ARM::MVE_VCADDf32:
8470 case ARM::MVE_VHCADDs32: {
8471 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8472 Operands[MnemonicOpsEndInd + 2]->
getReg()) {
8473 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8474 "Qd register and Qm register can't be identical");
8478 case ARM::MVE_VMOV_rr_q: {
8479 if (Operands[MnemonicOpsEndInd + 2]->
getReg() !=
8480 Operands[MnemonicOpsEndInd + 4]->
getReg())
8481 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8482 "Q-registers must be the same");
8483 if (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 3])
8484 .getVectorIndex() !=
8485 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 5])
8488 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8489 "Q-register indexes must be 2 and 0 or 3 and 1");
8492 case ARM::MVE_VMOV_q_rr: {
8493 if (Operands[MnemonicOpsEndInd]->
getReg() !=
8494 Operands[MnemonicOpsEndInd + 2]->
getReg())
8495 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8496 "Q-registers must be the same");
8497 if (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8498 .getVectorIndex() !=
8499 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 3])
8502 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8503 "Q-register indexes must be 2 and 0 or 3 and 1");
8506 case ARM::MVE_SQRSHR:
8507 case ARM::MVE_UQRSHL: {
8508 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8509 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8510 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8511 "Rda register and Rm register can't be identical");
8532 case ARM::t2SMLALBB:
8533 case ARM::t2SMLALBT:
8535 case ARM::t2SMLALDX:
8536 case ARM::t2SMLALTB:
8537 case ARM::t2SMLALTT:
8539 case ARM::t2SMLSLDX:
8540 case ARM::t2SMULL: {
8545 "unpredictable instruction, RdHi and RdLo must be different");
8553 case ARM::CDE_CX1DA:
8557 case ARM::CDE_CX2DA:
8561 case ARM::CDE_CX3DA:
8562 case ARM::CDE_VCX1_vec:
8563 case ARM::CDE_VCX1_fpsp:
8564 case ARM::CDE_VCX1_fpdp:
8565 case ARM::CDE_VCX1A_vec:
8566 case ARM::CDE_VCX1A_fpsp:
8567 case ARM::CDE_VCX1A_fpdp:
8568 case ARM::CDE_VCX2_vec:
8569 case ARM::CDE_VCX2_fpsp:
8570 case ARM::CDE_VCX2_fpdp:
8571 case ARM::CDE_VCX2A_vec:
8572 case ARM::CDE_VCX2A_fpsp:
8573 case ARM::CDE_VCX2A_fpdp:
8574 case ARM::CDE_VCX3_vec:
8575 case ARM::CDE_VCX3_fpsp:
8576 case ARM::CDE_VCX3_fpdp:
8577 case ARM::CDE_VCX3A_vec:
8578 case ARM::CDE_VCX3A_fpsp:
8579 case ARM::CDE_VCX3A_fpdp: {
8581 "CDE operand 1 must be a coprocessor ID");
8584 return Error(Operands[1]->getStartLoc(),
8585 "coprocessor must be configured as CDE");
8586 else if (Coproc >= 8)
8587 return Error(Operands[1]->getStartLoc(),
8588 "coprocessor must be in the range [p0, p7]");
8594 case ARM::t2LDC2L_OFFSET:
8595 case ARM::t2LDC2L_OPTION:
8596 case ARM::t2LDC2L_POST:
8597 case ARM::t2LDC2L_PRE:
8598 case ARM::t2LDC2_OFFSET:
8599 case ARM::t2LDC2_OPTION:
8600 case ARM::t2LDC2_POST:
8601 case ARM::t2LDC2_PRE:
8602 case ARM::t2LDCL_OFFSET:
8603 case ARM::t2LDCL_OPTION:
8604 case ARM::t2LDCL_POST:
8605 case ARM::t2LDCL_PRE:
8606 case ARM::t2LDC_OFFSET:
8607 case ARM::t2LDC_OPTION:
8608 case ARM::t2LDC_POST:
8609 case ARM::t2LDC_PRE:
8618 case ARM::t2STC2L_OFFSET:
8619 case ARM::t2STC2L_OPTION:
8620 case ARM::t2STC2L_POST:
8621 case ARM::t2STC2L_PRE:
8622 case ARM::t2STC2_OFFSET:
8623 case ARM::t2STC2_OPTION:
8624 case ARM::t2STC2_POST:
8625 case ARM::t2STC2_PRE:
8626 case ARM::t2STCL_OFFSET:
8627 case ARM::t2STCL_OPTION:
8628 case ARM::t2STCL_POST:
8629 case ARM::t2STCL_PRE:
8630 case ARM::t2STC_OFFSET:
8631 case ARM::t2STC_OPTION:
8632 case ARM::t2STC_POST:
8633 case ARM::t2STC_PRE: {
8638 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8640 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8643 "Operand must be a coprocessor ID");
8647 return Error(Operands[2]->getStartLoc(),
8648 "coprocessor must be configured as GCP");
8676 if (Operands[MnemonicOpsEndInd]->
getReg() !=
8677 Operands[MnemonicOpsEndInd + 1]->
getReg())
8678 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8679 "source and destination registers must be the same");
8691 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8693 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8694 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8695 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8696 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8697 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8698 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8699 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8702 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8704 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8706 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8708 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8709 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8710 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8711 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8712 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8714 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8715 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8716 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8717 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8718 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8721 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8723 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8725 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8726 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8727 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8728 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8729 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8730 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8731 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8732 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8733 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8734 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8735 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8738 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8739 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8740 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8741 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8742 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8743 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8744 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8745 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8746 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8747 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8748 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8749 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8750 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8751 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8752 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8753 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8754 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8755 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8758 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8760 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8762 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8763 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8764 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8765 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8766 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8767 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8768 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8769 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8770 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8771 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8772 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8775 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8776 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8777 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8778 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8779 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8780 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8781 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8782 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8783 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8784 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8785 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8786 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8787 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8788 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8789 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8790 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8791 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8792 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8800 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8802 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8805 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8806 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8807 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8808 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8811 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8813 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8815 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8818 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8820 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8821 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8822 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8823 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8824 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8825 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8828 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8830 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8833 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8836 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8839 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8840 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8841 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8842 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8843 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8844 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8845 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8848 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8850 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8852 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8855 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8857 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8858 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8859 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8860 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8861 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8862 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8865 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8867 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8870 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8871 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8872 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8873 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8874 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8875 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8876 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8877 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8878 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8879 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8880 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8881 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8882 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8885 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8887 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8889 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8892 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8894 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8895 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8896 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8897 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8898 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8899 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8902 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8904 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8907 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8910 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8913 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8914 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8915 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8916 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8917 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8918 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8919 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8922 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8924 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8927 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8928 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8929 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8930 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8931 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8932 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8933 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8934 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8935 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8936 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8937 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8938 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8939 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8943bool ARMAsmParser::processInstruction(MCInst &Inst,
8945 unsigned MnemonicOpsEndInd,
8949 bool HasWideQualifier =
false;
8950 for (
auto &
Op : Operands) {
8951 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8952 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8953 HasWideQualifier =
true;
8963 if (Operands.size() ==
8964 MnemonicOpsEndInd + 2) {
8965 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8966 *Operands[MnemonicOpsEndInd + 1]);
8968 auto &RegList =
Op.getRegList();
8971 if (RegList.size() == 32) {
8972 const unsigned Opcode =
8973 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8987 case ARM::LDRT_POST:
8988 case ARM::LDRBT_POST: {
8989 const unsigned Opcode =
8990 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8991 : ARM::LDRBT_POST_IMM;
9007 case ARM::LDRSHTii: {
9012 else if (Inst.
getOpcode() == ARM::LDRHTii)
9014 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9025 case ARM::STRT_POST:
9026 case ARM::STRBT_POST: {
9027 const unsigned Opcode =
9028 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9029 : ARM::STRBT_POST_IMM;
9078 case ARM::t2LDR_PRE_imm:
9079 case ARM::t2LDR_POST_imm: {
9093 case ARM::t2STR_PRE_imm:
9094 case ARM::t2STR_POST_imm: {
9108 case ARM::t2LDRB_OFFSET_imm: {
9118 case ARM::t2LDRB_PRE_imm:
9119 case ARM::t2LDRB_POST_imm: {
9123 : ARM::t2LDRB_POST);
9134 case ARM::t2STRB_OFFSET_imm: {
9144 case ARM::t2STRB_PRE_imm:
9145 case ARM::t2STRB_POST_imm: {
9149 : ARM::t2STRB_POST);
9160 case ARM::t2LDRH_OFFSET_imm: {
9170 case ARM::t2LDRH_PRE_imm:
9171 case ARM::t2LDRH_POST_imm: {
9175 : ARM::t2LDRH_POST);
9186 case ARM::t2STRH_OFFSET_imm: {
9196 case ARM::t2STRH_PRE_imm:
9197 case ARM::t2STRH_POST_imm: {
9201 : ARM::t2STRH_POST);
9212 case ARM::t2LDRSB_OFFSET_imm: {
9222 case ARM::t2LDRSB_PRE_imm:
9223 case ARM::t2LDRSB_POST_imm: {
9227 : ARM::t2LDRSB_POST);
9238 case ARM::t2LDRSH_OFFSET_imm: {
9248 case ARM::t2LDRSH_PRE_imm:
9249 case ARM::t2LDRSH_POST_imm: {
9253 : ARM::t2LDRSH_POST);
9264 case ARM::t2LDRpcrel:
9273 case ARM::t2LDRBpcrel:
9276 case ARM::t2LDRHpcrel:
9279 case ARM::t2LDRSBpcrel:
9282 case ARM::t2LDRSHpcrel:
9285 case ARM::LDRConstPool:
9286 case ARM::tLDRConstPool:
9287 case ARM::t2LDRConstPool: {
9292 if (Inst.
getOpcode() == ARM::LDRConstPool)
9294 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9296 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9298 const ARMOperand &PoolOperand =
9299 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
9300 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9308 bool MovHasS =
true;
9309 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9319 else if (hasV6T2Ops() &&
9332 else if (hasThumb2() &&
9337 else if (hasV8MBaseline() &&
9357 const MCExpr *CPLoc =
9358 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9359 PoolOperand.getStartLoc());
9370 case ARM::VST1LNdWB_register_Asm_8:
9371 case ARM::VST1LNdWB_register_Asm_16:
9372 case ARM::VST1LNdWB_register_Asm_32: {
9390 case ARM::VST2LNdWB_register_Asm_8:
9391 case ARM::VST2LNdWB_register_Asm_16:
9392 case ARM::VST2LNdWB_register_Asm_32:
9393 case ARM::VST2LNqWB_register_Asm_16:
9394 case ARM::VST2LNqWB_register_Asm_32: {
9414 case ARM::VST3LNdWB_register_Asm_8:
9415 case ARM::VST3LNdWB_register_Asm_16:
9416 case ARM::VST3LNdWB_register_Asm_32:
9417 case ARM::VST3LNqWB_register_Asm_16:
9418 case ARM::VST3LNqWB_register_Asm_32: {
9440 case ARM::VST4LNdWB_register_Asm_8:
9441 case ARM::VST4LNdWB_register_Asm_16:
9442 case ARM::VST4LNdWB_register_Asm_32:
9443 case ARM::VST4LNqWB_register_Asm_16:
9444 case ARM::VST4LNqWB_register_Asm_32: {
9468 case ARM::VST1LNdWB_fixed_Asm_8:
9469 case ARM::VST1LNdWB_fixed_Asm_16:
9470 case ARM::VST1LNdWB_fixed_Asm_32: {
9488 case ARM::VST2LNdWB_fixed_Asm_8:
9489 case ARM::VST2LNdWB_fixed_Asm_16:
9490 case ARM::VST2LNdWB_fixed_Asm_32:
9491 case ARM::VST2LNqWB_fixed_Asm_16:
9492 case ARM::VST2LNqWB_fixed_Asm_32: {
9512 case ARM::VST3LNdWB_fixed_Asm_8:
9513 case ARM::VST3LNdWB_fixed_Asm_16:
9514 case ARM::VST3LNdWB_fixed_Asm_32:
9515 case ARM::VST3LNqWB_fixed_Asm_16:
9516 case ARM::VST3LNqWB_fixed_Asm_32: {
9538 case ARM::VST4LNdWB_fixed_Asm_8:
9539 case ARM::VST4LNdWB_fixed_Asm_16:
9540 case ARM::VST4LNdWB_fixed_Asm_32:
9541 case ARM::VST4LNqWB_fixed_Asm_16:
9542 case ARM::VST4LNqWB_fixed_Asm_32: {
9566 case ARM::VST1LNdAsm_8:
9567 case ARM::VST1LNdAsm_16:
9568 case ARM::VST1LNdAsm_32: {
9584 case ARM::VST2LNdAsm_8:
9585 case ARM::VST2LNdAsm_16:
9586 case ARM::VST2LNdAsm_32:
9587 case ARM::VST2LNqAsm_16:
9588 case ARM::VST2LNqAsm_32: {
9606 case ARM::VST3LNdAsm_8:
9607 case ARM::VST3LNdAsm_16:
9608 case ARM::VST3LNdAsm_32:
9609 case ARM::VST3LNqAsm_16:
9610 case ARM::VST3LNqAsm_32: {
9630 case ARM::VST4LNdAsm_8:
9631 case ARM::VST4LNdAsm_16:
9632 case ARM::VST4LNdAsm_32:
9633 case ARM::VST4LNqAsm_16:
9634 case ARM::VST4LNqAsm_32: {
9657 case ARM::VLD1LNdWB_register_Asm_8:
9658 case ARM::VLD1LNdWB_register_Asm_16:
9659 case ARM::VLD1LNdWB_register_Asm_32: {
9678 case ARM::VLD2LNdWB_register_Asm_8:
9679 case ARM::VLD2LNdWB_register_Asm_16:
9680 case ARM::VLD2LNdWB_register_Asm_32:
9681 case ARM::VLD2LNqWB_register_Asm_16:
9682 case ARM::VLD2LNqWB_register_Asm_32: {
9705 case ARM::VLD3LNdWB_register_Asm_8:
9706 case ARM::VLD3LNdWB_register_Asm_16:
9707 case ARM::VLD3LNdWB_register_Asm_32:
9708 case ARM::VLD3LNqWB_register_Asm_16:
9709 case ARM::VLD3LNqWB_register_Asm_32: {
9736 case ARM::VLD4LNdWB_register_Asm_8:
9737 case ARM::VLD4LNdWB_register_Asm_16:
9738 case ARM::VLD4LNdWB_register_Asm_32:
9739 case ARM::VLD4LNqWB_register_Asm_16:
9740 case ARM::VLD4LNqWB_register_Asm_32: {
9771 case ARM::VLD1LNdWB_fixed_Asm_8:
9772 case ARM::VLD1LNdWB_fixed_Asm_16:
9773 case ARM::VLD1LNdWB_fixed_Asm_32: {
9792 case ARM::VLD2LNdWB_fixed_Asm_8:
9793 case ARM::VLD2LNdWB_fixed_Asm_16:
9794 case ARM::VLD2LNdWB_fixed_Asm_32:
9795 case ARM::VLD2LNqWB_fixed_Asm_16:
9796 case ARM::VLD2LNqWB_fixed_Asm_32: {
9819 case ARM::VLD3LNdWB_fixed_Asm_8:
9820 case ARM::VLD3LNdWB_fixed_Asm_16:
9821 case ARM::VLD3LNdWB_fixed_Asm_32:
9822 case ARM::VLD3LNqWB_fixed_Asm_16:
9823 case ARM::VLD3LNqWB_fixed_Asm_32: {
9850 case ARM::VLD4LNdWB_fixed_Asm_8:
9851 case ARM::VLD4LNdWB_fixed_Asm_16:
9852 case ARM::VLD4LNdWB_fixed_Asm_32:
9853 case ARM::VLD4LNqWB_fixed_Asm_16:
9854 case ARM::VLD4LNqWB_fixed_Asm_32: {
9885 case ARM::VLD1LNdAsm_8:
9886 case ARM::VLD1LNdAsm_16:
9887 case ARM::VLD1LNdAsm_32: {
9904 case ARM::VLD2LNdAsm_8:
9905 case ARM::VLD2LNdAsm_16:
9906 case ARM::VLD2LNdAsm_32:
9907 case ARM::VLD2LNqAsm_16:
9908 case ARM::VLD2LNqAsm_32: {
9929 case ARM::VLD3LNdAsm_8:
9930 case ARM::VLD3LNdAsm_16:
9931 case ARM::VLD3LNdAsm_32:
9932 case ARM::VLD3LNqAsm_16:
9933 case ARM::VLD3LNqAsm_32: {
9958 case ARM::VLD4LNdAsm_8:
9959 case ARM::VLD4LNdAsm_16:
9960 case ARM::VLD4LNdAsm_32:
9961 case ARM::VLD4LNqAsm_16:
9962 case ARM::VLD4LNqAsm_32: {
9992 case ARM::VLD3DUPdAsm_8:
9993 case ARM::VLD3DUPdAsm_16:
9994 case ARM::VLD3DUPdAsm_32:
9995 case ARM::VLD3DUPqAsm_8:
9996 case ARM::VLD3DUPqAsm_16:
9997 case ARM::VLD3DUPqAsm_32: {
10014 case ARM::VLD3DUPdWB_fixed_Asm_8:
10015 case ARM::VLD3DUPdWB_fixed_Asm_16:
10016 case ARM::VLD3DUPdWB_fixed_Asm_32:
10017 case ARM::VLD3DUPqWB_fixed_Asm_8:
10018 case ARM::VLD3DUPqWB_fixed_Asm_16:
10019 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10038 case ARM::VLD3DUPdWB_register_Asm_8:
10039 case ARM::VLD3DUPdWB_register_Asm_16:
10040 case ARM::VLD3DUPdWB_register_Asm_32:
10041 case ARM::VLD3DUPqWB_register_Asm_8:
10042 case ARM::VLD3DUPqWB_register_Asm_16:
10043 case ARM::VLD3DUPqWB_register_Asm_32: {
10063 case ARM::VLD3dAsm_8:
10064 case ARM::VLD3dAsm_16:
10065 case ARM::VLD3dAsm_32:
10066 case ARM::VLD3qAsm_8:
10067 case ARM::VLD3qAsm_16:
10068 case ARM::VLD3qAsm_32: {
10085 case ARM::VLD3dWB_fixed_Asm_8:
10086 case ARM::VLD3dWB_fixed_Asm_16:
10087 case ARM::VLD3dWB_fixed_Asm_32:
10088 case ARM::VLD3qWB_fixed_Asm_8:
10089 case ARM::VLD3qWB_fixed_Asm_16:
10090 case ARM::VLD3qWB_fixed_Asm_32: {
10109 case ARM::VLD3dWB_register_Asm_8:
10110 case ARM::VLD3dWB_register_Asm_16:
10111 case ARM::VLD3dWB_register_Asm_32:
10112 case ARM::VLD3qWB_register_Asm_8:
10113 case ARM::VLD3qWB_register_Asm_16:
10114 case ARM::VLD3qWB_register_Asm_32: {
10134 case ARM::VLD4DUPdAsm_8:
10135 case ARM::VLD4DUPdAsm_16:
10136 case ARM::VLD4DUPdAsm_32:
10137 case ARM::VLD4DUPqAsm_8:
10138 case ARM::VLD4DUPqAsm_16:
10139 case ARM::VLD4DUPqAsm_32: {
10158 case ARM::VLD4DUPdWB_fixed_Asm_8:
10159 case ARM::VLD4DUPdWB_fixed_Asm_16:
10160 case ARM::VLD4DUPdWB_fixed_Asm_32:
10161 case ARM::VLD4DUPqWB_fixed_Asm_8:
10162 case ARM::VLD4DUPqWB_fixed_Asm_16:
10163 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10184 case ARM::VLD4DUPdWB_register_Asm_8:
10185 case ARM::VLD4DUPdWB_register_Asm_16:
10186 case ARM::VLD4DUPdWB_register_Asm_32:
10187 case ARM::VLD4DUPqWB_register_Asm_8:
10188 case ARM::VLD4DUPqWB_register_Asm_16:
10189 case ARM::VLD4DUPqWB_register_Asm_32: {
10211 case ARM::VLD4dAsm_8:
10212 case ARM::VLD4dAsm_16:
10213 case ARM::VLD4dAsm_32:
10214 case ARM::VLD4qAsm_8:
10215 case ARM::VLD4qAsm_16:
10216 case ARM::VLD4qAsm_32: {
10235 case ARM::VLD4dWB_fixed_Asm_8:
10236 case ARM::VLD4dWB_fixed_Asm_16:
10237 case ARM::VLD4dWB_fixed_Asm_32:
10238 case ARM::VLD4qWB_fixed_Asm_8:
10239 case ARM::VLD4qWB_fixed_Asm_16:
10240 case ARM::VLD4qWB_fixed_Asm_32: {
10261 case ARM::VLD4dWB_register_Asm_8:
10262 case ARM::VLD4dWB_register_Asm_16:
10263 case ARM::VLD4dWB_register_Asm_32:
10264 case ARM::VLD4qWB_register_Asm_8:
10265 case ARM::VLD4qWB_register_Asm_16:
10266 case ARM::VLD4qWB_register_Asm_32: {
10288 case ARM::VST3dAsm_8:
10289 case ARM::VST3dAsm_16:
10290 case ARM::VST3dAsm_32:
10291 case ARM::VST3qAsm_8:
10292 case ARM::VST3qAsm_16:
10293 case ARM::VST3qAsm_32: {
10310 case ARM::VST3dWB_fixed_Asm_8:
10311 case ARM::VST3dWB_fixed_Asm_16:
10312 case ARM::VST3dWB_fixed_Asm_32:
10313 case ARM::VST3qWB_fixed_Asm_8:
10314 case ARM::VST3qWB_fixed_Asm_16:
10315 case ARM::VST3qWB_fixed_Asm_32: {
10334 case ARM::VST3dWB_register_Asm_8:
10335 case ARM::VST3dWB_register_Asm_16:
10336 case ARM::VST3dWB_register_Asm_32:
10337 case ARM::VST3qWB_register_Asm_8:
10338 case ARM::VST3qWB_register_Asm_16:
10339 case ARM::VST3qWB_register_Asm_32: {
10359 case ARM::VST4dAsm_8:
10360 case ARM::VST4dAsm_16:
10361 case ARM::VST4dAsm_32:
10362 case ARM::VST4qAsm_8:
10363 case ARM::VST4qAsm_16:
10364 case ARM::VST4qAsm_32: {
10383 case ARM::VST4dWB_fixed_Asm_8:
10384 case ARM::VST4dWB_fixed_Asm_16:
10385 case ARM::VST4dWB_fixed_Asm_32:
10386 case ARM::VST4qWB_fixed_Asm_8:
10387 case ARM::VST4qWB_fixed_Asm_16:
10388 case ARM::VST4qWB_fixed_Asm_32: {
10409 case ARM::VST4dWB_register_Asm_8:
10410 case ARM::VST4dWB_register_Asm_16:
10411 case ARM::VST4dWB_register_Asm_32:
10412 case ARM::VST4qWB_register_Asm_8:
10413 case ARM::VST4qWB_register_Asm_16:
10414 case ARM::VST4qWB_register_Asm_32: {
10442 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10443 !HasWideQualifier) {
10447 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
10448 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
10449 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
10467 case ARM::t2MOVSsr: {
10471 bool isNarrow =
false;
10476 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr) &&
10483 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
10484 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
10485 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
10486 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
10492 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10499 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10504 case ARM::t2MOVSsi: {
10508 bool isNarrow =
false;
10511 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi) &&
10518 bool isMov =
false;
10529 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10533 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
10534 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
10535 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
10536 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
10537 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
10540 if (Amount == 32) Amount = 0;
10543 if (isNarrow && !isMov)
10545 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10547 if (newOpc != ARM::t2RRX && !isMov)
10553 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10597 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10606 if (
Opc == ARM::MOVsi)
10627 case ARM::t2LDMIA_UPD: {
10643 case ARM::t2STMDB_UPD: {
10659 case ARM::LDMIA_UPD:
10662 if (
static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"pop" &&
10677 case ARM::STMDB_UPD:
10680 if (
static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"push" &&
10693 case ARM::t2ADDri12:
10694 case ARM::t2SUBri12:
10695 case ARM::t2ADDspImm12:
10696 case ARM::t2SUBspImm12: {
10699 const StringRef Token =
static_cast<ARMOperand &
>(*Operands[0]).
getToken();
10700 if ((Token !=
"add" && Token !=
"sub") ||
10704 case ARM::t2ADDri12:
10707 case ARM::t2SUBri12:
10710 case ARM::t2ADDspImm12:
10713 case ARM::t2SUBspImm12:
10728 Operands.size() == MnemonicOpsEndInd + 3) {
10739 Operands.size() == MnemonicOpsEndInd + 3) {
10745 case ARM::t2SUBri: {
10750 if (HasWideQualifier)
10757 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10763 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10764 ? MnemonicOpsEndInd + 1
10765 : MnemonicOpsEndInd + 2;
10766 MCParsedAsmOperand &
Op = *Operands[i];
10772 ARM::tADDi8 : ARM::tSUBi8);
10782 case ARM::t2ADDspImm:
10783 case ARM::t2SUBspImm: {
10788 if (V & 3 || V > ((1 << 7) - 1) << 2)
10801 case ARM::t2ADDrr: {
10863 case ARM::tLDMIA: {
10869 bool hasWritebackToken =
10870 (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
10872 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
10874 bool listContainsBase;
10876 (!listContainsBase && !hasWritebackToken) ||
10877 (listContainsBase && hasWritebackToken)) {
10880 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10883 if (hasWritebackToken)
10890 case ARM::tSTMIA_UPD: {
10895 bool listContainsBase;
10905 bool listContainsBase;
10919 bool listContainsBase;
10936 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10937 !HasWideQualifier) {
10958 !HasWideQualifier) {
10965 if (
Op == ARM::tMOVr) {
10983 !HasWideQualifier) {
10987 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
10988 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
10989 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
10990 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
11028 case ARM::ADDrsi: {
11034 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
11035 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
11036 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
11037 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
11038 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
11039 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
11062 assert(!inITBlock() &&
"nested IT blocks?!");
11078 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11079 !HasWideQualifier) {
11083 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
11084 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
11085 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
11086 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
11087 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
11088 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
11115 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11116 !HasWideQualifier) {
11120 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
11121 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
11122 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
11123 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
11142 case ARM::MVE_VPST:
11143 case ARM::MVE_VPTv16i8:
11144 case ARM::MVE_VPTv8i16:
11145 case ARM::MVE_VPTv4i32:
11146 case ARM::MVE_VPTv16u8:
11147 case ARM::MVE_VPTv8u16:
11148 case ARM::MVE_VPTv4u32:
11149 case ARM::MVE_VPTv16s8:
11150 case ARM::MVE_VPTv8s16:
11151 case ARM::MVE_VPTv4s32:
11152 case ARM::MVE_VPTv4f32:
11153 case ARM::MVE_VPTv8f16:
11154 case ARM::MVE_VPTv16i8r:
11155 case ARM::MVE_VPTv8i16r:
11156 case ARM::MVE_VPTv4i32r:
11157 case ARM::MVE_VPTv16u8r:
11158 case ARM::MVE_VPTv8u16r:
11159 case ARM::MVE_VPTv4u32r:
11160 case ARM::MVE_VPTv16s8r:
11161 case ARM::MVE_VPTv8s16r:
11162 case ARM::MVE_VPTv4s32r:
11163 case ARM::MVE_VPTv4f32r:
11164 case ARM::MVE_VPTv8f16r: {
11165 assert(!inVPTBlock() &&
"Nested VPT blocks are not allowed");
11167 VPTState.Mask = MO.
getImm();
11168 VPTState.CurPosition = 0;
11176ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11183 if (Operands[0]->isToken() &&
11184 static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"nop" &&
11185 ((
isThumb() && !isThumbOne()) || hasV6MOps())) {
11186 return Match_MnemonicFail;
11191 return Match_Success;
11195unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11199 const MCInstrDesc &MCID = MII.get(
Opc);
11202 "optionally flag setting instruction missing optional def operand");
11204 "operand count mismatch!");
11205 bool IsCPSR =
false;
11207 for (
unsigned OpNo = 0; OpNo < MCID.
NumOperands; ++OpNo) {
11208 if (MCID.
operands()[OpNo].isOptionalDef() &&
11215 if (isThumbOne() && !IsCPSR)
11216 return Match_RequiresFlagSetting;
11219 if (isThumbTwo() && !IsCPSR && !inITBlock())
11220 return Match_RequiresITBlock;
11221 if (isThumbTwo() && IsCPSR && inITBlock())
11222 return Match_RequiresNotITBlock;
11225 return Match_RequiresNotITBlock;
11226 }
else if (isThumbOne()) {
11229 if (
Opc == ARM::tADDhirr && !hasV6MOps() &&
11232 return Match_RequiresThumb2;
11234 else if (
Opc == ARM::tMOVr && !hasV6Ops() &&
11237 return Match_RequiresV6;
11243 if (
Opc == ARM::t2MOVr && !hasV8Ops())
11248 return Match_RequiresV8;
11253 return Match_RequiresV8;
11259 case ARM::VMRS_FPCXTS:
11260 case ARM::VMRS_FPCXTNS:
11261 case ARM::VMSR_FPCXTS:
11262 case ARM::VMSR_FPCXTNS:
11263 case ARM::VMRS_FPSCR_NZCVQC:
11264 case ARM::VMSR_FPSCR_NZCVQC:
11266 case ARM::VMRS_VPR:
11268 case ARM::VMSR_VPR:
11274 return Match_InvalidOperand;
11280 return Match_RequiresV8;
11288 return Match_InvalidTiedOperand;
11295 if (MCID.
operands()[
I].RegClass == ARM::rGPRRegClassID) {
11310 MCRegister
Reg =
Op.getReg();
11311 if ((
Reg == ARM::SP) && !hasV8Ops())
11312 return Match_RequiresV8;
11313 else if (
Reg == ARM::PC)
11314 return Match_InvalidOperand;
11317 return Match_Success;
11330bool ARMAsmParser::isITBlockTerminator(MCInst &Inst)
const {
11331 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11347unsigned ARMAsmParser::MatchInstruction(
OperandVector &Operands, MCInst &Inst,
11348 SmallVectorImpl<NearMissInfo> &NearMisses,
11349 bool MatchingInlineAsm,
11350 bool &EmitInITBlock,
11353 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11354 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11358 if (inImplicitITBlock()) {
11359 extendImplicitITBlock(ITState.Cond);
11360 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
11364 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11370 if (InstCond == ITCond) {
11371 EmitInITBlock =
true;
11372 return Match_Success;
11374 invertCurrentITCondition();
11375 EmitInITBlock =
true;
11376 return Match_Success;
11380 rewindImplicitITPosition();
11384 flushPendingInstructions(Out);
11385 unsigned PlainMatchResult =
11386 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11387 if (PlainMatchResult == Match_Success) {
11388 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11396 EmitInITBlock =
false;
11397 return Match_Success;
11400 EmitInITBlock =
false;
11401 return Match_Success;
11404 EmitInITBlock =
false;
11405 return Match_Success;
11412 startImplicitITBlock();
11413 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
11415 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11420 EmitInITBlock =
true;
11421 return Match_Success;
11424 discardImplicitITBlock();
11428 EmitInITBlock =
false;
11429 return PlainMatchResult;
11433 unsigned VariantID = 0);
11436bool ARMAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
11439 bool MatchingInlineAsm) {
11441 unsigned MatchResult;
11442 bool PendConditionalInstruction =
false;
11445 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11446 PendConditionalInstruction, Out);
11451 switch (MatchResult) {
11452 case Match_Success:
11459 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11462 forwardITPosition();
11463 forwardVPTPosition();
11472 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11481 forwardITPosition();
11482 forwardVPTPosition();
11490 if (PendConditionalInstruction) {
11491 PendingConditionalInsts.
push_back(Inst);
11492 if (isITBlockFull() || isITBlockTerminator(Inst))
11493 flushPendingInstructions(Out);
11498 case Match_NearMisses:
11499 ReportNearMisses(NearMisses, IDLoc, Operands);
11501 case Match_MnemonicFail: {
11502 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11504 ((ARMOperand &)*Operands[0]).
getToken(), FBS);
11505 return Error(IDLoc,
"invalid instruction" + Suggestion,
11506 ((ARMOperand &)*Operands[0]).getLocRange());
11514bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11520 if (IDVal ==
".word")
11521 parseLiteralValues(4, DirectiveID.
getLoc());
11522 else if (IDVal ==
".short" || IDVal ==
".hword")
11523 parseLiteralValues(2, DirectiveID.
getLoc());
11524 else if (IDVal ==
".thumb")
11525 parseDirectiveThumb(DirectiveID.
getLoc());
11526 else if (IDVal ==
".arm")
11527 parseDirectiveARM(DirectiveID.
getLoc());
11528 else if (IDVal ==
".thumb_func")
11529 parseDirectiveThumbFunc(DirectiveID.
getLoc());
11530 else if (IDVal ==
".code")
11531 parseDirectiveCode(DirectiveID.
getLoc());
11532 else if (IDVal ==
".syntax")
11533 parseDirectiveSyntax(DirectiveID.
getLoc());
11534 else if (IDVal ==
".unreq")
11535 parseDirectiveUnreq(DirectiveID.
getLoc());
11536 else if (IDVal ==
".fnend")
11537 parseDirectiveFnEnd(DirectiveID.
getLoc());
11538 else if (IDVal ==
".cantunwind")
11539 parseDirectiveCantUnwind(DirectiveID.
getLoc());
11540 else if (IDVal ==
".personality")
11541 parseDirectivePersonality(DirectiveID.
getLoc());
11542 else if (IDVal ==
".handlerdata")
11543 parseDirectiveHandlerData(DirectiveID.
getLoc());
11544 else if (IDVal ==
".setfp")
11545 parseDirectiveSetFP(DirectiveID.
getLoc());
11546 else if (IDVal ==
".pad")
11547 parseDirectivePad(DirectiveID.
getLoc());
11548 else if (IDVal ==
".save")
11549 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
11550 else if (IDVal ==
".vsave")
11551 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
11552 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
11553 parseDirectiveLtorg(DirectiveID.
getLoc());
11554 else if (IDVal ==
".even")
11555 parseDirectiveEven(DirectiveID.
getLoc());
11556 else if (IDVal ==
".personalityindex")
11557 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
11558 else if (IDVal ==
".unwind_raw")
11559 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
11560 else if (IDVal ==
".movsp")
11561 parseDirectiveMovSP(DirectiveID.
getLoc());
11562 else if (IDVal ==
".arch_extension")
11563 parseDirectiveArchExtension(DirectiveID.
getLoc());
11564 else if (IDVal ==
".align")
11565 return parseDirectiveAlign(DirectiveID.
getLoc());
11566 else if (IDVal ==
".thumb_set")
11567 parseDirectiveThumbSet(DirectiveID.
getLoc());
11568 else if (IDVal ==
".inst")
11569 parseDirectiveInst(DirectiveID.
getLoc());
11570 else if (IDVal ==
".inst.n")
11571 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
11572 else if (IDVal ==
".inst.w")
11573 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
11574 else if (!IsMachO && !IsCOFF) {
11575 if (IDVal ==
".arch")
11576 parseDirectiveArch(DirectiveID.
getLoc());
11577 else if (IDVal ==
".cpu")
11578 parseDirectiveCPU(DirectiveID.
getLoc());
11579 else if (IDVal ==
".eabi_attribute")
11580 parseDirectiveEabiAttr(DirectiveID.
getLoc());
11581 else if (IDVal ==
".fpu")
11582 parseDirectiveFPU(DirectiveID.
getLoc());
11583 else if (IDVal ==
".fnstart")
11584 parseDirectiveFnStart(DirectiveID.
getLoc());
11585 else if (IDVal ==
".object_arch")
11586 parseDirectiveObjectArch(DirectiveID.
getLoc());
11587 else if (IDVal ==
".tlsdescseq")
11588 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
11591 }
else if (IsCOFF) {
11592 if (IDVal ==
".seh_stackalloc")
11593 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
false);
11594 else if (IDVal ==
".seh_stackalloc_w")
11595 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
true);
11596 else if (IDVal ==
".seh_save_regs")
11597 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
false);
11598 else if (IDVal ==
".seh_save_regs_w")
11599 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
true);
11600 else if (IDVal ==
".seh_save_sp")
11601 parseDirectiveSEHSaveSP(DirectiveID.
getLoc());
11602 else if (IDVal ==
".seh_save_fregs")
11603 parseDirectiveSEHSaveFRegs(DirectiveID.
getLoc());
11604 else if (IDVal ==
".seh_save_lr")
11605 parseDirectiveSEHSaveLR(DirectiveID.
getLoc());
11606 else if (IDVal ==
".seh_endprologue")
11607 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
false);
11608 else if (IDVal ==
".seh_endprologue_fragment")
11609 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
true);
11610 else if (IDVal ==
".seh_nop")
11611 parseDirectiveSEHNop(DirectiveID.
getLoc(),
false);
11612 else if (IDVal ==
".seh_nop_w")
11613 parseDirectiveSEHNop(DirectiveID.
getLoc(),
true);
11614 else if (IDVal ==
".seh_startepilogue")
11615 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
false);
11616 else if (IDVal ==
".seh_startepilogue_cond")
11617 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
true);
11618 else if (IDVal ==
".seh_endepilogue")
11619 parseDirectiveSEHEpilogEnd(DirectiveID.
getLoc());
11620 else if (IDVal ==
".seh_custom")
11621 parseDirectiveSEHCustom(DirectiveID.
getLoc());
11633bool ARMAsmParser::parseLiteralValues(
unsigned Size, SMLoc L) {
11634 auto parseOne = [&]() ->
bool {
11635 const MCExpr *
Value;
11636 if (getParser().parseExpression(
Value))
11638 getParser().getStreamer().emitValue(
Value,
Size, L);
11641 return (parseMany(parseOne));
11646bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11647 if (parseEOL() || check(!hasThumb(), L,
"target does not support Thumb mode"))
11653 getTargetStreamer().emitCode16();
11654 getParser().getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
11660bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11661 if (parseEOL() || check(!hasARM(), L,
"target does not support ARM mode"))
11666 getTargetStreamer().emitCode32();
11667 getParser().getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
11671void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11674 flushPendingInstructions(getStreamer());
11677void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11678 if (NextSymbolIsThumb) {
11679 getTargetStreamer().emitThumbFunc(Symbol);
11680 NextSymbolIsThumb =
false;
11686bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11687 MCAsmParser &Parser = getParser();
11697 MCSymbol *
Func = getParser().getContext().getOrCreateSymbol(
11699 getTargetStreamer().emitThumbFunc(Func);
11714 getTargetStreamer().emitCode16();
11716 NextSymbolIsThumb =
true;
11722bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11723 MCAsmParser &Parser = getParser();
11724 const AsmToken &Tok = Parser.
getTok();
11726 Error(L,
"unexpected token in .syntax directive");
11732 if (check(
Mode ==
"divided" ||
Mode ==
"DIVIDED", L,
11733 "'.syntax divided' arm assembly not supported") ||
11734 check(
Mode !=
"unified" &&
Mode !=
"UNIFIED", L,
11735 "unrecognized syntax mode in .syntax directive") ||
11746bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11747 MCAsmParser &Parser = getParser();
11748 const AsmToken &Tok = Parser.
getTok();
11750 return Error(L,
"unexpected token in .code directive");
11752 if (Val != 16 && Val != 32) {
11753 Error(L,
"invalid operand to .code directive");
11763 return Error(L,
"target does not support Thumb mode");
11767 getTargetStreamer().emitCode16();
11770 return Error(L,
"target does not support ARM mode");
11774 getTargetStreamer().emitCode32();
11782bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11783 MCAsmParser &Parser = getParser();
11786 SMLoc SRegLoc, ERegLoc;
11787 const bool parseResult = parseRegister(
Reg, SRegLoc, ERegLoc);
11788 if (check(parseResult, SRegLoc,
"register name expected") || parseEOL())
11791 if (RegisterReqs.
insert(std::make_pair(Name,
Reg)).first->second !=
Reg)
11792 return Error(SRegLoc,
11793 "redefinition of '" + Name +
"' does not match original.");
11800bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11801 MCAsmParser &Parser = getParser();
11803 return Error(L,
"unexpected input in .unreq directive.");
11812void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb, SMLoc Loc) {
11814 if (WasThumb && hasThumb()) {
11817 }
else if (!WasThumb && hasARM()) {
11823 getTargetStreamer().emitCode16();
11825 getTargetStreamer().emitCode32();
11829 Warning(Loc, Twine(
"new target does not support ") +
11830 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
11831 (!WasThumb ?
"thumb" :
"arm") +
" mode");
11838bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11839 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11842 if (
ID == ARM::ArchKind::INVALID)
11843 return Error(L,
"Unknown arch name");
11846 MCSubtargetInfo &STI = copySTI();
11849 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11850 FixModeAfterArchChange(WasThumb, L);
11852 getTargetStreamer().emitArch(
ID);
11859bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11860 MCAsmParser &Parser = getParser();
11869 Error(TagLoc,
"attribute name not recognised: " + Name);
11875 const MCExpr *AttrExpr;
11882 if (check(!CE, TagLoc,
"expected numeric constant"))
11885 Tag =
CE->getValue();
11891 StringRef StringValue =
"";
11892 bool IsStringValue =
false;
11894 int64_t IntegerValue = 0;
11895 bool IsIntegerValue =
false;
11898 IsStringValue =
true;
11900 IsStringValue =
true;
11901 IsIntegerValue =
true;
11902 }
else if (
Tag < 32 ||
Tag % 2 == 0)
11903 IsIntegerValue =
true;
11904 else if (
Tag % 2 == 1)
11905 IsStringValue =
true;
11909 if (IsIntegerValue) {
11910 const MCExpr *ValueExpr;
11917 return Error(ValueExprLoc,
"expected numeric constant");
11918 IntegerValue =
CE->getValue();
11926 std::string EscapedValue;
11927 if (IsStringValue) {
11935 StringValue = EscapedValue;
11945 if (IsIntegerValue && IsStringValue) {
11947 getTargetStreamer().emitIntTextAttribute(
Tag, IntegerValue, StringValue);
11948 }
else if (IsIntegerValue)
11949 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
11950 else if (IsStringValue)
11951 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
11957bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11958 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11963 if (!getSTI().isCPUStringValid(CPU))
11964 return Error(L,
"Unknown CPU name");
11967 MCSubtargetInfo &STI = copySTI();
11969 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11970 FixModeAfterArchChange(WasThumb, L);
11977bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11978 SMLoc FPUNameLoc = getTok().getLoc();
11979 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11982 std::vector<StringRef> Features;
11984 return Error(FPUNameLoc,
"Unknown FPU name");
11986 MCSubtargetInfo &STI = copySTI();
11987 for (
auto Feature : Features)
11989 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11991 getTargetStreamer().emitFPU(
ID);
11997bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
12001 if (UC.hasFnStart()) {
12002 Error(L,
".fnstart starts before the end of previous one");
12003 UC.emitFnStartLocNotes();
12010 getTargetStreamer().emitFnStart();
12012 UC.recordFnStart(L);
12018bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12022 if (!UC.hasFnStart())
12023 return Error(L,
".fnstart must precede .fnend directive");
12026 getTargetStreamer().emitFnEnd();
12034bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12038 UC.recordCantUnwind(L);
12040 if (check(!UC.hasFnStart(), L,
".fnstart must precede .cantunwind directive"))
12043 if (UC.hasHandlerData()) {
12044 Error(L,
".cantunwind can't be used with .handlerdata directive");
12045 UC.emitHandlerDataLocNotes();
12048 if (UC.hasPersonality()) {
12049 Error(L,
".cantunwind can't be used with .personality directive");
12050 UC.emitPersonalityLocNotes();
12054 getTargetStreamer().emitCantUnwind();
12060bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12061 MCAsmParser &Parser = getParser();
12062 bool HasExistingPersonality = UC.hasPersonality();
12066 return Error(L,
"unexpected input in .personality directive.");
12073 UC.recordPersonality(L);
12076 if (!UC.hasFnStart())
12077 return Error(L,
".fnstart must precede .personality directive");
12078 if (UC.cantUnwind()) {
12079 Error(L,
".personality can't be used with .cantunwind directive");
12080 UC.emitCantUnwindLocNotes();
12083 if (UC.hasHandlerData()) {
12084 Error(L,
".personality must precede .handlerdata directive");
12085 UC.emitHandlerDataLocNotes();
12088 if (HasExistingPersonality) {
12089 Error(L,
"multiple personality directives");
12090 UC.emitPersonalityLocNotes();
12094 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12095 getTargetStreamer().emitPersonality(PR);
12101bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12105 UC.recordHandlerData(L);
12107 if (!UC.hasFnStart())
12108 return Error(L,
".fnstart must precede .personality directive");
12109 if (UC.cantUnwind()) {
12110 Error(L,
".handlerdata can't be used with .cantunwind directive");
12111 UC.emitCantUnwindLocNotes();
12115 getTargetStreamer().emitHandlerData();
12121bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12122 MCAsmParser &Parser = getParser();
12124 if (check(!UC.hasFnStart(), L,
".fnstart must precede .setfp directive") ||
12125 check(UC.hasHandlerData(), L,
12126 ".setfp must precede .handlerdata directive"))
12131 MCRegister
FPReg = tryParseRegister();
12133 if (check(!
FPReg, FPRegLoc,
"frame pointer register expected") ||
12139 MCRegister
SPReg = tryParseRegister();
12140 if (check(!
SPReg, SPRegLoc,
"stack pointer register expected") ||
12141 check(
SPReg != ARM::SP &&
SPReg != UC.getFPReg(), SPRegLoc,
12142 "register should be either $sp or the latest fp register"))
12146 UC.saveFPReg(
FPReg);
12156 const MCExpr *OffsetExpr;
12159 if (getParser().parseExpression(OffsetExpr, EndLoc))
12160 return Error(ExLoc,
"malformed setfp offset");
12162 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
12176bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12177 MCAsmParser &Parser = getParser();
12179 if (!UC.hasFnStart())
12180 return Error(L,
".fnstart must precede .pad directive");
12181 if (UC.hasHandlerData())
12182 return Error(L,
".pad must precede .handlerdata directive");
12190 const MCExpr *OffsetExpr;
12193 if (getParser().parseExpression(OffsetExpr, EndLoc))
12194 return Error(ExLoc,
"malformed pad offset");
12197 return Error(ExLoc,
"pad offset must be an immediate");
12202 getTargetStreamer().emitPad(
CE->getValue());
12209bool ARMAsmParser::parseDirectiveRegSave(SMLoc L,
bool IsVector) {
12211 if (!UC.hasFnStart())
12212 return Error(L,
".fnstart must precede .save or .vsave directives");
12213 if (UC.hasHandlerData())
12214 return Error(L,
".save or .vsave must precede .handlerdata directive");
12220 if (parseRegisterList(Operands,
true,
true) || parseEOL())
12222 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12223 if (!IsVector && !
Op.isRegList())
12224 return Error(L,
".save expects GPR registers");
12225 if (IsVector && !
Op.isDPRRegList())
12226 return Error(L,
".vsave expects DPR registers");
12228 getTargetStreamer().emitRegSave(
Op.getRegList(), IsVector);
12236bool ARMAsmParser::parseDirectiveInst(SMLoc Loc,
char Suffix) {
12252 return Error(Loc,
"width suffixes are invalid in ARM mode");
12255 auto parseOne = [&]() ->
bool {
12256 const MCExpr *Expr;
12257 if (getParser().parseExpression(Expr))
12261 return Error(Loc,
"expected constant expression");
12264 char CurSuffix = Suffix;
12267 if (
Value->getValue() > 0xffff)
12268 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
12271 if (
Value->getValue() > 0xffffffff)
12272 return Error(Loc, StringRef(Suffix ?
"inst.w" :
"inst") +
12273 " operand is too big");
12277 if (
Value->getValue() < 0xe800)
12279 else if (
Value->getValue() >= 0xe8000000)
12282 return Error(Loc,
"cannot determine Thumb instruction size, "
12283 "use inst.n/inst.w instead");
12289 getTargetStreamer().emitInst(
Value->getValue(), CurSuffix);
12290 forwardITPosition();
12291 forwardVPTPosition();
12296 return Error(Loc,
"expected expression following directive");
12297 if (parseMany(parseOne))
12304bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12307 getTargetStreamer().emitCurrentConstantPool();
12311bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12312 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12318 getStreamer().initSections(getSTI());
12319 Section = getStreamer().getCurrentSectionOnly();
12322 assert(Section &&
"must have section to emit alignment");
12323 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12324 getStreamer().emitCodeAlignment(
Align(2), getSTI());
12326 getStreamer().emitValueToAlignment(
Align(2));
12333bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12334 MCAsmParser &Parser = getParser();
12335 bool HasExistingPersonality = UC.hasPersonality();
12337 const MCExpr *IndexExpression;
12343 UC.recordPersonalityIndex(L);
12345 if (!UC.hasFnStart()) {
12346 return Error(L,
".fnstart must precede .personalityindex directive");
12348 if (UC.cantUnwind()) {
12349 Error(L,
".personalityindex cannot be used with .cantunwind");
12350 UC.emitCantUnwindLocNotes();
12353 if (UC.hasHandlerData()) {
12354 Error(L,
".personalityindex must precede .handlerdata directive");
12355 UC.emitHandlerDataLocNotes();
12358 if (HasExistingPersonality) {
12359 Error(L,
"multiple personality directives");
12360 UC.emitPersonalityLocNotes();
12366 return Error(IndexLoc,
"index must be a constant number");
12368 return Error(IndexLoc,
12369 "personality routine index should be in range [0-3]");
12371 getTargetStreamer().emitPersonalityIndex(
CE->getValue());
12377bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12378 MCAsmParser &Parser = getParser();
12379 int64_t StackOffset;
12380 const MCExpr *OffsetExpr;
12381 SMLoc OffsetLoc = getLexer().
getLoc();
12383 if (!UC.hasFnStart())
12384 return Error(L,
".fnstart must precede .unwind_raw directives");
12385 if (getParser().parseExpression(OffsetExpr))
12386 return Error(OffsetLoc,
"expected expression");
12390 return Error(OffsetLoc,
"offset must be a constant");
12392 StackOffset =
CE->getValue();
12399 auto parseOne = [&]() ->
bool {
12400 const MCExpr *OE =
nullptr;
12401 SMLoc OpcodeLoc = getLexer().getLoc();
12404 OpcodeLoc,
"expected opcode expression"))
12408 return Error(OpcodeLoc,
"opcode value must be a constant");
12409 const int64_t Opcode = OC->
getValue();
12410 if (Opcode & ~0xff)
12411 return Error(OpcodeLoc,
"invalid opcode");
12417 SMLoc OpcodeLoc = getLexer().getLoc();
12419 return Error(OpcodeLoc,
"expected opcode expression");
12420 if (parseMany(parseOne))
12423 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12429bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12430 MCAsmParser &Parser = getParser();
12433 return TokError(
"expected variable after '.tlsdescseq' directive");
12443 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12449bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12450 MCAsmParser &Parser = getParser();
12451 if (!UC.hasFnStart())
12452 return Error(L,
".fnstart must precede .movsp directives");
12453 if (UC.getFPReg() != ARM::SP)
12454 return Error(L,
"unexpected .movsp directive");
12457 MCRegister
SPReg = tryParseRegister();
12459 return Error(SPRegLoc,
"register expected");
12461 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
12468 const MCExpr *OffsetExpr;
12472 return Error(OffsetLoc,
"malformed offset expression");
12476 return Error(OffsetLoc,
"offset must be an immediate constant");
12485 UC.saveFPReg(
SPReg);
12492bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12493 MCAsmParser &Parser = getParser();
12495 return Error(getLexer().getLoc(),
"unexpected token");
12503 if (
ID == ARM::ArchKind::INVALID)
12504 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
12508 getTargetStreamer().emitObjectArch(
ID);
12514bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12519 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12520 assert(Section &&
"must have section to emit alignment");
12521 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12522 getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
12524 getStreamer().emitValueToAlignment(
Align(4), 0, 1, 0);
12532bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12533 MCAsmParser &Parser = getParser();
12537 "expected identifier after '.thumb_set'") ||
12542 const MCExpr *
Value;
12544 Parser, Sym,
Value))
12547 getTargetStreamer().emitThumbSet(Sym,
Value);
12554bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L,
bool Wide) {
12556 if (parseImmExpr(
Size))
12558 getTargetStreamer().emitARMWinCFIAllocStack(
Size, Wide);
12565bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L,
bool Wide) {
12568 if (parseRegisterList(Operands) || parseEOL())
12570 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12571 if (!
Op.isRegList())
12572 return Error(L,
".seh_save_regs{_w} expects GPR registers");
12573 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12575 for (
size_t i = 0; i < RegList.
size(); ++i) {
12580 return Error(L,
".seh_save_regs{_w} can't include SP");
12581 assert(
Reg < 16U &&
"Register out of range");
12582 unsigned Bit = (1u <<
Reg);
12585 if (!Wide && (Mask & 0x1f00) != 0)
12587 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12588 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12594bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12595 MCRegister
Reg = tryParseRegister();
12597 return Error(L,
"expected GPR");
12599 if (Index > 14 || Index == 13)
12600 return Error(L,
"invalid register for .seh_save_sp");
12601 getTargetStreamer().emitARMWinCFISaveSP(Index);
12607bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12610 if (parseRegisterList(Operands) || parseEOL())
12612 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12613 if (!
Op.isDPRRegList())
12614 return Error(L,
".seh_save_fregs expects DPR registers");
12615 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12617 for (
size_t i = 0; i < RegList.
size(); ++i) {
12619 assert(
Reg < 32U &&
"Register out of range");
12620 unsigned Bit = (1u <<
Reg);
12625 return Error(L,
".seh_save_fregs missing registers");
12627 unsigned First = 0;
12628 while ((Mask & 1) == 0) {
12632 if (((Mask + 1) & Mask) != 0)
12634 ".seh_save_fregs must take a contiguous range of registers");
12636 while ((Mask & 2) != 0) {
12641 return Error(L,
".seh_save_fregs must be all d0-d15 or d16-d31");
12642 getTargetStreamer().emitARMWinCFISaveFRegs(
First,
Last);
12648bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12650 if (parseImmExpr(
Offset))
12652 getTargetStreamer().emitARMWinCFISaveLR(
Offset);
12659bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L,
bool Fragment) {
12660 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12667bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L,
bool Wide) {
12668 getTargetStreamer().emitARMWinCFINop(Wide);
12675bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L,
bool Condition) {
12678 MCAsmParser &Parser = getParser();
12680 const AsmToken &Tok = Parser.
getTok();
12682 return Error(S,
".seh_startepilogue_cond missing condition");
12685 return Error(S,
"invalid condition");
12689 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12695bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12696 getTargetStreamer().emitARMWinCFIEpilogEnd();
12702bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12703 unsigned Opcode = 0;
12706 if (parseImmExpr(Byte))
12708 if (Byte > 0xff || Byte < 0)
12709 return Error(L,
"Invalid byte value in .seh_custom");
12710 if (Opcode > 0x00ffffff)
12711 return Error(L,
"Too many bytes in .seh_custom");
12714 Opcode = (Opcode << 8) | Byte;
12716 getTargetStreamer().emitARMWinCFICustom(Opcode);
12728#define GET_REGISTER_MATCHER
12729#define GET_SUBTARGET_FEATURE_NAME
12730#define GET_MATCHER_IMPLEMENTATION
12731#define GET_MNEMONIC_SPELL_CHECKER
12732#include "ARMGenAsmMatcher.inc"
12738ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12739 switch (MatchError) {
12742 return hasV8Ops() ?
"operand must be a register in range [r0, r14]"
12743 :
"operand must be a register in range [r0, r12] or r14";
12746 return hasD32() ?
"operand must be a register in range [d0, d31]"
12747 :
"operand must be a register in range [d0, d15]";
12748 case Match_DPR_RegList:
12749 return hasD32() ?
"operand must be a list of registers in range [d0, d31]"
12750 :
"operand must be a list of registers in range [d0, d15]";
12754 return getMatchKindDiag(MatchError);
12762ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12763 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12777 std::multimap<unsigned, unsigned> OperandMissesSeen;
12778 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12779 bool ReportedTooFewOperands =
false;
12785 for (NearMissInfo &
I :
reverse(NearMissesIn)) {
12786 switch (
I.getKind()) {
12789 ((ARMOperand &)*Operands[
I.getOperandIndex()]).getStartLoc();
12790 const char *OperandDiag =
12791 getCustomOperandDiag((ARMMatchResultTy)
I.getOperandError());
12798 unsigned DupCheckMatchClass = OperandDiag ?
I.getOperandClass() : ~0
U;
12799 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
12800 if (std::any_of(PrevReports.first, PrevReports.second,
12801 [DupCheckMatchClass](
12802 const std::pair<unsigned, unsigned> Pair) {
12803 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12804 return Pair.second == DupCheckMatchClass;
12806 return isSubclass((MatchClassKind)DupCheckMatchClass,
12807 (MatchClassKind)Pair.second);
12810 OperandMissesSeen.insert(
12811 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
12813 NearMissMessage Message;
12814 Message.Loc = OperandLoc;
12816 Message.Message = OperandDiag;
12817 }
else if (
I.getOperandClass() == InvalidMatchClass) {
12818 Message.Message =
"too many operands for instruction";
12820 Message.Message =
"invalid operand for instruction";
12822 dbgs() <<
"Missing diagnostic string for operand class "
12823 << getMatchClassName((MatchClassKind)
I.getOperandClass())
12824 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
12825 <<
", opcode " << MII.getName(
I.getOpcode()) <<
"\n");
12831 const FeatureBitset &MissingFeatures =
I.getFeatures();
12833 if (FeatureMissesSeen.
count(MissingFeatures))
12835 FeatureMissesSeen.
insert(MissingFeatures);
12839 if (MissingFeatures.
test(Feature_IsARMBit) && !hasARM())
12843 if (
isThumb() && MissingFeatures.
test(Feature_IsARMBit) &&
12844 MissingFeatures.
count() > 1)
12846 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumbBit) &&
12847 MissingFeatures.
count() > 1)
12849 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumb2Bit) &&
12850 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12851 Feature_IsThumbBit})).any())
12853 if (isMClass() && MissingFeatures.
test(Feature_HasNEONBit))
12856 NearMissMessage Message;
12857 Message.Loc = IDLoc;
12858 raw_svector_ostream OS(Message.Message);
12860 OS <<
"instruction requires:";
12861 for (
unsigned Feature : MissingFeatures)
12869 NearMissMessage Message;
12870 Message.Loc = IDLoc;
12871 switch (
I.getPredicateError()) {
12872 case Match_RequiresNotITBlock:
12873 Message.Message =
"flag setting instruction only valid outside IT block";
12875 case Match_RequiresITBlock:
12876 Message.Message =
"instruction only valid inside IT block";
12878 case Match_RequiresV6:
12879 Message.Message =
"instruction variant requires ARMv6 or later";
12881 case Match_RequiresThumb2:
12882 Message.Message =
"instruction variant requires Thumb2";
12884 case Match_RequiresV8:
12885 Message.Message =
"instruction variant requires ARMv8 or later";
12887 case Match_RequiresFlagSetting:
12888 Message.Message =
"no flag-preserving variant of this instruction available";
12890 case Match_InvalidTiedOperand: {
12891 ARMOperand &
Op =
static_cast<ARMOperand &
>(*Operands[0]);
12892 if (
Op.isToken() &&
Op.getToken() ==
"mul") {
12893 Message.Message =
"destination register must match a source register";
12894 Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc();
12900 case Match_InvalidOperand:
12901 Message.Message =
"invalid operand for instruction";
12911 if (!ReportedTooFewOperands) {
12912 SMLoc EndLoc = ((ARMOperand &)*Operands.
back()).getEndLoc();
12914 EndLoc, StringRef(
"too few operands for instruction")});
12915 ReportedTooFewOperands =
true;
12927void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12930 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
12935 Error(IDLoc,
"invalid instruction");
12936 }
else if (
Messages.size() == 1) {
12938 Error(Messages[0].Loc, Messages[0].Message);
12942 Error(IDLoc,
"invalid instruction, any one of the following would fix this:");
12943 for (
auto &M : Messages) {
12949bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12953 static const struct {
12954 const uint64_t
Kind;
12955 const FeatureBitset ArchCheck;
12956 const FeatureBitset Features;
12958 {
ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12960 {Feature_HasV8Bit},
12961 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12963 {Feature_HasV8Bit},
12964 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12966 {Feature_HasV8Bit},
12967 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12969 {Feature_HasV8_1MMainlineBit},
12970 {ARM::HasMVEFloatOps}},
12972 {Feature_HasV8Bit},
12973 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12975 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12976 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12978 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12981 {Feature_HasV8Bit},
12982 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12983 {
ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12985 {
ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12987 {Feature_HasV8_2aBit},
12988 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12989 {
ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12990 {
ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12991 {
ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12999 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
13002 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13009 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
13012 return Error(ExtLoc,
"architectural extension '" + Name +
13014 "allowed for the current base architecture");
13016 MCSubtargetInfo &STI = copySTI();
13017 if (EnableFeature) {
13022 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
13023 setAvailableFeatures(Features);
13031bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13033 MCAsmParser &Parser = getParser();
13036 return Error(getLexer().getLoc(),
"expected architecture extension name");
13045 if (Name ==
"nocrypto") {
13046 enableArchExtFeature(
"nosha2", ExtLoc);
13047 enableArchExtFeature(
"noaes", ExtLoc);
13050 if (enableArchExtFeature(Name, ExtLoc))
13053 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13058unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13060 ARMOperand &
Op =
static_cast<ARMOperand &
>(AsmOp);
13069 if (
CE->getValue() == 0)
13070 return Match_Success;
13075 if (
CE->getValue() == 8)
13076 return Match_Success;
13081 if (
CE->getValue() == 16)
13082 return Match_Success;
13086 const MCExpr *SOExpr =
Op.getImm();
13088 if (!SOExpr->evaluateAsAbsolute(
Value))
13089 return Match_Success;
13090 assert((
Value >= std::numeric_limits<int32_t>::min() &&
13091 Value <= std::numeric_limits<uint32_t>::max()) &&
13092 "expression value must be representable in 32 bits");
13096 if (hasV8Ops() &&
Op.isReg() &&
Op.getReg() == ARM::SP)
13097 return Match_Success;
13100 return Match_InvalidOperand;
13103bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13104 StringRef ExtraToken) {
13108 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13109 (Mnemonic.
starts_with(
"vldrh") && Mnemonic !=
"vldrhi") ||
13111 !(ExtraToken ==
".f16" || ExtraToken ==
".32" || ExtraToken ==
".16" ||
13112 ExtraToken ==
".8")) ||
13113 (Mnemonic.
starts_with(
"vrint") && Mnemonic !=
"vrintr") ||
13114 (Mnemonic.
starts_with(
"vstrh") && Mnemonic !=
"vstrhi"))
13117 const char *predicable_prefixes[] = {
13118 "vabav",
"vabd",
"vabs",
"vadc",
"vadd",
13119 "vaddlv",
"vaddv",
"vand",
"vbic",
"vbrsr",
13120 "vcadd",
"vcls",
"vclz",
"vcmla",
"vcmp",
13121 "vcmul",
"vctp",
"vcvt",
"vddup",
"vdup",
13122 "vdwdup",
"veor",
"vfma",
"vfmas",
"vfms",
13123 "vhadd",
"vhcadd",
"vhsub",
"vidup",
"viwdup",
13124 "vldrb",
"vldrd",
"vldrw",
"vmax",
"vmaxa",
13125 "vmaxav",
"vmaxnm",
"vmaxnma",
"vmaxnmav",
"vmaxnmv",
13126 "vmaxv",
"vmin",
"vminav",
"vminnm",
"vminnmav",
13127 "vminnmv",
"vminv",
"vmla",
"vmladav",
"vmlaldav",
13128 "vmlalv",
"vmlas",
"vmlav",
"vmlsdav",
"vmlsldav",
13129 "vmovlb",
"vmovlt",
"vmovnb",
"vmovnt",
"vmul",
13130 "vmvn",
"vneg",
"vorn",
"vorr",
"vpnot",
13131 "vpsel",
"vqabs",
"vqadd",
"vqdmladh",
"vqdmlah",
13132 "vqdmlash",
"vqdmlsdh",
"vqdmulh",
"vqdmull",
"vqmovn",
13133 "vqmovun",
"vqneg",
"vqrdmladh",
"vqrdmlah",
"vqrdmlash",
13134 "vqrdmlsdh",
"vqrdmulh",
"vqrshl",
"vqrshrn",
"vqrshrun",
13135 "vqshl",
"vqshrn",
"vqshrun",
"vqsub",
"vrev16",
13136 "vrev32",
"vrev64",
"vrhadd",
"vrmlaldavh",
"vrmlalvh",
13137 "vrmlsldavh",
"vrmulh",
"vrshl",
"vrshr",
"vrshrn",
13138 "vsbc",
"vshl",
"vshlc",
"vshll",
"vshr",
13139 "vshrn",
"vsli",
"vsri",
"vstrb",
"vstrd",
13142 return any_of(predicable_prefixes, [&Mnemonic](
const char *prefix) {
13147std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13148 return ARMOperand::CreateCondCode(
ARMCC::AL, SMLoc(), *
this);
13151std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13152 return ARMOperand::CreateCCOut(0, SMLoc(), *
this);
13155std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13156 return ARMOperand::CreateVPTPred(
ARMVCC::None, SMLoc(), *
this);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
static bool instIsBreakpoint(const MCInst &Inst)
unsigned findCCOutInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isDataTypeToken(StringRef Tok)
}
static MCRegister getNextRegister(MCRegister Reg)
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
unsigned getRegListInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isVectorPredicable(const MCInstrDesc &MCID)
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg)
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, MCRegister Reg, MCRegister HiReg, bool &containsReg)
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmParser()
Force static initialization.
static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID)
static bool isThumbI8Relocation(MCParsedAsmOperand &MCOp)
bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool insertNoDuplicates(SmallVectorImpl< std::pair< unsigned, MCRegister > > &Regs, unsigned Enc, MCRegister Reg)
static unsigned getMnemonicOpsEndInd(const OperandVector &Operands)
static bool isARMMCExpr(MCParsedAsmOperand &MCOp)
unsigned findCondCodeInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool isThumb(const MCSubtargetInfo &STI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Register getFPReg(const CSKYSubtarget &STI)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_EXTERNAL_VISIBILITY
static cl::opt< bool > AddBuildAttributes("hexagon-add-build-attributes")
Value * getPointer(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool containsReg(SmallSetVector< Register, 32 > LocalDefsV, const BitVector &LocalDefsP, Register Reg, const TargetRegisterInfo *TRI)
Check if target reg is contained in given lists, which are: LocalDefsV as given list for virtual regs...
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Pre allocate WWM Registers
static cl::opt< ExtensionSet, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Implements a dense probed hash-table based set.
Base class for user error types.
Container class for subtarget features.
constexpr bool test(unsigned I) const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range={})=0
Emit a note at the location L, with the message Msg.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ Constant
Constant expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const FeatureBitset & ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
MCStreamer & getStreamer()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
static constexpr size_t npos
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
LLVM_ABI std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
LLVM_ABI const TagNameMap & getARMAttributeTags()
static CondCodes getOppositeCondition(CondCodes CC)
unsigned getSORegOffset(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
unsigned encodeNEONi16splat(unsigned Value)
float getFPImmFloat(unsigned Imm)
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO, unsigned IdxMode=0)
unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
ShiftOpc getSORegShOp(unsigned Op)
bool isNEONi16splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getAM5FP16Opc(AddrOpc Opc, unsigned char Offset)
getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset, unsigned IdxMode=0)
getAM3Opc - This function encodes the addrmode3 opc field.
bool isNEONi32splat(unsigned Value)
Checks if Value is a correct immediate for instructions like VBIC/VORR.
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
StringRef getShiftOpcStr(ShiftOpc Op)
unsigned encodeNEONi32splat(unsigned Value)
Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
static const char * IFlagsToString(unsigned val)
LLVM_ABI bool getFPUFeatures(FPUKind FPUKind, std::vector< StringRef > &Features)
LLVM_ABI StringRef getArchName(ArchKind AK)
LLVM_ABI uint64_t parseArchExt(StringRef ArchExt)
LLVM_ABI ArchKind parseArch(StringRef Arch)
bool isVpred(OperandType op)
LLVM_ABI FPUKind parseFPU(StringRef FPU)
bool isCDECoproc(size_t Coproc, const MCSubtargetInfo &STI)
@ D16
Only 16 D registers.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
LLVM_ABI 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.
@ CE
Windows NT (Windows on ARM)
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
static const char * ARMVPTPredToString(ARMVCC::VPTCodes CC)
constexpr T rotr(T V, int R)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Target & getTheThumbBETarget()
static unsigned ARMCondCodeFromString(StringRef CC)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
@ Never
Never set the bit.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool IsCPSRDead< MCInst >(const MCInst *Instr)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
static bool isValidCoprocessorNumber(unsigned Num, const FeatureBitset &featureBits)
isValidCoprocessorNumber - decide whether an explicit coprocessor number is legal in generic instruct...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static unsigned ARMVectorCondCodeFromString(StringRef CC)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
@ Always
Always emit .debug_str_offsets talbes as DWARF64 for testing.
Target & getTheARMLETarget()
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...