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 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
Reg.RegNum);
1381 bool isQReg()
const {
1383 ARMMCRegisterClasses[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 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum) &&
1401 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(Memory.BaseRegNum))
1403 if (Memory.OffsetRegNum &&
1404 !ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
1405 Memory.OffsetRegNum))
1409 bool isGPRMem()
const {
1410 if (Kind != k_Memory)
1412 if (Memory.BaseRegNum &&
1413 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
1415 if (Memory.OffsetRegNum &&
1416 !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum))
1420 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1421 bool isRegShiftedReg()
const {
1422 return Kind == k_ShiftedRegister &&
1423 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1424 RegShiftedReg.SrcReg) &&
1425 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1426 RegShiftedReg.ShiftReg);
1428 bool isRegShiftedImm()
const {
1429 return Kind == k_ShiftedImmediate &&
1430 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
1431 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 ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
1485 bool isPostIdxReg()
const {
1488 bool isMemNoOffset(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1492 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1493 (alignOK || Memory.Alignment == Alignment);
1495 bool isMemNoOffsetT2(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1499 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1504 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1505 (alignOK || Memory.Alignment == Alignment);
1507 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1511 if (!ARMMCRegisterClasses[ARM::rGPRRegClassID].
contains(
1516 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1517 (alignOK || Memory.Alignment == Alignment);
1519 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1523 if (!ARMMCRegisterClasses[ARM::tGPRRegClassID].
contains(
1528 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1529 (alignOK || Memory.Alignment == Alignment);
1531 bool isMemPCRelImm12()
const {
1532 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1535 if (Memory.BaseRegNum != ARM::PC)
1538 if (!Memory.OffsetImm)
return true;
1540 int64_t Val =
CE->getValue();
1541 return (Val > -4096 && Val < 4096) ||
1542 (Val == std::numeric_limits<int32_t>::min());
1547 bool isAlignedMemory()
const {
1548 return isMemNoOffset(
true);
1551 bool isAlignedMemoryNone()
const {
1552 return isMemNoOffset(
false, 0);
1555 bool isDupAlignedMemoryNone()
const {
1556 return isMemNoOffset(
false, 0);
1559 bool isAlignedMemory16()
const {
1560 if (isMemNoOffset(
false, 2))
1562 return isMemNoOffset(
false, 0);
1565 bool isDupAlignedMemory16()
const {
1566 if (isMemNoOffset(
false, 2))
1568 return isMemNoOffset(
false, 0);
1571 bool isAlignedMemory32()
const {
1572 if (isMemNoOffset(
false, 4))
1574 return isMemNoOffset(
false, 0);
1577 bool isDupAlignedMemory32()
const {
1578 if (isMemNoOffset(
false, 4))
1580 return isMemNoOffset(
false, 0);
1583 bool isAlignedMemory64()
const {
1584 if (isMemNoOffset(
false, 8))
1586 return isMemNoOffset(
false, 0);
1589 bool isDupAlignedMemory64()
const {
1590 if (isMemNoOffset(
false, 8))
1592 return isMemNoOffset(
false, 0);
1595 bool isAlignedMemory64or128()
const {
1596 if (isMemNoOffset(
false, 8))
1598 if (isMemNoOffset(
false, 16))
1600 return isMemNoOffset(
false, 0);
1603 bool isDupAlignedMemory64or128()
const {
1604 if (isMemNoOffset(
false, 8))
1606 if (isMemNoOffset(
false, 16))
1608 return isMemNoOffset(
false, 0);
1611 bool isAlignedMemory64or128or256()
const {
1612 if (isMemNoOffset(
false, 8))
1614 if (isMemNoOffset(
false, 16))
1616 if (isMemNoOffset(
false, 32))
1618 return isMemNoOffset(
false, 0);
1621 bool isAddrMode2()
const {
1622 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1624 if (Memory.OffsetRegNum)
return true;
1626 if (!Memory.OffsetImm)
return true;
1628 int64_t Val =
CE->getValue();
1629 return Val > -4096 && Val < 4096;
1634 bool isAM2OffsetImm()
const {
1635 if (!isImm())
return false;
1638 if (!CE)
return false;
1639 int64_t Val =
CE->getValue();
1640 return (Val == std::numeric_limits<int32_t>::min()) ||
1641 (Val > -4096 && Val < 4096);
1644 bool isAddrMode3()
const {
1650 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1654 if (Memory.OffsetRegNum)
return true;
1656 if (!Memory.OffsetImm)
return true;
1658 int64_t Val =
CE->getValue();
1661 return (Val > -256 && Val < 256) ||
1662 Val == std::numeric_limits<int32_t>::min();
1667 bool isAM3Offset()
const {
1674 if (!CE)
return false;
1675 int64_t Val =
CE->getValue();
1677 return (Val > -256 && Val < 256) ||
1678 Val == std::numeric_limits<int32_t>::min();
1681 bool isAddrMode5()
const {
1687 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1689 if (Memory.OffsetRegNum)
return false;
1691 if (!Memory.OffsetImm)
return true;
1693 int64_t Val =
CE->getValue();
1694 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1695 Val == std::numeric_limits<int32_t>::min();
1700 bool isAddrMode5FP16()
const {
1706 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1708 if (Memory.OffsetRegNum)
return false;
1710 if (!Memory.OffsetImm)
return true;
1712 int64_t Val =
CE->getValue();
1713 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1714 Val == std::numeric_limits<int32_t>::min();
1719 bool isMemTBB()
const {
1720 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1726 bool isMemTBH()
const {
1727 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1728 Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm != 1 ||
1729 Memory.Alignment != 0 )
1734 bool isMemRegOffset()
const {
1735 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1740 bool isT2MemRegOffset()
const {
1741 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1742 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1747 if (Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm > 3)
1752 bool isMemThumbRR()
const {
1755 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1762 bool isMemThumbRIs4()
const {
1763 if (!isGPRMem() || Memory.OffsetRegNum ||
1767 if (!Memory.OffsetImm)
return true;
1769 int64_t Val =
CE->getValue();
1770 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1775 bool isMemThumbRIs2()
const {
1776 if (!isGPRMem() || Memory.OffsetRegNum ||
1780 if (!Memory.OffsetImm)
return true;
1782 int64_t Val =
CE->getValue();
1783 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1788 bool isMemThumbRIs1()
const {
1789 if (!isGPRMem() || Memory.OffsetRegNum ||
1793 if (!Memory.OffsetImm)
return true;
1795 int64_t Val =
CE->getValue();
1796 return Val >= 0 && Val <= 31;
1801 bool isMemThumbSPI()
const {
1802 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1803 Memory.Alignment != 0)
1806 if (!Memory.OffsetImm)
return true;
1808 int64_t Val =
CE->getValue();
1809 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1814 bool isMemImm8s4Offset()
const {
1820 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1823 if (!Memory.OffsetImm)
return true;
1825 int64_t Val =
CE->getValue();
1827 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1828 Val == std::numeric_limits<int32_t>::min();
1833 bool isMemImm7s4Offset()
const {
1839 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1840 !ARMMCRegisterClasses[ARM::GPRnopcRegClassID].contains(
1844 if (!Memory.OffsetImm)
return true;
1846 int64_t Val =
CE->getValue();
1848 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1853 bool isMemImm0_1020s4Offset()
const {
1854 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1857 if (!Memory.OffsetImm)
return true;
1859 int64_t Val =
CE->getValue();
1860 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1865 bool isMemImm8Offset()
const {
1866 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1869 if (Memory.BaseRegNum == ARM::PC)
return false;
1871 if (!Memory.OffsetImm)
return true;
1873 int64_t Val =
CE->getValue();
1874 return (Val == std::numeric_limits<int32_t>::min()) ||
1875 (Val > -256 && Val < 256);
1880 template<
unsigned Bits,
unsigned RegClassID>
1881 bool isMemImm7ShiftedOffset()
const {
1882 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1883 !ARMMCRegisterClasses[RegClassID].contains(Memory.BaseRegNum))
1889 if (!Memory.OffsetImm)
return true;
1891 int64_t Val =
CE->getValue();
1895 if (Val == INT32_MIN)
1898 unsigned Divisor = 1U <<
Bits;
1901 if (Val % Divisor != 0)
1906 return (Val >= -127 && Val <= 127);
1911 template <
int shift>
bool isMemRegRQOffset()
const {
1912 if (!isMVEMem() || Memory.OffsetImm !=
nullptr || Memory.Alignment != 0)
1915 if (!ARMMCRegisterClasses[ARM::GPRnopcRegClassID].
contains(
1918 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1919 Memory.OffsetRegNum))
1926 (Memory.ShiftType !=
ARM_AM::uxtw || Memory.ShiftImm != shift))
1932 template <
int shift>
bool isMemRegQOffset()
const {
1933 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1936 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
1940 if (!Memory.OffsetImm)
1942 static_assert(shift < 56,
1943 "Such that we dont shift by a value higher than 62");
1945 int64_t Val =
CE->getValue();
1948 if ((Val & ((1U << shift) - 1)) != 0)
1954 int64_t
Range = (1U << (7 + shift)) - 1;
1955 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1960 bool isMemPosImm8Offset()
const {
1961 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1964 if (!Memory.OffsetImm)
return true;
1966 int64_t Val =
CE->getValue();
1967 return Val >= 0 && Val < 256;
1972 bool isMemNegImm8Offset()
const {
1973 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1976 if (Memory.BaseRegNum == ARM::PC)
return false;
1978 if (!Memory.OffsetImm)
return false;
1980 int64_t Val =
CE->getValue();
1981 return (Val == std::numeric_limits<int32_t>::min()) ||
1982 (Val > -256 && Val < 0);
1987 bool isMemUImm12Offset()
const {
1988 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1991 if (!Memory.OffsetImm)
return true;
1993 int64_t Val =
CE->getValue();
1994 return (Val >= 0 && Val < 4096);
1999 bool isMemImm12Offset()
const {
2007 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2010 if (!Memory.OffsetImm)
return true;
2012 int64_t Val =
CE->getValue();
2013 return (Val > -4096 && Val < 4096) ||
2014 (Val == std::numeric_limits<int32_t>::min());
2021 bool isConstPoolAsmImm()
const {
2024 return (isConstantPoolImm());
2027 bool isPostIdxImm8()
const {
2028 if (!isImm())
return false;
2030 if (!CE)
return false;
2031 int64_t Val =
CE->getValue();
2032 return (Val > -256 && Val < 256) ||
2033 (Val == std::numeric_limits<int32_t>::min());
2036 bool isPostIdxImm8s4()
const {
2037 if (!isImm())
return false;
2039 if (!CE)
return false;
2040 int64_t Val =
CE->getValue();
2041 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2042 (Val == std::numeric_limits<int32_t>::min());
2045 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2046 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2047 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2050 bool isAnyVectorList()
const {
2051 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2052 Kind == k_VectorListIndexed;
2055 bool isVectorList()
const {
return Kind == k_VectorList; }
2057 bool isSingleSpacedVectorList()
const {
2058 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2061 bool isDoubleSpacedVectorList()
const {
2062 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2065 bool isVecListOneD()
const {
2067 if (isDReg() && !Parser->hasMVE())
2069 if (!isSingleSpacedVectorList())
return false;
2070 return VectorList.Count == 1;
2073 bool isVecListTwoMQ()
const {
2074 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2075 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2079 bool isVecListDPair()
const {
2082 if (isQReg() && !Parser->hasMVE())
2084 if (!isSingleSpacedVectorList())
return false;
2085 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2089 bool isVecListThreeD()
const {
2090 if (!isSingleSpacedVectorList())
return false;
2091 return VectorList.Count == 3;
2094 bool isVecListFourD()
const {
2095 if (!isSingleSpacedVectorList())
return false;
2096 return VectorList.Count == 4;
2099 bool isVecListDPairSpaced()
const {
2100 if (Kind != k_VectorList)
return false;
2101 if (isSingleSpacedVectorList())
return false;
2102 return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
2106 bool isVecListThreeQ()
const {
2107 if (!isDoubleSpacedVectorList())
return false;
2108 return VectorList.Count == 3;
2111 bool isVecListFourQ()
const {
2112 if (!isDoubleSpacedVectorList())
return false;
2113 return VectorList.Count == 4;
2116 bool isVecListFourMQ()
const {
2117 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2118 ARMMCRegisterClasses[ARM::MQPRRegClassID].contains(
2122 bool isSingleSpacedVectorAllLanes()
const {
2123 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2126 bool isDoubleSpacedVectorAllLanes()
const {
2127 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2130 bool isVecListOneDAllLanes()
const {
2131 if (!isSingleSpacedVectorAllLanes())
return false;
2132 return VectorList.Count == 1;
2135 bool isVecListDPairAllLanes()
const {
2136 if (!isSingleSpacedVectorAllLanes())
return false;
2137 return (ARMMCRegisterClasses[ARM::DPairRegClassID]
2141 bool isVecListDPairSpacedAllLanes()
const {
2142 if (!isDoubleSpacedVectorAllLanes())
return false;
2143 return VectorList.Count == 2;
2146 bool isVecListThreeDAllLanes()
const {
2147 if (!isSingleSpacedVectorAllLanes())
return false;
2148 return VectorList.Count == 3;
2151 bool isVecListThreeQAllLanes()
const {
2152 if (!isDoubleSpacedVectorAllLanes())
return false;
2153 return VectorList.Count == 3;
2156 bool isVecListFourDAllLanes()
const {
2157 if (!isSingleSpacedVectorAllLanes())
return false;
2158 return VectorList.Count == 4;
2161 bool isVecListFourQAllLanes()
const {
2162 if (!isDoubleSpacedVectorAllLanes())
return false;
2163 return VectorList.Count == 4;
2166 bool isSingleSpacedVectorIndexed()
const {
2167 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2170 bool isDoubleSpacedVectorIndexed()
const {
2171 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2174 bool isVecListOneDByteIndexed()
const {
2175 if (!isSingleSpacedVectorIndexed())
return false;
2176 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2179 bool isVecListOneDHWordIndexed()
const {
2180 if (!isSingleSpacedVectorIndexed())
return false;
2181 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2184 bool isVecListOneDWordIndexed()
const {
2185 if (!isSingleSpacedVectorIndexed())
return false;
2186 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2189 bool isVecListTwoDByteIndexed()
const {
2190 if (!isSingleSpacedVectorIndexed())
return false;
2191 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2194 bool isVecListTwoDHWordIndexed()
const {
2195 if (!isSingleSpacedVectorIndexed())
return false;
2196 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2199 bool isVecListTwoQWordIndexed()
const {
2200 if (!isDoubleSpacedVectorIndexed())
return false;
2201 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2204 bool isVecListTwoQHWordIndexed()
const {
2205 if (!isDoubleSpacedVectorIndexed())
return false;
2206 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2209 bool isVecListTwoDWordIndexed()
const {
2210 if (!isSingleSpacedVectorIndexed())
return false;
2211 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2214 bool isVecListThreeDByteIndexed()
const {
2215 if (!isSingleSpacedVectorIndexed())
return false;
2216 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2219 bool isVecListThreeDHWordIndexed()
const {
2220 if (!isSingleSpacedVectorIndexed())
return false;
2221 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2224 bool isVecListThreeQWordIndexed()
const {
2225 if (!isDoubleSpacedVectorIndexed())
return false;
2226 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2229 bool isVecListThreeQHWordIndexed()
const {
2230 if (!isDoubleSpacedVectorIndexed())
return false;
2231 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2234 bool isVecListThreeDWordIndexed()
const {
2235 if (!isSingleSpacedVectorIndexed())
return false;
2236 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2239 bool isVecListFourDByteIndexed()
const {
2240 if (!isSingleSpacedVectorIndexed())
return false;
2241 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2244 bool isVecListFourDHWordIndexed()
const {
2245 if (!isSingleSpacedVectorIndexed())
return false;
2246 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2249 bool isVecListFourQWordIndexed()
const {
2250 if (!isDoubleSpacedVectorIndexed())
return false;
2251 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2254 bool isVecListFourQHWordIndexed()
const {
2255 if (!isDoubleSpacedVectorIndexed())
return false;
2256 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2259 bool isVecListFourDWordIndexed()
const {
2260 if (!isSingleSpacedVectorIndexed())
return false;
2261 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2264 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2266 template <
unsigned NumLanes>
2267 bool isVectorIndexInRange()
const {
2268 if (Kind != k_VectorIndex)
return false;
2269 return VectorIndex.Val < NumLanes;
2272 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2273 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2274 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2275 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2277 template<
int PermittedValue,
int OtherPermittedValue>
2278 bool isMVEPairVectorIndex()
const {
2279 if (Kind != k_VectorIndex)
return false;
2280 return VectorIndex.Val == PermittedValue ||
2281 VectorIndex.Val == OtherPermittedValue;
2284 bool isNEONi8splat()
const {
2285 if (!isImm())
return false;
2288 if (!CE)
return false;
2289 int64_t
Value =
CE->getValue();
2296 if (isNEONByteReplicate(2))
2302 if (!CE)
return false;
2303 unsigned Value =
CE->getValue();
2307 bool isNEONi16splatNot()
const {
2312 if (!CE)
return false;
2313 unsigned Value =
CE->getValue();
2318 if (isNEONByteReplicate(4))
2324 if (!CE)
return false;
2325 unsigned Value =
CE->getValue();
2329 bool isNEONi32splatNot()
const {
2334 if (!CE)
return false;
2335 unsigned Value =
CE->getValue();
2339 static bool isValidNEONi32vmovImm(int64_t
Value) {
2342 return ((
Value & 0xffffffffffffff00) == 0) ||
2343 ((
Value & 0xffffffffffff00ff) == 0) ||
2344 ((
Value & 0xffffffffff00ffff) == 0) ||
2345 ((
Value & 0xffffffff00ffffff) == 0) ||
2346 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2347 ((
Value & 0xffffffffff00ffff) == 0xffff);
2350 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2351 assert((Width == 8 || Width == 16 || Width == 32) &&
2352 "Invalid element width");
2353 assert(NumElems * Width <= 64 &&
"Invalid result width");
2361 int64_t
Value =
CE->getValue();
2367 uint64_t
Mask = (1ull << Width) - 1;
2369 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2371 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2374 for (
unsigned i = 1; i < NumElems; ++i) {
2376 if ((
Value & Mask) != Elem)
2382 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2383 return isNEONReplicate(8, NumBytes,
false);
2386 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2387 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2388 "Invalid source width");
2389 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2390 "Invalid destination width");
2391 assert(FromW < ToW &&
"ToW is not less than FromW");
2394 template<
unsigned FromW,
unsigned ToW>
2395 bool isNEONmovReplicate()
const {
2396 checkNeonReplicateArgs(FromW, ToW);
2397 if (ToW == 64 && isNEONi64splat())
2399 return isNEONReplicate(FromW, ToW / FromW,
false);
2402 template<
unsigned FromW,
unsigned ToW>
2403 bool isNEONinvReplicate()
const {
2404 checkNeonReplicateArgs(FromW, ToW);
2405 return isNEONReplicate(FromW, ToW / FromW,
true);
2408 bool isNEONi32vmov()
const {
2409 if (isNEONByteReplicate(4))
2417 return isValidNEONi32vmovImm(
CE->getValue());
2420 bool isNEONi32vmovNeg()
const {
2421 if (!isImm())
return false;
2424 if (!CE)
return false;
2425 return isValidNEONi32vmovImm(~
CE->getValue());
2428 bool isNEONi64splat()
const {
2429 if (!isImm())
return false;
2432 if (!CE)
return false;
2433 uint64_t
Value =
CE->getValue();
2435 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2436 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2440 template<
int64_t Angle,
int64_t Remainder>
2441 bool isComplexRotation()
const {
2442 if (!isImm())
return false;
2445 if (!CE)
return false;
2446 uint64_t
Value =
CE->getValue();
2448 return (
Value % Angle == Remainder &&
Value <= 270);
2451 bool isMVELongShift()
const {
2452 if (!isImm())
return false;
2455 if (!CE)
return false;
2456 uint64_t
Value =
CE->getValue();
2460 bool isMveSaturateOp()
const {
2461 if (!isImm())
return false;
2463 if (!CE)
return false;
2464 uint64_t
Value =
CE->getValue();
2468 bool isITCondCodeNoAL()
const {
2469 if (!isITCondCode())
return false;
2474 bool isITCondCodeRestrictedI()
const {
2475 if (!isITCondCode())
2481 bool isITCondCodeRestrictedS()
const {
2482 if (!isITCondCode())
2489 bool isITCondCodeRestrictedU()
const {
2490 if (!isITCondCode())
2496 bool isITCondCodeRestrictedFP()
const {
2497 if (!isITCondCode())
2504 void setVecListDPair(
unsigned int DPair) {
2505 Kind = k_VectorList;
2506 VectorList.RegNum = DPair;
2507 VectorList.Count = 2;
2508 VectorList.isDoubleSpaced =
false;
2511 void setVecListOneD(
unsigned int DReg) {
2512 Kind = k_VectorList;
2513 VectorList.RegNum =
DReg;
2514 VectorList.Count = 1;
2515 VectorList.isDoubleSpaced =
false;
2518 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
2528 void addARMBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2529 assert(
N == 1 &&
"Invalid number of operands!");
2533 void addThumbBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2534 assert(
N == 1 &&
"Invalid number of operands!");
2538 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2539 assert(
N == 2 &&
"Invalid number of operands!");
2545 void addVPTPredNOperands(MCInst &Inst,
unsigned N)
const {
2546 assert(
N == 3 &&
"Invalid number of operands!");
2548 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2553 void addVPTPredROperands(MCInst &Inst,
unsigned N)
const {
2554 assert(
N == 4 &&
"Invalid number of operands!");
2555 addVPTPredNOperands(Inst,
N-1);
2558 RegNum = ARM::NoRegister;
2561 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2562 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2564 "Inactive register in vpred_r is not tied to an output!");
2570 void addCoprocNumOperands(MCInst &Inst,
unsigned N)
const {
2571 assert(
N == 1 &&
"Invalid number of operands!");
2575 void addCoprocRegOperands(MCInst &Inst,
unsigned N)
const {
2576 assert(
N == 1 &&
"Invalid number of operands!");
2580 void addCoprocOptionOperands(MCInst &Inst,
unsigned N)
const {
2581 assert(
N == 1 &&
"Invalid number of operands!");
2585 void addITMaskOperands(MCInst &Inst,
unsigned N)
const {
2586 assert(
N == 1 &&
"Invalid number of operands!");
2590 void addITCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2591 assert(
N == 1 &&
"Invalid number of operands!");
2595 void addITCondCodeInvOperands(MCInst &Inst,
unsigned N)
const {
2596 assert(
N == 1 &&
"Invalid number of operands!");
2600 void addCCOutOperands(MCInst &Inst,
unsigned N)
const {
2601 assert(
N == 1 &&
"Invalid number of operands!");
2605 void addRegOperands(MCInst &Inst,
unsigned N)
const {
2606 assert(
N == 1 &&
"Invalid number of operands!");
2610 void addRegShiftedRegOperands(MCInst &Inst,
unsigned N)
const {
2611 assert(
N == 3 &&
"Invalid number of operands!");
2612 assert(isRegShiftedReg() &&
2613 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2620 void addRegShiftedImmOperands(MCInst &Inst,
unsigned N)
const {
2621 assert(
N == 2 &&
"Invalid number of operands!");
2622 assert(isRegShiftedImm() &&
2623 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2626 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2631 void addShifterImmOperands(MCInst &Inst,
unsigned N)
const {
2632 assert(
N == 1 &&
"Invalid number of operands!");
2637 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
2638 assert(
N == 1 &&
"Invalid number of operands!");
2639 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2640 for (MCRegister
Reg : RegList)
2644 void addRegListWithAPSROperands(MCInst &Inst,
unsigned N)
const {
2645 assert(
N == 1 &&
"Invalid number of operands!");
2646 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2647 for (MCRegister
Reg : RegList)
2651 void addDPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2652 addRegListOperands(Inst,
N);
2655 void addSPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2656 addRegListOperands(Inst,
N);
2659 void addFPSRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2660 addRegListOperands(Inst,
N);
2663 void addFPDRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2664 addRegListOperands(Inst,
N);
2667 void addRotImmOperands(MCInst &Inst,
unsigned N)
const {
2668 assert(
N == 1 &&
"Invalid number of operands!");
2673 void addModImmOperands(MCInst &Inst,
unsigned N)
const {
2674 assert(
N == 1 &&
"Invalid number of operands!");
2678 return addImmOperands(Inst,
N);
2683 void addModImmNotOperands(MCInst &Inst,
unsigned N)
const {
2684 assert(
N == 1 &&
"Invalid number of operands!");
2690 void addModImmNegOperands(MCInst &Inst,
unsigned N)
const {
2691 assert(
N == 1 &&
"Invalid number of operands!");
2697 void addThumbModImmNeg8_255Operands(MCInst &Inst,
unsigned N)
const {
2698 assert(
N == 1 &&
"Invalid number of operands!");
2700 uint32_t Val = -
CE->getValue();
2704 void addThumbModImmNeg1_7Operands(MCInst &Inst,
unsigned N)
const {
2705 assert(
N == 1 &&
"Invalid number of operands!");
2707 uint32_t Val = -
CE->getValue();
2711 void addBitfieldOperands(MCInst &Inst,
unsigned N)
const {
2712 assert(
N == 1 &&
"Invalid number of operands!");
2717 uint32_t
Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2718 (32 - (lsb + width)));
2722 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2723 assert(
N == 1 &&
"Invalid number of operands!");
2727 void addFBits16Operands(MCInst &Inst,
unsigned N)
const {
2728 assert(
N == 1 &&
"Invalid number of operands!");
2733 void addFBits32Operands(MCInst &Inst,
unsigned N)
const {
2734 assert(
N == 1 &&
"Invalid number of operands!");
2739 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2740 assert(
N == 1 &&
"Invalid number of operands!");
2746 void addImm8s4Operands(MCInst &Inst,
unsigned N)
const {
2747 assert(
N == 1 &&
"Invalid number of operands!");
2754 void addImm7s4Operands(MCInst &Inst,
unsigned N)
const {
2755 assert(
N == 1 &&
"Invalid number of operands!");
2762 void addImm7Shift0Operands(MCInst &Inst,
unsigned N)
const {
2763 assert(
N == 1 &&
"Invalid number of operands!");
2768 void addImm7Shift1Operands(MCInst &Inst,
unsigned N)
const {
2769 assert(
N == 1 &&
"Invalid number of operands!");
2774 void addImm7Shift2Operands(MCInst &Inst,
unsigned N)
const {
2775 assert(
N == 1 &&
"Invalid number of operands!");
2780 void addImm7Operands(MCInst &Inst,
unsigned N)
const {
2781 assert(
N == 1 &&
"Invalid number of operands!");
2786 void addImm0_1020s4Operands(MCInst &Inst,
unsigned N)
const {
2787 assert(
N == 1 &&
"Invalid number of operands!");
2794 void addImm0_508s4NegOperands(MCInst &Inst,
unsigned N)
const {
2795 assert(
N == 1 &&
"Invalid number of operands!");
2802 void addImm0_508s4Operands(MCInst &Inst,
unsigned N)
const {
2803 assert(
N == 1 &&
"Invalid number of operands!");
2810 void addImm1_16Operands(MCInst &Inst,
unsigned N)
const {
2811 assert(
N == 1 &&
"Invalid number of operands!");
2818 void addImm1_32Operands(MCInst &Inst,
unsigned N)
const {
2819 assert(
N == 1 &&
"Invalid number of operands!");
2826 void addImmThumbSROperands(MCInst &Inst,
unsigned N)
const {
2827 assert(
N == 1 &&
"Invalid number of operands!");
2831 unsigned Imm =
CE->getValue();
2835 void addPKHASRImmOperands(MCInst &Inst,
unsigned N)
const {
2836 assert(
N == 1 &&
"Invalid number of operands!");
2840 int Val =
CE->getValue();
2844 void addT2SOImmNotOperands(MCInst &Inst,
unsigned N)
const {
2845 assert(
N == 1 &&
"Invalid number of operands!");
2852 void addT2SOImmNegOperands(MCInst &Inst,
unsigned N)
const {
2853 assert(
N == 1 &&
"Invalid number of operands!");
2860 void addImm0_4095NegOperands(MCInst &Inst,
unsigned N)
const {
2861 assert(
N == 1 &&
"Invalid number of operands!");
2868 void addUnsignedOffset_b8s2Operands(MCInst &Inst,
unsigned N)
const {
2877 void addThumbMemPCOperands(MCInst &Inst,
unsigned N)
const {
2878 assert(
N == 1 &&
"Invalid number of operands!");
2890 assert(isGPRMem() &&
"Unknown value type!");
2898 void addMemBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2899 assert(
N == 1 &&
"Invalid number of operands!");
2903 void addInstSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2904 assert(
N == 1 &&
"Invalid number of operands!");
2908 void addTraceSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2909 assert(
N == 1 &&
"Invalid number of operands!");
2913 void addMemNoOffsetOperands(MCInst &Inst,
unsigned N)
const {
2914 assert(
N == 1 &&
"Invalid number of operands!");
2918 void addMemNoOffsetT2Operands(MCInst &Inst,
unsigned N)
const {
2919 assert(
N == 1 &&
"Invalid number of operands!");
2923 void addMemNoOffsetT2NoSpOperands(MCInst &Inst,
unsigned N)
const {
2924 assert(
N == 1 &&
"Invalid number of operands!");
2928 void addMemNoOffsetTOperands(MCInst &Inst,
unsigned N)
const {
2929 assert(
N == 1 &&
"Invalid number of operands!");
2933 void addMemPCRelImm12Operands(MCInst &Inst,
unsigned N)
const {
2934 assert(
N == 1 &&
"Invalid number of operands!");
2941 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2942 assert(
N == 1 &&
"Invalid number of operands!");
2943 assert(isImm() &&
"Not an immediate!");
2953 int Val =
CE->getValue();
2957 void addAlignedMemoryOperands(MCInst &Inst,
unsigned N)
const {
2958 assert(
N == 2 &&
"Invalid number of operands!");
2963 void addDupAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2964 addAlignedMemoryOperands(Inst,
N);
2967 void addAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2968 addAlignedMemoryOperands(Inst,
N);
2971 void addAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2972 addAlignedMemoryOperands(Inst,
N);
2975 void addDupAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2976 addAlignedMemoryOperands(Inst,
N);
2979 void addAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2980 addAlignedMemoryOperands(Inst,
N);
2983 void addDupAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2984 addAlignedMemoryOperands(Inst,
N);
2987 void addAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2988 addAlignedMemoryOperands(Inst,
N);
2991 void addDupAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2992 addAlignedMemoryOperands(Inst,
N);
2995 void addAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2996 addAlignedMemoryOperands(Inst,
N);
2999 void addDupAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
3000 addAlignedMemoryOperands(Inst,
N);
3003 void addAlignedMemory64or128or256Operands(MCInst &Inst,
unsigned N)
const {
3004 addAlignedMemoryOperands(Inst,
N);
3007 void addAddrMode2Operands(MCInst &Inst,
unsigned N)
const {
3008 assert(
N == 3 &&
"Invalid number of operands!");
3011 if (!Memory.OffsetRegNum) {
3012 if (!Memory.OffsetImm)
3015 int32_t Val =
CE->getValue();
3018 if (Val == std::numeric_limits<int32_t>::min())
3031 Memory.ShiftImm, Memory.ShiftType);
3036 void addAM2OffsetImmOperands(MCInst &Inst,
unsigned N)
const {
3037 assert(
N == 2 &&
"Invalid number of operands!");
3039 assert(CE &&
"non-constant AM2OffsetImm operand!");
3040 int32_t Val =
CE->getValue();
3043 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3044 if (Val < 0) Val = -Val;
3050 void addAddrMode3Operands(MCInst &Inst,
unsigned N)
const {
3051 assert(
N == 3 &&
"Invalid number of operands!");
3064 if (!Memory.OffsetRegNum) {
3065 if (!Memory.OffsetImm)
3068 int32_t Val =
CE->getValue();
3071 if (Val == std::numeric_limits<int32_t>::min())
3088 void addAM3OffsetOperands(MCInst &Inst,
unsigned N)
const {
3089 assert(
N == 2 &&
"Invalid number of operands!");
3090 if (Kind == k_PostIndexRegister) {
3099 const MCConstantExpr *
CE =
static_cast<const MCConstantExpr*
>(
getImm());
3100 int32_t Val =
CE->getValue();
3103 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3104 if (Val < 0) Val = -Val;
3110 void addAddrMode5Operands(MCInst &Inst,
unsigned N)
const {
3111 assert(
N == 2 &&
"Invalid number of operands!");
3122 if (!Memory.OffsetImm)
3126 int32_t Val =
CE->getValue() / 4;
3129 if (Val == std::numeric_limits<int32_t>::min())
3139 void addAddrMode5FP16Operands(MCInst &Inst,
unsigned N)
const {
3140 assert(
N == 2 &&
"Invalid number of operands!");
3152 if (!Memory.OffsetImm)
3155 int32_t Val =
CE->getValue() / 2;
3158 if (Val == std::numeric_limits<int32_t>::min())
3168 void addMemImm8s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3169 assert(
N == 2 &&
"Invalid number of operands!");
3180 addExpr(Inst, Memory.OffsetImm);
3183 void addMemImm7s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3184 assert(
N == 2 &&
"Invalid number of operands!");
3195 addExpr(Inst, Memory.OffsetImm);
3198 void addMemImm0_1020s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3199 assert(
N == 2 &&
"Invalid number of operands!");
3201 if (!Memory.OffsetImm)
3210 void addMemImmOffsetOperands(MCInst &Inst,
unsigned N)
const {
3211 assert(
N == 2 &&
"Invalid number of operands!");
3213 addExpr(Inst, Memory.OffsetImm);
3216 void addMemRegRQOffsetOperands(MCInst &Inst,
unsigned N)
const {
3217 assert(
N == 2 &&
"Invalid number of operands!");
3222 void addMemUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3223 assert(
N == 2 &&
"Invalid number of operands!");
3233 addExpr(Inst, Memory.OffsetImm);
3236 void addMemImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3237 assert(
N == 2 &&
"Invalid number of operands!");
3247 addExpr(Inst, Memory.OffsetImm);
3250 void addConstPoolAsmImmOperands(MCInst &Inst,
unsigned N)
const {
3251 assert(
N == 1 &&
"Invalid number of operands!");
3254 addExpr(Inst, getConstantPoolImm());
3257 void addMemTBBOperands(MCInst &Inst,
unsigned N)
const {
3258 assert(
N == 2 &&
"Invalid number of operands!");
3263 void addMemTBHOperands(MCInst &Inst,
unsigned N)
const {
3264 assert(
N == 2 &&
"Invalid number of operands!");
3269 void addMemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3270 assert(
N == 3 &&
"Invalid number of operands!");
3273 Memory.ShiftImm, Memory.ShiftType);
3279 void addT2MemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3280 assert(
N == 3 &&
"Invalid number of operands!");
3286 void addMemThumbRROperands(MCInst &Inst,
unsigned N)
const {
3287 assert(
N == 2 &&
"Invalid number of operands!");
3292 void addMemThumbRIs4Operands(MCInst &Inst,
unsigned N)
const {
3293 assert(
N == 2 &&
"Invalid number of operands!");
3295 if (!Memory.OffsetImm)
3304 void addMemThumbRIs2Operands(MCInst &Inst,
unsigned N)
const {
3305 assert(
N == 2 &&
"Invalid number of operands!");
3307 if (!Memory.OffsetImm)
3315 void addMemThumbRIs1Operands(MCInst &Inst,
unsigned N)
const {
3316 assert(
N == 2 &&
"Invalid number of operands!");
3318 addExpr(Inst, Memory.OffsetImm);
3321 void addMemThumbSPIOperands(MCInst &Inst,
unsigned N)
const {
3322 assert(
N == 2 &&
"Invalid number of operands!");
3324 if (!Memory.OffsetImm)
3333 void addPostIdxImm8Operands(MCInst &Inst,
unsigned N)
const {
3334 assert(
N == 1 &&
"Invalid number of operands!");
3336 assert(CE &&
"non-constant post-idx-imm8 operand!");
3337 int Imm =
CE->getValue();
3338 bool isAdd =
Imm >= 0;
3339 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3344 void addPostIdxImm8s4Operands(MCInst &Inst,
unsigned N)
const {
3345 assert(
N == 1 &&
"Invalid number of operands!");
3347 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3348 int Imm =
CE->getValue();
3349 bool isAdd =
Imm >= 0;
3350 if (Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3356 void addPostIdxRegOperands(MCInst &Inst,
unsigned N)
const {
3357 assert(
N == 2 &&
"Invalid number of operands!");
3362 void addPostIdxRegShiftedOperands(MCInst &Inst,
unsigned N)
const {
3363 assert(
N == 2 &&
"Invalid number of operands!");
3369 PostIdxReg.ShiftTy);
3373 void addPowerTwoOperands(MCInst &Inst,
unsigned N)
const {
3374 assert(
N == 1 &&
"Invalid number of operands!");
3379 void addMSRMaskOperands(MCInst &Inst,
unsigned N)
const {
3380 assert(
N == 1 &&
"Invalid number of operands!");
3384 void addBankedRegOperands(MCInst &Inst,
unsigned N)
const {
3385 assert(
N == 1 &&
"Invalid number of operands!");
3389 void addProcIFlagsOperands(MCInst &Inst,
unsigned N)
const {
3390 assert(
N == 1 &&
"Invalid number of operands!");
3394 void addVecListOperands(MCInst &Inst,
unsigned N)
const {
3395 assert(
N == 1 &&
"Invalid number of operands!");
3397 if (isAnyVectorList())
3399 else if (isDReg() && !Parser->hasMVE()) {
3401 }
else if (isQReg() && !Parser->hasMVE()) {
3402 MCRegister DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3403 DPair = Parser->getMRI()->getMatchingSuperReg(
3404 DPair, ARM::dsub_0, &ARMMCRegisterClasses[ARM::DPairRegClassID]);
3409 "attempted to add a vector list register with wrong type!");
3413 void addMVEVecListOperands(MCInst &Inst,
unsigned N)
const {
3414 assert(
N == 1 &&
"Invalid number of operands!");
3430 const MCRegisterClass *RC_in = &ARMMCRegisterClasses[ARM::MQPRRegClassID];
3431 const MCRegisterClass *RC_out =
3432 (VectorList.Count == 2) ? &ARMMCRegisterClasses[ARM::MQQPRRegClassID]
3433 : &ARMMCRegisterClasses[
ARM::MQQQQPRRegClassID];
3436 for (
I = 0;
I <
E;
I++)
3439 assert(
I <
E &&
"Invalid vector list start register!");
3444 void addVecListIndexedOperands(MCInst &Inst,
unsigned N)
const {
3445 assert(
N == 2 &&
"Invalid number of operands!");
3450 void addVectorIndex8Operands(MCInst &Inst,
unsigned N)
const {
3451 assert(
N == 1 &&
"Invalid number of operands!");
3455 void addVectorIndex16Operands(MCInst &Inst,
unsigned N)
const {
3456 assert(
N == 1 &&
"Invalid number of operands!");
3460 void addVectorIndex32Operands(MCInst &Inst,
unsigned N)
const {
3461 assert(
N == 1 &&
"Invalid number of operands!");
3465 void addVectorIndex64Operands(MCInst &Inst,
unsigned N)
const {
3466 assert(
N == 1 &&
"Invalid number of operands!");
3470 void addMVEVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3471 assert(
N == 1 &&
"Invalid number of operands!");
3475 void addMVEPairVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3476 assert(
N == 1 &&
"Invalid number of operands!");
3480 void addNEONi8splatOperands(MCInst &Inst,
unsigned N)
const {
3481 assert(
N == 1 &&
"Invalid number of operands!");
3488 void addNEONi16splatOperands(MCInst &Inst,
unsigned N)
const {
3489 assert(
N == 1 &&
"Invalid number of operands!");
3492 unsigned Value =
CE->getValue();
3497 void addNEONi16splatNotOperands(MCInst &Inst,
unsigned N)
const {
3498 assert(
N == 1 &&
"Invalid number of operands!");
3501 unsigned Value =
CE->getValue();
3506 void addNEONi32splatOperands(MCInst &Inst,
unsigned N)
const {
3507 assert(
N == 1 &&
"Invalid number of operands!");
3510 unsigned Value =
CE->getValue();
3515 void addNEONi32splatNotOperands(MCInst &Inst,
unsigned N)
const {
3516 assert(
N == 1 &&
"Invalid number of operands!");
3519 unsigned Value =
CE->getValue();
3524 void addNEONi8ReplicateOperands(MCInst &Inst,
bool Inv)
const {
3529 "All instructions that wants to replicate non-zero byte "
3530 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3531 unsigned Value =
CE->getValue();
3534 unsigned B =
Value & 0xff;
3539 void addNEONinvi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3540 assert(
N == 1 &&
"Invalid number of operands!");
3541 addNEONi8ReplicateOperands(Inst,
true);
3544 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3547 else if (
Value > 0xffff &&
Value <= 0xffffff)
3549 else if (
Value > 0xffffff)
3554 void addNEONi32vmovOperands(MCInst &Inst,
unsigned N)
const {
3555 assert(
N == 1 &&
"Invalid number of operands!");
3558 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3562 void addNEONvmovi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3563 assert(
N == 1 &&
"Invalid number of operands!");
3564 addNEONi8ReplicateOperands(Inst,
false);
3567 void addNEONvmovi16ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3568 assert(
N == 1 &&
"Invalid number of operands!");
3574 "All instructions that want to replicate non-zero half-word "
3575 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3576 uint64_t
Value =
CE->getValue();
3577 unsigned Elem =
Value & 0xffff;
3579 Elem = (Elem >> 8) | 0x200;
3583 void addNEONi32vmovNegOperands(MCInst &Inst,
unsigned N)
const {
3584 assert(
N == 1 &&
"Invalid number of operands!");
3587 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3591 void addNEONvmovi32ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3592 assert(
N == 1 &&
"Invalid number of operands!");
3598 "All instructions that want to replicate non-zero word "
3599 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3600 uint64_t
Value =
CE->getValue();
3601 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3605 void addNEONi64splatOperands(MCInst &Inst,
unsigned N)
const {
3606 assert(
N == 1 &&
"Invalid number of operands!");
3609 uint64_t
Value =
CE->getValue();
3611 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3617 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
3618 assert(
N == 1 &&
"Invalid number of operands!");
3623 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
3624 assert(
N == 1 &&
"Invalid number of operands!");
3629 void addMveSaturateOperands(MCInst &Inst,
unsigned N)
const {
3630 assert(
N == 1 &&
"Invalid number of operands!");
3632 unsigned Imm =
CE->getValue();
3633 assert((Imm == 48 || Imm == 64) &&
"Invalid saturate operand");
3637 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
3639 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask, SMLoc S,
3640 ARMAsmParser &Parser) {
3641 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3648 static std::unique_ptr<ARMOperand>
3650 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3657 static std::unique_ptr<ARMOperand> CreateVPTPred(
ARMVCC::VPTCodes CC, SMLoc S,
3658 ARMAsmParser &Parser) {
3659 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3666 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal, SMLoc S,
3667 ARMAsmParser &Parser) {
3668 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3669 Op->Cop.Val = CopVal;
3675 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal, SMLoc S,
3676 ARMAsmParser &Parser) {
3677 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3678 Op->Cop.Val = CopVal;
3684 static std::unique_ptr<ARMOperand>
3685 CreateCoprocOption(
unsigned Val, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3686 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3693 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister
Reg, SMLoc S,
3694 ARMAsmParser &Parser) {
3695 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3696 Op->Reg.RegNum =
Reg;
3702 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3703 ARMAsmParser &Parser) {
3704 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3705 Op->Tok.Data = Str.data();
3706 Op->Tok.Length = Str.size();
3712 static std::unique_ptr<ARMOperand> CreateReg(MCRegister
Reg, SMLoc S, SMLoc
E,
3713 ARMAsmParser &Parser) {
3714 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3715 Op->Reg.RegNum =
Reg;
3721 static std::unique_ptr<ARMOperand>
3723 MCRegister ShiftReg,
unsigned ShiftImm, SMLoc S,
3724 SMLoc
E, ARMAsmParser &Parser) {
3725 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3726 Op->RegShiftedReg.ShiftTy = ShTy;
3727 Op->RegShiftedReg.SrcReg = SrcReg;
3728 Op->RegShiftedReg.ShiftReg = ShiftReg;
3729 Op->RegShiftedReg.ShiftImm = ShiftImm;
3735 static std::unique_ptr<ARMOperand>
3737 unsigned ShiftImm, SMLoc S, SMLoc
E,
3738 ARMAsmParser &Parser) {
3739 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3740 Op->RegShiftedImm.ShiftTy = ShTy;
3741 Op->RegShiftedImm.SrcReg = SrcReg;
3742 Op->RegShiftedImm.ShiftImm = ShiftImm;
3748 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3750 ARMAsmParser &Parser) {
3751 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3752 Op->ShifterImm.isASR = isASR;
3753 Op->ShifterImm.Imm =
Imm;
3759 static std::unique_ptr<ARMOperand>
3760 CreateRotImm(
unsigned Imm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3761 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3762 Op->RotImm.Imm =
Imm;
3768 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3770 ARMAsmParser &Parser) {
3771 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3773 Op->ModImm.Rot = Rot;
3779 static std::unique_ptr<ARMOperand>
3780 CreateConstantPoolImm(
const MCExpr *Val, SMLoc S, SMLoc
E,
3781 ARMAsmParser &Parser) {
3782 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3789 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3790 unsigned Width, SMLoc S,
3792 ARMAsmParser &Parser) {
3793 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3794 Op->Bitfield.LSB = LSB;
3795 Op->Bitfield.Width = Width;
3801 static std::unique_ptr<ARMOperand>
3802 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3803 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3804 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3805 KindTy Kind = k_RegisterList;
3807 if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
3808 Regs.front().second)) {
3809 if (Regs.back().second == ARM::VPR)
3810 Kind = k_FPDRegisterListWithVPR;
3812 Kind = k_DPRRegisterList;
3813 }
else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
3814 Regs.front().second)) {
3815 if (Regs.back().second == ARM::VPR)
3816 Kind = k_FPSRegisterListWithVPR;
3818 Kind = k_SPRRegisterList;
3819 }
else if (Regs.front().second == ARM::VPR) {
3820 assert(Regs.size() == 1 &&
3821 "Register list starting with VPR expected to only contain VPR");
3822 Kind = k_FPSRegisterListWithVPR;
3825 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3826 Kind = k_RegisterListWithAPSR;
3830 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3831 for (
const auto &
P : Regs)
3832 Op->Registers.push_back(
P.second);
3834 Op->StartLoc = StartLoc;
3835 Op->EndLoc = EndLoc;
3839 static std::unique_ptr<ARMOperand>
3840 CreateVectorList(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced, SMLoc S,
3841 SMLoc
E, ARMAsmParser &Parser) {
3842 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3843 Op->VectorList.RegNum =
Reg;
3845 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3851 static std::unique_ptr<ARMOperand>
3852 CreateVectorListAllLanes(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced,
3853 SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3854 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3855 Op->VectorList.RegNum =
Reg;
3857 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3863 static std::unique_ptr<ARMOperand>
3864 CreateVectorListIndexed(MCRegister
Reg,
unsigned Count,
unsigned Index,
3865 bool isDoubleSpaced, SMLoc S, SMLoc
E,
3866 ARMAsmParser &Parser) {
3867 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3868 Op->VectorList.RegNum =
Reg;
3870 Op->VectorList.LaneIndex =
Index;
3871 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3877 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx, SMLoc S,
3878 SMLoc
E, MCContext &Ctx,
3879 ARMAsmParser &Parser) {
3880 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3881 Op->VectorIndex.Val = Idx;
3887 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val, SMLoc S,
3888 SMLoc
E, ARMAsmParser &Parser) {
3889 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3896 static std::unique_ptr<ARMOperand>
3897 CreateMem(MCRegister BaseReg,
const MCExpr *OffsetImm, MCRegister OffsetReg,
3899 bool isNegative, SMLoc S, SMLoc
E, ARMAsmParser &Parser,
3900 SMLoc AlignmentLoc = SMLoc()) {
3901 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3903 Op->Memory.OffsetImm = OffsetImm;
3904 Op->Memory.OffsetRegNum = OffsetReg;
3905 Op->Memory.ShiftType = ShiftType;
3906 Op->Memory.ShiftImm = ShiftImm;
3907 Op->Memory.Alignment = Alignment;
3908 Op->Memory.isNegative = isNegative;
3911 Op->AlignmentLoc = AlignmentLoc;
3915 static std::unique_ptr<ARMOperand>
3917 unsigned ShiftImm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3918 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3919 Op->PostIdxReg.RegNum =
Reg;
3920 Op->PostIdxReg.isAdd = isAdd;
3921 Op->PostIdxReg.ShiftTy = ShiftTy;
3922 Op->PostIdxReg.ShiftImm = ShiftImm;
3928 static std::unique_ptr<ARMOperand>
3929 CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3930 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3931 Op->MBOpt.Val = Opt;
3937 static std::unique_ptr<ARMOperand>
3939 ARMAsmParser &Parser) {
3940 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3941 Op->ISBOpt.Val = Opt;
3947 static std::unique_ptr<ARMOperand>
3949 ARMAsmParser &Parser) {
3950 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3951 Op->TSBOpt.Val = Opt;
3957 static std::unique_ptr<ARMOperand>
3959 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3966 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask, SMLoc S,
3967 ARMAsmParser &Parser) {
3968 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3969 Op->MMask.Val = MMask;
3975 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg, SMLoc S,
3976 ARMAsmParser &Parser) {
3977 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3978 Op->BankedReg.Val =
Reg;
3987void ARMOperand::print(raw_ostream &OS,
const MCAsmInfo &MAI)
const {
4005 case k_ITCondMask: {
4006 static const char *
const MaskStr[] = {
4007 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4008 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4009 "(t)",
"(tett)",
"(tet)",
"(tete)",
4010 "(te)",
"(teet)",
"(tee)",
"(teee)",
4012 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4013 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4017 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4020 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4022 case k_CoprocOption:
4023 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4026 OS <<
"<mask: " << getMSRMask() <<
">";
4029 OS <<
"<banked reg: " << getBankedReg() <<
">";
4034 case k_MemBarrierOpt:
4035 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4037 case k_InstSyncBarrierOpt:
4038 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4040 case k_TraceSyncBarrierOpt:
4041 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4045 if (Memory.BaseRegNum)
4046 OS <<
" base:" <<
RegName(Memory.BaseRegNum);
4047 if (Memory.OffsetImm) {
4048 OS <<
" offset-imm:";
4051 if (Memory.OffsetRegNum)
4052 OS <<
" offset-reg:" << (Memory.isNegative ?
"-" :
"")
4053 <<
RegName(Memory.OffsetRegNum);
4056 OS <<
" shift-imm:" << Memory.ShiftImm;
4058 if (Memory.Alignment)
4059 OS <<
" alignment:" << Memory.Alignment;
4062 case k_PostIndexRegister:
4063 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4064 <<
RegName(PostIdxReg.RegNum);
4067 << PostIdxReg.ShiftImm;
4070 case k_ProcIFlags: {
4071 OS <<
"<ARM_PROC::";
4072 unsigned IFlags = getProcIFlags();
4073 for (
int i=2; i >= 0; --i)
4074 if (IFlags & (1 << i))
4082 case k_ShifterImmediate:
4083 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4084 <<
" #" << ShifterImm.Imm <<
">";
4086 case k_ShiftedRegister:
4087 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4089 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4091 case k_ShiftedImmediate:
4092 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4094 << RegShiftedImm.ShiftImm <<
">";
4096 case k_RotateImmediate:
4097 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4099 case k_ModifiedImmediate:
4100 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4101 << ModImm.Rot <<
")>";
4103 case k_ConstantPoolImmediate:
4104 OS <<
"<constant_pool_imm #";
4105 MAI.
printExpr(OS, *getConstantPoolImm());
4107 case k_BitfieldDescriptor:
4108 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4109 <<
", width: " <<
Bitfield.Width <<
">";
4111 case k_RegisterList:
4112 case k_RegisterListWithAPSR:
4113 case k_DPRRegisterList:
4114 case k_SPRRegisterList:
4115 case k_FPSRegisterListWithVPR:
4116 case k_FPDRegisterListWithVPR: {
4117 OS <<
"<register_list ";
4119 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4120 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4122 if (++
I <
E) OS <<
", ";
4129 OS <<
"<vector_list " << VectorList.Count <<
" * "
4130 <<
RegName(VectorList.RegNum) <<
">";
4132 case k_VectorListAllLanes:
4133 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4134 <<
RegName(VectorList.RegNum) <<
">";
4136 case k_VectorListIndexed:
4137 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4138 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4144 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4158 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4159 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4160 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4165 unsigned MnemonicOpsEndInd = 1;
4168 if (Operands[0]->isToken() &&
4169 static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"cps") {
4170 if (Operands.
size() > 1 && Operands[1]->isImm() &&
4171 static_cast<ARMOperand &
>(*Operands[1]).getImm()->getKind() ==
4174 static_cast<ARMOperand &
>(*Operands[1]).getImm())
4177 static_cast<ARMOperand &
>(*Operands[1]).getImm())
4179 ++MnemonicOpsEndInd;
4183 bool RHSCondCode =
false;
4184 while (MnemonicOpsEndInd < Operands.
size()) {
4185 auto Op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
4187 if (
Op.isITMask()) {
4189 MnemonicOpsEndInd++;
4190 }
else if (
Op.isToken() &&
4194 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4195 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4201 MnemonicOpsEndInd++;
4204 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4205 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4206 MnemonicOpsEndInd++;
4210 return MnemonicOpsEndInd;
4213bool ARMAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4215 const AsmToken &Tok = getParser().getTok();
4218 Reg = tryParseRegister();
4223ParseStatus ARMAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4225 if (parseRegister(
Reg, StartLoc, EndLoc))
4233MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4234 MCAsmParser &Parser = getParser();
4235 const AsmToken &Tok = Parser.
getTok();
4237 return MCRegister();
4242 Reg = StringSwitch<MCRegister>(lowerCase)
4243 .Case(
"r13", ARM::SP)
4244 .Case(
"r14", ARM::LR)
4245 .Case(
"r15", ARM::PC)
4246 .Case(
"ip", ARM::R12)
4248 .Case(
"a1", ARM::R0)
4249 .Case(
"a2", ARM::R1)
4250 .Case(
"a3", ARM::R2)
4251 .Case(
"a4", ARM::R3)
4252 .Case(
"v1", ARM::R4)
4253 .Case(
"v2", ARM::R5)
4254 .Case(
"v3", ARM::R6)
4255 .Case(
"v4", ARM::R7)
4256 .Case(
"v5", ARM::R8)
4257 .Case(
"v6", ARM::R9)
4258 .Case(
"v7", ARM::R10)
4259 .Case(
"v8", ARM::R11)
4260 .Case(
"sb", ARM::R9)
4261 .Case(
"sl", ARM::R10)
4262 .Case(
"fp", ARM::R11)
4263 .Default(MCRegister());
4269 auto Entry = RegisterReqs.
find(lowerCase);
4271 if (Entry == RegisterReqs.
end())
4272 return MCRegister();
4274 return Entry->getValue();
4278 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4279 return MCRegister();
4286std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4287 MCAsmParser &Parser = getParser();
4288 const AsmToken &Tok = Parser.
getTok();
4290 return std::nullopt;
4293 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4300 .Default(std::nullopt);
4308int ARMAsmParser::tryParseShiftRegister(
OperandVector &Operands) {
4309 MCAsmParser &Parser = getParser();
4312 auto ShiftTyOpt = tryParseShiftToken();
4313 if (ShiftTyOpt == std::nullopt)
4315 auto ShiftTy = ShiftTyOpt.value();
4322 std::unique_ptr<ARMOperand> PrevOp(
4324 if (!PrevOp->isReg())
4325 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4326 MCRegister SrcReg = PrevOp->getReg();
4330 MCRegister ShiftReg;
4342 const MCExpr *ShiftExpr =
nullptr;
4343 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4344 Error(ImmLoc,
"invalid immediate shift value");
4350 Error(ImmLoc,
"invalid immediate shift value");
4356 Imm =
CE->getValue();
4360 Error(ImmLoc,
"immediate shift value out of range");
4370 ShiftReg = tryParseRegister();
4372 Error(L,
"expected immediate or register in shift operand");
4377 "expected immediate or register in shift operand");
4383 Operands.
push_back(ARMOperand::CreateShiftedRegister(
4384 ShiftTy, SrcReg, ShiftReg, Imm, S, EndLoc, *
this));
4386 Operands.
push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
4398bool ARMAsmParser::tryParseRegisterWithWriteBack(
OperandVector &Operands) {
4399 MCAsmParser &Parser = getParser();
4402 MCRegister
Reg = tryParseRegister();
4406 Operands.
push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4408 const AsmToken &ExclaimTok = Parser.
getTok();
4411 ExclaimTok.
getLoc(), *
this));
4423 const MCExpr *ImmVal;
4424 if (getParser().parseExpression(ImmVal))
4428 return TokError(
"immediate value expected for vector index");
4455 if (Name.size() < 2 || Name[0] != CoprocOp)
4457 Name = (Name[1] ==
'r') ? Name.drop_front(2) : Name.drop_front();
4459 switch (Name.size()) {
4482 case '0':
return 10;
4483 case '1':
return 11;
4484 case '2':
return 12;
4485 case '3':
return 13;
4486 case '4':
return 14;
4487 case '5':
return 15;
4493ParseStatus ARMAsmParser::parseITCondCode(
OperandVector &Operands) {
4494 MCAsmParser &Parser = getParser();
4496 const AsmToken &Tok = Parser.
getTok();
4513ParseStatus ARMAsmParser::parseCoprocNumOperand(
OperandVector &Operands) {
4514 MCAsmParser &Parser = getParser();
4516 const AsmToken &Tok = Parser.
getTok();
4527 Operands.
push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4534ParseStatus ARMAsmParser::parseCoprocRegOperand(
OperandVector &Operands) {
4535 MCAsmParser &Parser = getParser();
4537 const AsmToken &Tok = Parser.
getTok();
4546 Operands.
push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4552ParseStatus ARMAsmParser::parseCoprocOptionOperand(
OperandVector &Operands) {
4553 MCAsmParser &Parser = getParser();
4563 if (getParser().parseExpression(Expr))
4564 return Error(Loc,
"illegal expression");
4566 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4568 "coprocessor option must be an immediate in range [0, 255]");
4569 int Val =
CE->getValue();
4577 Operands.
push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4588 if (!ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4592 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4593 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4594 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4595 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4596 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4597 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4598 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4599 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4608 Regs.emplace_back(Enc,
Reg);
4609 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4610 if (J->first == Enc) {
4611 Regs.erase(J.base());
4622bool ARMAsmParser::parseRegisterList(
OperandVector &Operands,
bool EnforceOrder,
4623 bool AllowRAAC,
bool IsLazyLoadStore,
4625 MCAsmParser &Parser = getParser();
4627 return TokError(
"Token is not a Left Curly Brace");
4634 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4635 MCRegister
Reg = tryParseRegister(AllowOutOfBoundReg);
4637 return Error(RegLoc,
"register expected");
4638 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4639 return Error(RegLoc,
"pseudo-register not allowed");
4650 bool VSCCLRMAdjustEncoding =
false;
4653 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4654 Reg = getDRegFromQReg(
Reg);
4659 const MCRegisterClass *RC;
4660 if (
Reg == ARM::RA_AUTH_CODE ||
4661 ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4662 RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
4663 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg))
4664 RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
4665 else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
contains(
Reg))
4666 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
4667 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4668 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4669 else if (
Reg == ARM::VPR)
4670 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4672 return Error(RegLoc,
"invalid register in register list");
4684 if (
Reg == ARM::RA_AUTH_CODE)
4685 return Error(RegLoc,
"pseudo-register not allowed");
4688 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4690 return Error(AfterMinusLoc,
"register expected");
4691 if (EndReg == ARM::RA_AUTH_CODE)
4692 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4694 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4695 EndReg = getDRegFromQReg(EndReg) + 1;
4702 return Error(AfterMinusLoc,
"invalid register in register list");
4705 return Error(AfterMinusLoc,
"bad range in register list");
4708 while (
Reg != EndReg) {
4711 if (VSCCLRMAdjustEncoding)
4714 Warning(AfterMinusLoc, StringRef(
"duplicated register (") +
4716 ") in register list");
4723 MCRegister OldReg =
Reg;
4725 const AsmToken RegTok = Parser.
getTok();
4726 Reg = tryParseRegister(AllowOutOfBoundReg);
4728 return Error(RegLoc,
"register expected");
4729 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4730 return Error(RegLoc,
"pseudo-register not allowed");
4732 bool isQReg =
false;
4733 if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4734 Reg = getDRegFromQReg(
Reg);
4738 RC->
getID() == ARMMCRegisterClasses[ARM::GPRRegClassID].getID() &&
4739 ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
Reg)) {
4742 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4744 if (
Reg == ARM::VPR &&
4745 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4746 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4747 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4748 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4752 ") in register list");
4758 if (IsVSCCLRM && OldReg == ARM::S31 &&
Reg ==
ARM::D16) {
4759 VSCCLRMAdjustEncoding =
true;
4760 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4763 if ((
Reg == ARM::RA_AUTH_CODE &&
4764 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
4766 return Error(RegLoc,
"invalid register in register list");
4772 if (VSCCLRMAdjustEncoding)
4774 if (EnforceOrder && EReg < EOldReg) {
4775 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
4776 Warning(RegLoc,
"register list not in ascending order");
4777 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].
contains(
Reg))
4778 return Error(RegLoc,
"register list not in ascending order");
4781 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4782 RC != &ARMMCRegisterClasses[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 (ARMMCRegisterClasses[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 (ARMMCRegisterClasses[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 &ARMMCRegisterClasses[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() && !ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
Reg))
4935 "vector register in range Q0-Q7 expected");
4938 else if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
4939 FirstReg =
Reg = getDRegFromQReg(
Reg);
4947 if (!parseVectorLane(LaneKind, LaneIndex,
E).isSuccess())
4955 else if (Spacing == 2)
4957 "sequential registers in double spaced list");
4960 MCRegister EndReg = tryParseRegister();
4962 return Error(AfterMinusLoc,
"register expected");
4964 if (!hasMVE() && ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(EndReg))
4965 EndReg = getDRegFromQReg(EndReg) + 1;
4972 !ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(EndReg)) ||
4974 !ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(EndReg)))
4975 return Error(AfterMinusLoc,
"invalid register in register list");
4978 return Error(AfterMinusLoc,
"bad range in register list");
4980 VectorLaneTy NextLaneKind;
4981 unsigned NextLaneIndex;
4982 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
4984 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4985 return Error(AfterMinusLoc,
"mismatched lane index in register list");
4994 MCRegister OldReg =
Reg;
4995 Reg = tryParseRegister();
4997 return Error(RegLoc,
"register expected");
5000 if (!ARMMCRegisterClasses[ARM::MQPRRegClassID].
contains(
Reg))
5001 return Error(RegLoc,
"vector register in range Q0-Q7 expected");
5010 else if (ARMMCRegisterClasses[ARM::QPRRegClassID].
contains(
Reg)) {
5013 else if (Spacing == 2)
5016 "invalid register in double-spaced list (must be 'D' register')");
5017 Reg = getDRegFromQReg(
Reg);
5018 if (
Reg != OldReg + 1)
5019 return Error(RegLoc,
"non-contiguous register range");
5023 VectorLaneTy NextLaneKind;
5024 unsigned NextLaneIndex;
5026 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5028 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5029 return Error(LaneLoc,
"mismatched lane index in register list");
5036 Spacing = 1 + (
Reg == OldReg + 2);
5039 if (
Reg != OldReg + Spacing)
5040 return Error(RegLoc,
"non-contiguous register range");
5043 VectorLaneTy NextLaneKind;
5044 unsigned NextLaneIndex;
5046 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5048 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5049 return Error(EndLoc,
"mismatched lane index in register list");
5062 if (
Count == 2 && !hasMVE()) {
5063 const MCRegisterClass *RC = (Spacing == 1) ?
5064 &ARMMCRegisterClasses[ARM::DPairRegClassID] :
5065 &ARMMCRegisterClasses[
ARM::DPairSpcRegClassID];
5068 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5069 ARMOperand::CreateVectorListAllLanes);
5070 Operands.
push_back(Create(FirstReg,
Count, (Spacing == 2), S,
E, *
this));
5074 Operands.
push_back(ARMOperand::CreateVectorListIndexed(
5075 FirstReg,
Count, LaneIndex, (Spacing == 2), S,
E, *
this));
5082ParseStatus ARMAsmParser::parseMemBarrierOptOperand(
OperandVector &Operands) {
5083 MCAsmParser &Parser = getParser();
5085 const AsmToken &Tok = Parser.
getTok();
5091 Opt = StringSwitch<unsigned>(OptStr.
lower())
5126 const MCExpr *MemBarrierID;
5127 if (getParser().parseExpression(MemBarrierID))
5128 return Error(Loc,
"illegal expression");
5132 return Error(Loc,
"constant expression expected");
5134 int Val =
CE->getValue();
5136 return Error(Loc,
"immediate value out of range");
5141 "expected an immediate or barrier type");
5149ARMAsmParser::parseTraceSyncBarrierOptOperand(
OperandVector &Operands) {
5150 MCAsmParser &Parser = getParser();
5152 const AsmToken &Tok = Parser.
getTok();
5163 ARMOperand::CreateTraceSyncBarrierOpt(
ARM_TSB::CSYNC, S, *
this));
5169ARMAsmParser::parseInstSyncBarrierOptOperand(
OperandVector &Operands) {
5170 MCAsmParser &Parser = getParser();
5172 const AsmToken &Tok = Parser.
getTok();
5191 const MCExpr *ISBarrierID;
5192 if (getParser().parseExpression(ISBarrierID))
5193 return Error(Loc,
"illegal expression");
5197 return Error(Loc,
"constant expression expected");
5199 int Val =
CE->getValue();
5201 return Error(Loc,
"immediate value out of range");
5206 "expected an immediate or barrier type");
5208 Operands.
push_back(ARMOperand::CreateInstSyncBarrierOpt(
5214ParseStatus ARMAsmParser::parseProcIFlagsOperand(
OperandVector &Operands) {
5215 MCAsmParser &Parser = getParser();
5217 const AsmToken &Tok = Parser.
getTok();
5225 if (IFlagsStr !=
"none") {
5226 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
5227 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.
substr(i, 1).
lower())
5235 if (Flag == ~0U || (IFlags & Flag))
5249ParseStatus ARMAsmParser::parseMSRMaskOperand(
OperandVector &Operands) {
5251 if (
static_cast<ARMOperand &
>(*Operands.
back()).isMSRMask() ||
5252 static_cast<ARMOperand &
>(*Operands.
back()).isBankedReg())
5254 MCAsmParser &Parser = getParser();
5256 const AsmToken &Tok = Parser.
getTok();
5260 if (Val > 255 || Val < 0) {
5263 unsigned SYSmvalue = Val & 0xFF;
5265 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5274 auto TheReg = ARMSysReg::lookupMClassSysRegByName(
Mask.lower());
5275 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5278 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5281 Operands.
push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5287 StringRef
Flags =
"";
5288 std::string SpecReg =
Mask.slice(Start,
Next).lower();
5295 unsigned FlagsVal = 0;
5297 if (SpecReg ==
"apsr") {
5298 FlagsVal = StringSwitch<unsigned>(Flags)
5301 .Case(
"nzcvqg", 0xc)
5304 if (FlagsVal == ~0U) {
5310 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
5312 if (Flags ==
"all" || Flags ==
"")
5314 for (
int i = 0, e =
Flags.size(); i != e; ++i) {
5315 unsigned Flag = StringSwitch<unsigned>(
Flags.substr(i, 1))
5324 if (Flag == ~0U || (FlagsVal & Flag))
5340 if (SpecReg ==
"spsr")
5344 Operands.
push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *
this));
5350ParseStatus ARMAsmParser::parseBankedRegOperand(
OperandVector &Operands) {
5352 if (
static_cast<ARMOperand &
>(*Operands.
back()).isBankedReg() ||
5353 static_cast<ARMOperand &
>(*Operands.
back()).isMSRMask())
5355 MCAsmParser &Parser = getParser();
5357 const AsmToken &Tok = Parser.
getTok();
5362 auto TheReg = ARMBankedReg::lookupBankedRegByName(
RegName.lower());
5365 unsigned Encoding = TheReg->Encoding;
5368 Operands.
push_back(ARMOperand::CreateBankedReg(Encoding, S, *
this));
5375ParseStatus ARMAsmParser::parsePKHImm(
OperandVector &Operands,
5377 MCAsmParser &Parser = getParser();
5378 auto ShiftCodeOpt = tryParseShiftToken();
5380 if (!ShiftCodeOpt.has_value())
5382 auto ShiftCode = ShiftCodeOpt.value();
5386 if (ShiftCode !=
Op)
5398 const MCExpr *ShiftAmount;
5401 if (getParser().parseExpression(ShiftAmount, EndLoc))
5402 return Error(Loc,
"illegal expression");
5405 return Error(Loc,
"constant expression expected");
5406 int Val =
CE->getValue();
5407 if (Val < Low || Val >
High)
5408 return Error(Loc,
"immediate value out of range");
5410 Operands.
push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *
this));
5415ParseStatus ARMAsmParser::parseSetEndImm(
OperandVector &Operands) {
5416 MCAsmParser &Parser = getParser();
5417 const AsmToken &Tok = Parser.
getTok();
5420 return Error(S,
"'be' or 'le' operand expected");
5428 return Error(S,
"'be' or 'le' operand expected");
5429 Operands.
push_back(ARMOperand::CreateImm(
5439ParseStatus ARMAsmParser::parseShifterImm(
OperandVector &Operands) {
5440 MCAsmParser &Parser = getParser();
5441 const AsmToken &Tok = Parser.
getTok();
5447 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
5449 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5462 const MCExpr *ShiftAmount;
5464 if (getParser().parseExpression(ShiftAmount, EndLoc))
5465 return Error(ExLoc,
"malformed shift expression");
5468 return Error(ExLoc,
"shift amount must be an immediate");
5470 int64_t Val =
CE->getValue();
5473 if (Val < 1 || Val > 32)
5474 return Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
5477 return Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
5478 if (Val == 32) Val = 0;
5481 if (Val < 0 || Val > 31)
5482 return Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
5486 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *
this));
5494ParseStatus ARMAsmParser::parseRotImm(
OperandVector &Operands) {
5495 MCAsmParser &Parser = getParser();
5496 const AsmToken &Tok = Parser.
getTok();
5501 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
5512 const MCExpr *ShiftAmount;
5514 if (getParser().parseExpression(ShiftAmount, EndLoc))
5515 return Error(ExLoc,
"malformed rotate expression");
5518 return Error(ExLoc,
"rotate amount must be an immediate");
5520 int64_t Val =
CE->getValue();
5524 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5525 return Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
5527 Operands.
push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *
this));
5532ParseStatus ARMAsmParser::parseModImm(
OperandVector &Operands) {
5533 MCAsmParser &Parser = getParser();
5534 AsmLexer &Lexer = getLexer();
5565 const MCExpr *Imm1Exp;
5566 if (getParser().parseExpression(Imm1Exp, Ex1))
5567 return Error(Sx1,
"malformed expression");
5573 Imm1 =
CE->getValue();
5577 Operands.
push_back(ARMOperand::CreateModImm(
5578 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *
this));
5589 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5595 Operands.
push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5602 "expected modified immediate operand: #[0, 255], #even[0-30]");
5605 return Error(Sx1,
"immediate operand must a number in the range [0, 255]");
5619 const MCExpr *Imm2Exp;
5620 if (getParser().parseExpression(Imm2Exp, Ex2))
5621 return Error(Sx2,
"malformed expression");
5626 Imm2 =
CE->getValue();
5627 if (!(Imm2 & ~0x1E)) {
5629 Operands.
push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *
this));
5633 "immediate operand must an even number in the range [0, 30]");
5635 return Error(Sx2,
"constant expression expected");
5639ParseStatus ARMAsmParser::parseBitfield(
OperandVector &Operands) {
5640 MCAsmParser &Parser = getParser();
5648 const MCExpr *LSBExpr;
5650 if (getParser().parseExpression(LSBExpr))
5651 return Error(
E,
"malformed immediate expression");
5654 return Error(
E,
"'lsb' operand must be an immediate");
5656 int64_t LSB =
CE->getValue();
5658 if (LSB < 0 || LSB > 31)
5659 return Error(
E,
"'lsb' operand must be in the range [0,31]");
5671 const MCExpr *WidthExpr;
5673 if (getParser().parseExpression(WidthExpr, EndLoc))
5674 return Error(
E,
"malformed immediate expression");
5677 return Error(
E,
"'width' operand must be an immediate");
5679 int64_t Width =
CE->getValue();
5681 if (Width < 1 || Width > 32 - LSB)
5682 return Error(
E,
"'width' operand must be in the range [1,32-lsb]");
5684 Operands.
push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *
this));
5689ParseStatus ARMAsmParser::parsePostIdxReg(
OperandVector &Operands) {
5698 MCAsmParser &Parser = getParser();
5699 AsmToken Tok = Parser.
getTok();
5701 bool haveEaten =
false;
5713 MCRegister
Reg = tryParseRegister();
5721 unsigned ShiftImm = 0;
5724 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5732 ARMOperand::CreatePostIdxReg(
Reg, isAdd, ShiftTy, ShiftImm, S,
E, *
this));
5737ParseStatus ARMAsmParser::parseAM3Offset(
OperandVector &Operands) {
5749 MCAsmParser &Parser = getParser();
5750 AsmToken Tok = Parser.
getTok();
5762 if (getParser().parseExpression(
Offset,
E))
5766 return Error(S,
"constant expression expected");
5769 int32_t Val =
CE->getValue();
5770 if (isNegative && Val == 0)
5771 Val = std::numeric_limits<int32_t>::min();
5773 Operands.
push_back(ARMOperand::CreateImm(
5779 bool haveEaten =
false;
5791 MCRegister
Reg = tryParseRegister();
5798 Operands.
push_back(ARMOperand::CreatePostIdxReg(
5806 unsigned MnemonicOpsEndInd) {
5807 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5808 auto Op =
static_cast<ARMOperand &
>(*Operands[
I]);
5809 if (
Op.isCondCode())
5816 unsigned MnemonicOpsEndInd) {
5817 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5818 auto Op =
static_cast<ARMOperand &
>(*Operands[
I]);
5828void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5832 unsigned CondOutI =
findCCOutInd(Operands, MnemonicOpsEndInd);
5835 unsigned RegRd = MnemonicOpsEndInd;
5836 unsigned RegRn = MnemonicOpsEndInd + 1;
5837 unsigned RegRm = MnemonicOpsEndInd;
5839 if (Operands.
size() == MnemonicOpsEndInd + 3) {
5842 if (((ARMOperand &)*Operands[RegRd]).
getReg() ==
5843 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1]).
getReg()) {
5844 RegRn = MnemonicOpsEndInd + 2;
5845 RegRm = MnemonicOpsEndInd + 1;
5847 RegRn = MnemonicOpsEndInd + 1;
5848 RegRm = MnemonicOpsEndInd + 2;
5853 ((ARMOperand &)*Operands[RegRd]).addRegOperands(Inst, 1);
5855 if (CondOutI != 0) {
5856 ((ARMOperand &)*Operands[CondOutI]).addCCOutOperands(Inst, 1);
5859 *ARMOperand::CreateCCOut(0, Operands[0]->getEndLoc(), *
this);
5860 Op.addCCOutOperands(Inst, 1);
5863 ((ARMOperand &)*Operands[RegRn]).addRegOperands(Inst, 1);
5865 ((ARMOperand &)*Operands[RegRm]).addRegOperands(Inst, 1);
5869 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5871 ARMOperand
Op = *ARMOperand::CreateCondCode(
5873 Op.addCondCodeOperands(Inst, 2);
5877void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5883 :
static_cast<ARMOperand &
>(*Operands[CondI]).getCondCode());
5891 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5892 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5911 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
5912 if (!
op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5918 ARMOperand &
op =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
5919 if (!
op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5924 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5926 ((ARMOperand &)*Operands[CondI]).addCondCodeOperands(Inst, 2);
5928 ARMOperand
Op = *ARMOperand::CreateCondCode(
5930 Op.addCondCodeOperands(Inst, 2);
5934void ARMAsmParser::cvtMVEVMOVQtoDReg(
5941 assert(Operands.
size() == MnemonicOpsEndInd + 6);
5943 ((ARMOperand &)*Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1);
5944 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 1])
5945 .addRegOperands(Inst, 1);
5946 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 2])
5947 .addRegOperands(Inst, 1);
5948 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 3])
5949 .addMVEPairVectorIndexOperands(Inst, 1);
5951 ((ARMOperand &)*Operands[MnemonicOpsEndInd + 5])
5952 .addMVEPairVectorIndexOperands(Inst, 1);
5954 ((ARMOperand &)*Operands[CondI])
5955 .addCondCodeOperands(Inst, 2);
5958 *ARMOperand::CreateCondCode(
ARMCC::AL, Operands[0]->getEndLoc(), *
this);
5959 Op.addCondCodeOperands(Inst, 2);
5966 MCAsmParser &Parser = getParser();
5969 return TokError(
"Token is not a Left Bracket");
5973 const AsmToken &BaseRegTok = Parser.
getTok();
5974 MCRegister
BaseReg = tryParseRegister();
5976 return Error(BaseRegTok.
getLoc(),
"register expected");
5979 const AsmToken &Tok = Parser.
getTok();
5982 return Error(Tok.
getLoc(),
"malformed memory operand");
5988 Operands.
push_back(ARMOperand::CreateMem(
5995 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6003 "Lost colon or comma in memory operand?!");
6012 SMLoc AlignmentLoc = Tok.
getLoc();
6015 if (getParser().parseExpression(Expr))
6023 return Error (
E,
"constant expression expected");
6026 switch (
CE->getValue()) {
6029 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6030 case 16:
Align = 2;
break;
6031 case 32:
Align = 4;
break;
6032 case 64:
Align = 8;
break;
6033 case 128:
Align = 16;
break;
6034 case 256:
Align = 32;
break;
6045 Operands.
push_back(ARMOperand::CreateMem(BaseReg,
nullptr, 0,
6047 S,
E, *
this, AlignmentLoc));
6053 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6073 const MCExpr *
Offset, *AdjustedOffset;
6074 if (getParser().parseExpression(
Offset))
6080 int32_t Val =
CE->getValue();
6081 if (isNegative && Val == 0)
6086 AdjustedOffset =
CE;
6089 Operands.
push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6103 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6111 bool isNegative =
false;
6121 MCRegister OffsetReg = tryParseRegister();
6123 return Error(
E,
"register expected");
6127 unsigned ShiftImm = 0;
6130 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6140 Operands.
push_back(ARMOperand::CreateMem(BaseReg,
nullptr, OffsetReg,
6141 ShiftType, ShiftImm, 0, isNegative,
6148 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6161 MCAsmParser &Parser = getParser();
6163 const AsmToken &Tok = Parser.
getTok();
6165 return Error(Loc,
"illegal shift operator");
6167 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
6168 ShiftName ==
"asl" || ShiftName ==
"ASL")
6170 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
6172 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
6174 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
6176 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
6178 else if (ShiftName ==
"uxtw" || ShiftName ==
"UXTW")
6181 return Error(Loc,
"illegal shift operator");
6189 const AsmToken &HashTok = Parser.
getTok();
6196 if (getParser().parseExpression(Expr))
6203 return Error(Loc,
"shift amount must be an immediate");
6204 int64_t
Imm =
CE->getValue();
6208 return Error(Loc,
"immediate shift value out of range");
6222ParseStatus ARMAsmParser::parseFPImm(
OperandVector &Operands) {
6225 MCAsmParser &Parser = getParser();
6252 bool isVmovf =
false;
6254 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
6255 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*Operands[
I]);
6256 if (TyOp.isToken() &&
6257 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
6258 TyOp.getToken() ==
".f16")) {
6264 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*Operands[0]);
6265 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
6266 Mnemonic.getToken() ==
"fconsts");
6267 if (!(isVmovf || isFconst))
6273 bool isNegative =
false;
6278 const AsmToken &Tok = Parser.
getTok();
6279 SMLoc Loc = Tok.
getLoc();
6282 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
6284 IntVal ^= (uint64_t)isNegative << 31;
6296 if (Val > 255 || Val < 0)
6297 return Error(Loc,
"encoded floating point value out of range");
6299 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
6307 return Error(Loc,
"invalid floating point immediate");
6312bool ARMAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
6313 MCAsmParser &Parser = getParser();
6318 ParseStatus ResTy = MatchOperandParserImpl(Operands, Mnemonic);
6327 switch (getLexer().getKind()) {
6335 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
6337 if (!tryParseRegisterWithWriteBack(Operands))
6339 int Res = tryParseShiftRegister(Operands);
6345 if (Mnemonic ==
"vmrs" &&
6349 Operands.
push_back(ARMOperand::CreateToken(
"APSR_nzcv", S, *
this));
6364 const MCExpr *IdVal;
6366 if (getParser().parseExpression(IdVal))
6369 Operands.
push_back(ARMOperand::CreateImm(IdVal, S,
E, *
this));
6373 return parseMemory(Operands);
6375 bool IsLazyLoadStore = Mnemonic ==
"vlldm" || Mnemonic ==
"vlstm";
6376 bool IsVSCCLRM = Mnemonic ==
"vscclrm";
6377 return parseRegisterList(Operands, !Mnemonic.
starts_with(
"clr"),
false,
6378 IsLazyLoadStore, IsVSCCLRM);
6391 auto AdjacentToken = getLexer().peekTok(
false);
6395 if (!ExpectIdentifier) {
6403 const MCExpr *ImmVal;
6404 if (getParser().parseExpression(ImmVal))
6408 int32_t Val =
CE->getValue();
6409 if (IsNegative && Val == 0)
6414 Operands.
push_back(ARMOperand::CreateImm(ImmVal, S,
E, *
this));
6420 Operands.
push_back(ARMOperand::CreateToken(
6436 if (parsePrefix(Spec))
6439 const MCExpr *SubExprVal;
6440 if (getParser().parseExpression(SubExprVal))
6443 const auto *ExprVal =
6446 Operands.
push_back(ARMOperand::CreateImm(ExprVal, S,
E, *
this));
6451 if (Mnemonic !=
"ldr")
6452 return Error(S,
"unexpected token in operand");
6454 const MCExpr *SubExprVal;
6455 if (getParser().parseExpression(SubExprVal))
6462 ARMOperand::CreateConstantPoolImm(SubExprVal, S,
E, *
this));
6468bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6469 const MCExpr *Expr =
nullptr;
6470 SMLoc
L = getParser().getTok().getLoc();
6471 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
6474 if (check(!
Value, L,
"expected constant expression"))
6476 Out =
Value->getValue();
6484 MCAsmParser &Parser = getParser();
6505 static const struct PrefixEntry {
6506 const char *Spelling;
6508 uint8_t SupportedFormats;
6509 } PrefixEntries[] = {
6521 llvm::find_if(PrefixEntries, [&IDVal](
const PrefixEntry &PE) {
6522 return PE.Spelling == IDVal;
6524 if (Prefix == std::end(PrefixEntries)) {
6529 uint8_t CurrentFormat;
6532 CurrentFormat = MACHO;
6535 CurrentFormat =
ELF;
6538 CurrentFormat =
COFF;
6541 CurrentFormat = WASM;
6551 if (~
Prefix->SupportedFormats & CurrentFormat) {
6553 "cannot represent relocation in the current file format");
6577StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6581 unsigned &ProcessorIMod,
6582 StringRef &ITMask) {
6585 CarrySetting =
false;
6591 if ((Mnemonic ==
"movs" &&
isThumb()) || Mnemonic ==
"teq" ||
6592 Mnemonic ==
"vceq" || Mnemonic ==
"svc" || Mnemonic ==
"mls" ||
6593 Mnemonic ==
"smmls" || Mnemonic ==
"vcls" || Mnemonic ==
"vmls" ||
6594 Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" || Mnemonic ==
"vcge" ||
6595 Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" || Mnemonic ==
"vaclt" ||
6596 Mnemonic ==
"vacle" || Mnemonic ==
"hlt" || Mnemonic ==
"vcgt" ||
6597 Mnemonic ==
"vcle" || Mnemonic ==
"smlal" || Mnemonic ==
"umaal" ||
6598 Mnemonic ==
"umlal" || Mnemonic ==
"vabal" || Mnemonic ==
"vmlal" ||
6599 Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" || Mnemonic ==
"fmuls" ||
6600 Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" ||
6601 Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" ||
6602 Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" ||
6603 Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
6604 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vins" ||
6605 Mnemonic ==
"vmovx" || Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
6606 Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" || Mnemonic ==
"vudot" ||
6607 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6608 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"wls" ||
6609 Mnemonic ==
"le" || Mnemonic ==
"dls" || Mnemonic ==
"csel" ||
6610 Mnemonic ==
"csinc" || Mnemonic ==
"csinv" || Mnemonic ==
"csneg" ||
6611 Mnemonic ==
"cinc" || Mnemonic ==
"cinv" || Mnemonic ==
"cneg" ||
6612 Mnemonic ==
"cset" || Mnemonic ==
"csetm" || Mnemonic ==
"aut" ||
6613 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"bti")
6618 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
6619 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
6620 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
6621 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs" &&
6623 (Mnemonic ==
"vmine" || Mnemonic ==
"vshle" || Mnemonic ==
"vshlt" ||
6624 Mnemonic ==
"vshllt" || Mnemonic ==
"vrshle" || Mnemonic ==
"vrshlt" ||
6625 Mnemonic ==
"vmvne" || Mnemonic ==
"vorne" || Mnemonic ==
"vnege" ||
6626 Mnemonic ==
"vnegt" || Mnemonic ==
"vmule" || Mnemonic ==
"vmult" ||
6627 Mnemonic ==
"vrintne" || Mnemonic ==
"vcmult" ||
6628 Mnemonic ==
"vcmule" || Mnemonic ==
"vpsele" || Mnemonic ==
"vpselt" ||
6632 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
6640 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" || Mnemonic ==
"mrs" ||
6641 Mnemonic ==
"smmls" || Mnemonic ==
"vabs" || Mnemonic ==
"vcls" ||
6642 Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" || Mnemonic ==
"vnmls" ||
6643 Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" || Mnemonic ==
"vrsqrts" ||
6644 Mnemonic ==
"srs" || Mnemonic ==
"flds" || Mnemonic ==
"fmrs" ||
6645 Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" || Mnemonic ==
"fsts" ||
6646 Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" || Mnemonic ==
"fmuls" ||
6647 Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" || Mnemonic ==
"vfms" ||
6648 Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" || Mnemonic ==
"bxns" ||
6649 Mnemonic ==
"blxns" || Mnemonic ==
"vfmas" || Mnemonic ==
"vmlas" ||
6650 (Mnemonic ==
"movs" &&
isThumb()))) {
6651 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
6652 CarrySetting =
true;
6660 StringSwitch<unsigned>(Mnemonic.
substr(Mnemonic.
size()-2, 2))
6665 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
6666 ProcessorIMod =
IMod;
6670 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic !=
"vmovlt" &&
6671 Mnemonic !=
"vshllt" && Mnemonic !=
"vrshrnt" && Mnemonic !=
"vshrnt" &&
6672 Mnemonic !=
"vqrshrunt" && Mnemonic !=
"vqshrunt" &&
6673 Mnemonic !=
"vqrshrnt" && Mnemonic !=
"vqshrnt" && Mnemonic !=
"vmullt" &&
6674 Mnemonic !=
"vqmovnt" && Mnemonic !=
"vqmovunt" && Mnemonic !=
"vmovnt" &&
6675 Mnemonic !=
"vqdmullt" && Mnemonic !=
"vpnot" && Mnemonic !=
"vcvtt" &&
6676 Mnemonic !=
"vcvt") {
6680 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-1);
6688 ITMask = Mnemonic.
substr(2);
6689 Mnemonic = Mnemonic.
slice(0, 2);
6693 ITMask = Mnemonic.
substr(4);
6694 Mnemonic = Mnemonic.
slice(0, 4);
6696 ITMask = Mnemonic.
substr(3);
6697 Mnemonic = Mnemonic.
slice(0, 3);
6707void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6708 StringRef ExtraToken,
6710 bool &CanAcceptCarrySet,
6711 bool &CanAcceptPredicationCode,
6712 bool &CanAcceptVPTPredicationCode) {
6713 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6716 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6717 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
6718 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
6719 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
6720 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
6721 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
6722 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
6724 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
6725 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
6727 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
6728 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
6729 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
6731 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vmaxnm" ||
6732 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
6733 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
6734 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
6735 Mnemonic.
starts_with(
"aes") || Mnemonic ==
"hvc" ||
6736 Mnemonic ==
"setpan" || Mnemonic.
starts_with(
"sha1") ||
6739 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" || Mnemonic ==
"vudot" ||
6740 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6741 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"vfmat" ||
6742 Mnemonic ==
"vfmab" || Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" ||
6743 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" || Mnemonic ==
"pssbb" ||
6744 Mnemonic ==
"vsmmla" || Mnemonic ==
"vummla" || Mnemonic ==
"vusmmla" ||
6745 Mnemonic ==
"vusdot" || Mnemonic ==
"vsudot" || Mnemonic ==
"bfcsel" ||
6746 Mnemonic ==
"wls" || Mnemonic ==
"dls" || Mnemonic ==
"le" ||
6747 Mnemonic ==
"csel" || Mnemonic ==
"csinc" || Mnemonic ==
"csinv" ||
6748 Mnemonic ==
"csneg" || Mnemonic ==
"cinc" || Mnemonic ==
"cinv" ||
6749 Mnemonic ==
"cneg" || Mnemonic ==
"cset" || Mnemonic ==
"csetm" ||
6750 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6751 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6753 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"aut" ||
6754 Mnemonic ==
"bti" ||
6761 CanAcceptPredicationCode =
false;
6764 CanAcceptPredicationCode =
6765 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
6766 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
6767 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
6768 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
6769 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
6770 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" && Mnemonic !=
"tsb" &&
6772 }
else if (isThumbOne()) {
6774 CanAcceptPredicationCode = Mnemonic !=
"movs";
6776 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
6778 CanAcceptPredicationCode =
true;
6782 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I) {
6783 auto &
Op =
static_cast<ARMOperand &
>(*Operands[
I]);
6784 if (
Op.isToken() &&
Op.getToken() ==
".w")
6794void ARMAsmParser::tryConvertingToTwoOperandForm(
6800 if (Operands.
size() != MnemonicOpsEndInd + 3)
6803 const auto &Op3 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]);
6804 auto &Op4 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
6805 if (!Op3.isReg() || !Op4.isReg())
6808 auto Op3Reg = Op3.getReg();
6809 auto Op4Reg = Op4.getReg();
6815 auto &Op5 =
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 2]);
6817 if (Mnemonic !=
"add")
6819 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6820 (Op5.isReg() && Op5.getReg() == ARM::PC);
6821 if (!TryTransform) {
6822 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6823 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6824 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6825 Op5.isImm() && !Op5.isImm0_508s4());
6829 }
else if (!isThumbOne())
6832 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
6833 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6834 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
6835 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
6841 bool Transform = Op3Reg == Op4Reg;
6846 const ARMOperand *LastOp = &Op5;
6848 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6849 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
6850 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
6851 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
6862 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
6868 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
6875 Operands.
erase(Operands.
begin() + MnemonicOpsEndInd);
6884 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
6894bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6895 StringRef Mnemonic,
OperandVector &Operands,
unsigned MnemonicOpsEndInd) {
6896 if (!hasMVE() || Operands.
size() <= MnemonicOpsEndInd)
6909 for (
auto &Operand : Operands) {
6910 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6911 ((*Operand).isReg() &&
6912 (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(
6913 (*Operand).getReg()) ||
6914 ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
6915 (*Operand).getReg())))) {
6921 for (
auto &Operand : Operands) {
6925 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6926 static_cast<ARMOperand &
>(*Operand).isQReg())
6942 unsigned VariantID);
6953void ARMAsmParser::fixupGNULDRDAlias(
StringRef Mnemonic,
6955 unsigned MnemonicOpsEndInd) {
6956 if (Mnemonic !=
"ldrd" && Mnemonic !=
"strd" && Mnemonic !=
"ldrexd" &&
6957 Mnemonic !=
"strexd" && Mnemonic !=
"ldaexd" && Mnemonic !=
"stlexd")
6960 unsigned IdX = Mnemonic ==
"strexd" || Mnemonic ==
"stlexd"
6961 ? MnemonicOpsEndInd + 1
6962 : MnemonicOpsEndInd;
6964 if (Operands.
size() < IdX + 2)
6967 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[IdX]);
6968 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*Operands[IdX + 1]);
6972 if (!Op3.isGPRMem())
6980 if (!
isThumb() && (RtEncoding & 1)) {
6985 if (Op2.getReg() == ARM::PC)
6987 MCRegister PairedReg = GPR.
getRegister(RtEncoding + 1);
6988 if (!PairedReg || PairedReg == ARM::PC ||
6989 (PairedReg == ARM::SP && !hasV8Ops()))
6993 ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(),
6994 Op2.getEndLoc(), *
this));
7002bool ARMAsmParser::CDEConvertDualRegOperand(StringRef Mnemonic,
7004 unsigned MnemonicOpsEndInd) {
7005 assert(MS.isCDEDualRegInstr(Mnemonic));
7007 if (Operands.
size() < 3 + MnemonicOpsEndInd)
7011 "operand must be an even-numbered register in the range [r0, r10]");
7013 const MCParsedAsmOperand &Op2 = *Operands[MnemonicOpsEndInd + 1];
7044 RPair = ARM::R10_R11;
7048 const MCParsedAsmOperand &Op3 = *Operands[MnemonicOpsEndInd + 2];
7052 Operands.
erase(Operands.
begin() + MnemonicOpsEndInd + 2);
7053 Operands[MnemonicOpsEndInd + 1] =
7059 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7060 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCondCode()) {
7062 --MnemonicOpsEndInd;
7068 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7069 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCCOut()) {
7071 --MnemonicOpsEndInd;
7077 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I)
7078 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred()) {
7080 --MnemonicOpsEndInd;
7086bool ARMAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
7088 MCAsmParser &Parser = getParser();
7095 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
7096 unsigned AssemblerDialect = getParser().getAssemblerDialect();
7102 parseDirectiveReq(Name, NameLoc);
7110 StringRef Mnemonic =
Name.slice(Start,
Next);
7116 unsigned ProcessorIMod;
7119 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
7120 CarrySetting, ProcessorIMod, ITMask);
7123 if (isThumbOne() && PredicationCode !=
ARMCC::AL && Mnemonic !=
"b") {
7124 return Error(NameLoc,
"conditional execution not supported in Thumb1");
7127 Operands.
push_back(ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7140 if (Mnemonic ==
"it" || Mnemonic.
starts_with(
"vpt") ||
7143 Mnemonic ==
"vpt" ? SMLoc::getFromPointer(NameLoc.
getPointer() + 3) :
7144 SMLoc::getFromPointer(NameLoc.
getPointer() + 4);
7145 if (ITMask.
size() > 3) {
7146 if (Mnemonic ==
"it")
7147 return Error(Loc,
"too many conditions on IT instruction");
7148 return Error(Loc,
"too many conditions on VPT instruction");
7152 if (Pos !=
't' && Pos !=
'e') {
7153 return Error(Loc,
"illegal IT block condition mask '" + ITMask +
"'");
7159 Operands.
push_back(ARMOperand::CreateITMask(Mask, Loc, *
this));
7172 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
7173 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
7174 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
7178 if (!CanAcceptCarrySet && CarrySetting) {
7179 return Error(NameLoc,
"instruction '" + Mnemonic +
7180 "' can not set flags, but 's' suffix specified");
7184 if (!CanAcceptPredicationCode && PredicationCode !=
ARMCC::AL) {
7185 return Error(NameLoc,
"instruction '" + Mnemonic +
7186 "' is not predicable, but condition code specified");
7191 if (!CanAcceptVPTPredicationCode && VPTPredicationCode !=
ARMVCC::None) {
7192 return Error(NameLoc,
"instruction '" + Mnemonic +
7193 "' is not VPT predicable, but VPT code T/E is specified");
7197 if (CanAcceptCarrySet && CarrySetting) {
7199 Operands.
push_back(ARMOperand::CreateCCOut(
7200 CarrySetting ? ARM::CPSR : ARM::NoRegister, Loc, *
this));
7207 Operands.
push_back(ARMOperand::CreateCondCode(
7215 !(Mnemonic.
starts_with(
"vcvt") && Mnemonic !=
"vcvta" &&
7216 Mnemonic !=
"vcvtn" && Mnemonic !=
"vcvtp" && Mnemonic !=
"vcvtm")) {
7219 Operands.
push_back(ARMOperand::CreateVPTPred(
7224 if (ProcessorIMod) {
7225 Operands.
push_back(ARMOperand::CreateImm(
7228 }
else if (Mnemonic ==
"cps" && isMClass()) {
7229 return Error(NameLoc,
"instruction 'cps' requires effect for M-class");
7236 ExtraToken =
Name.slice(Start,
Next);
7245 if (ExtraToken ==
".n" && !
isThumb()) {
7247 return Error(Loc,
"instruction with .n (narrow) qualifier not allowed in "
7254 if (ExtraToken !=
".n" && (
isThumb() || ExtraToken !=
".w")) {
7256 Operands.
push_back(ARMOperand::CreateToken(ExtraToken, Loc, *
this));
7263 unsigned MnemonicOpsEndInd = Operands.
size();
7268 if (parseOperand(Operands, Mnemonic)) {
7274 if (parseOperand(Operands, Mnemonic)) {
7283 tryConvertingToTwoOperandForm(Mnemonic, PredicationCode, CarrySetting,
7284 Operands, MnemonicOpsEndInd);
7286 if (hasCDE() && MS.isCDEInstr(Mnemonic)) {
7294 if (MS.isCDEDualRegInstr(Mnemonic)) {
7296 CDEConvertDualRegOperand(Mnemonic, Operands, MnemonicOpsEndInd);
7303 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7304 MnemonicOpsEndInd) &&
7305 Mnemonic ==
"vmov" && PredicationCode ==
ARMCC::LT) {
7313 Mnemonic.
size() - 1 + CarrySetting);
7316 Operands.
insert(Operands.
begin(), ARMOperand::CreateToken(
7317 StringRef(
"vmovlt"), MLoc, *
this));
7318 }
else if (Mnemonic ==
"vcvt" && PredicationCode ==
ARMCC::NE &&
7319 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7320 MnemonicOpsEndInd)) {
7329 Mnemonic.
size() - 1 + CarrySetting);
7333 ARMOperand::CreateToken(StringRef(
"vcvtn"), MLoc, *
this));
7334 }
else if (Mnemonic ==
"vmul" && PredicationCode ==
ARMCC::LT &&
7335 !shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7336 MnemonicOpsEndInd)) {
7343 Operands.
insert(Operands.
begin(), ARMOperand::CreateToken(
7344 StringRef(
"vmullt"), MLoc, *
this));
7349 if (!shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7350 MnemonicOpsEndInd)) {
7357 if (Mnemonic.
starts_with(
"vcvtt") && MnemonicOpsEndInd > 2) {
7359 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd - 2]);
7361 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd - 1]);
7362 if (!(Sz1.isToken() && Sz1.getToken().starts_with(
".f") &&
7363 Sz2.isToken() && Sz2.getToken().starts_with(
".f"))) {
7368 Mnemonic = Mnemonic.
substr(0, 4);
7370 ARMOperand::CreateToken(Mnemonic, MLoc, *
this));
7374 Mnemonic.
size() + CarrySetting);
7377 ARMOperand::CreateVPTPred(
7379 ++MnemonicOpsEndInd;
7381 }
else if (CanAcceptVPTPredicationCode) {
7385 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands,
7386 MnemonicOpsEndInd)) {
7393 bool usedVPTPredicationCode =
false;
7394 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7395 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred())
7396 usedVPTPredicationCode =
true;
7397 if (!usedVPTPredicationCode) {
7405 Mnemonic =
Name.slice(0, Mnemonic.
size() + 1);
7408 ARMOperand::CreateToken(Mnemonic, NameLoc, *
this));
7417 if (!
isThumb() && Mnemonic ==
"blx" &&
7418 Operands.
size() == MnemonicOpsEndInd + 1 &&
7419 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).isImm())
7423 fixupGNULDRDAlias(Mnemonic, Operands, MnemonicOpsEndInd);
7432 bool IsLoad = (Mnemonic ==
"ldrexd" || Mnemonic ==
"ldaexd");
7433 if (!
isThumb() && Operands.
size() > MnemonicOpsEndInd + 1 + (!IsLoad) &&
7434 (Mnemonic ==
"ldrexd" || Mnemonic ==
"strexd" || Mnemonic ==
"ldaexd" ||
7435 Mnemonic ==
"stlexd")) {
7436 unsigned Idx = IsLoad ? MnemonicOpsEndInd : MnemonicOpsEndInd + 1;
7437 ARMOperand &Op1 =
static_cast<ARMOperand &
>(*Operands[Idx]);
7438 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*Operands[Idx + 1]);
7440 const MCRegisterClass &MRC = MRI->
getRegClass(ARM::GPRRegClassID);
7442 if (Op1.isReg() && MRC.
contains(Op1.getReg())) {
7443 MCRegister Reg1 = Op1.getReg();
7445 MCRegister Reg2 = Op2.getReg();
7449 return Error(Op2.getStartLoc(),
7450 IsLoad ?
"destination operands must be sequential"
7451 :
"source operands must be sequential");
7457 IsLoad ?
"destination operands must start start at an even register"
7458 :
"source operands must start start at an even register");
7461 Reg1, ARM::gsub_0, &(MRI->
getRegClass(ARM::GPRPairRegClassID)));
7462 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7463 Op2.getEndLoc(), *
this);
7473 if (isThumbTwo() && Mnemonic ==
"sub" &&
7474 Operands.
size() == MnemonicOpsEndInd + 3 &&
7475 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).isReg() &&
7476 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]).getReg() ==
7478 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]).isReg() &&
7479 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]).getReg() ==
7481 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 2]).isImm()) {
7482 Operands.
front() = ARMOperand::CreateToken(Name, NameLoc, *
this);
7522 return Inst.
getOpcode() == ARM::tBKPT ||
7529 unsigned MnemonicOpsEndInd) {
7530 for (
unsigned I = MnemonicOpsEndInd;
I < Operands.
size(); ++
I) {
7531 const ARMOperand &
Op =
static_cast<const ARMOperand &
>(*Operands[
I]);
7532 if (
Op.isRegList()) {
7539bool ARMAsmParser::validatetLDMRegList(
const MCInst &Inst,
7541 unsigned MnemonicOpsEndInd,
7542 unsigned ListIndex,
bool IsARPop) {
7547 if (!IsARPop && ListContainsSP)
7549 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7550 "SP may not be in the register list");
7551 if (ListContainsPC && ListContainsLR)
7553 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7554 "PC and LR may not be in the register list simultaneously");
7558bool ARMAsmParser::validatetSTMRegList(
const MCInst &Inst,
7560 unsigned MnemonicOpsEndInd,
7561 unsigned ListIndex) {
7565 if (ListContainsSP && ListContainsPC)
7567 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7568 "SP and PC may not be in the register list");
7571 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7572 "SP may not be in the register list");
7575 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
7576 "PC may not be in the register list");
7580bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst,
const OperandVector &Operands,
7581 bool Load,
bool ARMMode,
bool Writeback,
7582 unsigned MnemonicOpsEndInd) {
7583 unsigned RtIndex =
Load || !Writeback ? 0 : 1;
7590 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7595 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7596 "Rt must be even-numbered");
7599 if (Rt2 != Rt + 1) {
7601 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7602 "destination operands must be sequential");
7604 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7605 "source operands must be sequential");
7612 if (!ARMMode && Load) {
7614 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7615 "destination operands can't be identical");
7621 if (Rn == Rt || Rn == Rt2) {
7623 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7624 "base register needs to be different from destination "
7627 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7628 "source register and base register can't be identical");
7639 for (
unsigned i = 0; i <
MCID.NumOperands; ++i) {
7651 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
7658bool ARMAsmParser::validateInstruction(MCInst &Inst,
7660 unsigned MnemonicOpsEndInd) {
7661 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
7662 SMLoc Loc = Operands[0]->getStartLoc();
7670 return Error(Loc,
"instructions in IT block must be predicable");
7673 if (
Cond != currentITCond()) {
7675 SMLoc CondLoc = Operands[0]->getEndLoc();
7676 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7677 if (
static_cast<ARMOperand &
>(*Operands[
I]).isCondCode())
7678 CondLoc = Operands[
I]->getStartLoc();
7679 return Error(CondLoc,
"incorrect condition in IT block; got '" +
7681 "', but expected '" +
7690 return Error(Loc,
"predicated instructions must be in IT block");
7694 return Warning(Loc,
"predicated instructions should be in IT block");
7701 if (MCID.
operands()[i].isPredicate()) {
7703 return Error(Loc,
"instruction is not predicable");
7711 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
7712 return Error(Loc,
"instruction must be outside of IT block or the last instruction in an IT block");
7716 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
7718 return Error(Loc,
"instruction in VPT block must be predicable");
7721 if (Pred != VPTPred) {
7723 for (
unsigned I = 1;
I < Operands.
size(); ++
I)
7724 if (
static_cast<ARMOperand &
>(*Operands[
I]).isVPTPred())
7725 PredLoc = Operands[
I]->getStartLoc();
7726 return Error(PredLoc,
"incorrect predication in VPT block; got '" +
7728 "', but expected '" +
7735 return Error(Loc,
"VPT predicated instructions must be in VPT block");
7737 const unsigned Opcode = Inst.
getOpcode();
7742 case ARM::VLSTM_T2: {
7745 if (Operands.
size() ==
7746 MnemonicOpsEndInd + 2) {
7747 ARMOperand &
Op =
static_cast<ARMOperand &
>(
7748 *Operands[MnemonicOpsEndInd + 1]);
7750 auto &RegList =
Op.getRegList();
7752 if (RegList.size() == 32 && !hasV8_1MMainline()) {
7753 return Error(
Op.getEndLoc(),
"T2 version requires v8.1-M.Main");
7756 if (hasD32() && RegList.size() != 32) {
7757 return Error(
Op.getEndLoc(),
"operand must be exactly {d0-d31}");
7760 if (!hasD32() && (RegList.size() != 16 && RegList.size() != 32)) {
7762 "operand must be exactly {d0-d15} (T1) or {d0-d31} (T2)");
7778 return Error(Loc,
"unpredictable IT predicate sequence");
7782 if (validateLDRDSTRD(Inst, Operands,
true,
true,
7783 false, MnemonicOpsEndInd))
7787 case ARM::LDRD_POST:
7788 if (validateLDRDSTRD(Inst, Operands,
true,
true,
7789 true, MnemonicOpsEndInd))
7793 if (validateLDRDSTRD(Inst, Operands,
true,
false,
7794 false, MnemonicOpsEndInd))
7797 case ARM::t2LDRD_PRE:
7798 case ARM::t2LDRD_POST:
7799 if (validateLDRDSTRD(Inst, Operands,
true,
false,
7800 true, MnemonicOpsEndInd))
7806 if (RmReg == ARM::SP && !hasV8Ops())
7807 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7808 "r13 (SP) is an unpredictable operand to BXJ");
7812 if (validateLDRDSTRD(Inst, Operands,
false,
true,
7813 false, MnemonicOpsEndInd))
7817 case ARM::STRD_POST:
7818 if (validateLDRDSTRD(Inst, Operands,
false,
true,
7819 true, MnemonicOpsEndInd))
7822 case ARM::t2STRD_PRE:
7823 case ARM::t2STRD_POST:
7824 if (validateLDRDSTRD(Inst, Operands,
false,
false,
7825 true, MnemonicOpsEndInd))
7828 case ARM::STR_PRE_IMM:
7829 case ARM::STR_PRE_REG:
7830 case ARM::t2STR_PRE:
7831 case ARM::STR_POST_IMM:
7832 case ARM::STR_POST_REG:
7833 case ARM::t2STR_POST:
7835 case ARM::t2STRH_PRE:
7836 case ARM::STRH_POST:
7837 case ARM::t2STRH_POST:
7838 case ARM::STRB_PRE_IMM:
7839 case ARM::STRB_PRE_REG:
7840 case ARM::t2STRB_PRE:
7841 case ARM::STRB_POST_IMM:
7842 case ARM::STRB_POST_REG:
7843 case ARM::t2STRB_POST: {
7849 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7850 "source register and base register can't be identical");
7853 case ARM::t2LDR_PRE_imm:
7854 case ARM::t2LDR_POST_imm:
7855 case ARM::t2STR_PRE_imm:
7856 case ARM::t2STR_POST_imm: {
7862 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7863 "destination register and base register can't be identical");
7864 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7865 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7867 if (Imm > 255 || Imm < -255)
7868 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7869 "operand must be in range [-255, 255]");
7871 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7872 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7874 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7875 "operand must be a register in range [r0, r14]");
7881 case ARM::t2LDRB_OFFSET_imm:
7882 case ARM::t2LDRB_PRE_imm:
7883 case ARM::t2LDRB_POST_imm:
7884 case ARM::t2STRB_OFFSET_imm:
7885 case ARM::t2STRB_PRE_imm:
7886 case ARM::t2STRB_POST_imm: {
7887 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7888 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7889 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7890 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7892 if (Imm > 255 || Imm < -255)
7893 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7894 "operand must be in range [-255, 255]");
7895 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7896 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7898 if (Imm > 0 || Imm < -255)
7899 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7900 "operand must be in range [0, 255] with a negative sign");
7903 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7904 "if operand is PC, should call the LDRB (literal)");
7909 case ARM::t2LDRH_OFFSET_imm:
7910 case ARM::t2LDRH_PRE_imm:
7911 case ARM::t2LDRH_POST_imm:
7912 case ARM::t2STRH_OFFSET_imm:
7913 case ARM::t2STRH_PRE_imm:
7914 case ARM::t2STRH_POST_imm: {
7915 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7916 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7917 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7918 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7920 if (Imm > 255 || Imm < -255)
7921 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7922 "operand must be in range [-255, 255]");
7923 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7924 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7926 if (Imm > 0 || Imm < -255)
7927 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7928 "operand must be in range [0, 255] with a negative sign");
7931 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7932 "if operand is PC, should call the LDRH (literal)");
7937 case ARM::t2LDRSB_OFFSET_imm:
7938 case ARM::t2LDRSB_PRE_imm:
7939 case ARM::t2LDRSB_POST_imm: {
7940 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7941 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7943 if (Imm > 255 || Imm < -255)
7944 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7945 "operand must be in range [-255, 255]");
7946 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7948 if (Imm > 0 || Imm < -255)
7949 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7950 "operand must be in range [0, 255] with a negative sign");
7953 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7954 "if operand is PC, should call the LDRH (literal)");
7959 case ARM::t2LDRSH_OFFSET_imm:
7960 case ARM::t2LDRSH_PRE_imm:
7961 case ARM::t2LDRSH_POST_imm: {
7962 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7963 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7965 if (Imm > 255 || Imm < -255)
7966 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7967 "operand must be in range [-255, 255]");
7968 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7970 if (Imm > 0 || Imm < -255)
7971 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7972 "operand must be in range [0, 255] with a negative sign");
7975 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
7976 "if operand is PC, should call the LDRH (literal)");
7981 case ARM::LDR_PRE_IMM:
7982 case ARM::LDR_PRE_REG:
7983 case ARM::t2LDR_PRE:
7984 case ARM::LDR_POST_IMM:
7985 case ARM::LDR_POST_REG:
7986 case ARM::t2LDR_POST:
7988 case ARM::t2LDRH_PRE:
7989 case ARM::LDRH_POST:
7990 case ARM::t2LDRH_POST:
7991 case ARM::LDRSH_PRE:
7992 case ARM::t2LDRSH_PRE:
7993 case ARM::LDRSH_POST:
7994 case ARM::t2LDRSH_POST:
7995 case ARM::LDRB_PRE_IMM:
7996 case ARM::LDRB_PRE_REG:
7997 case ARM::t2LDRB_PRE:
7998 case ARM::LDRB_POST_IMM:
7999 case ARM::LDRB_POST_REG:
8000 case ARM::t2LDRB_POST:
8001 case ARM::LDRSB_PRE:
8002 case ARM::t2LDRSB_PRE:
8003 case ARM::LDRSB_POST:
8004 case ARM::t2LDRSB_POST: {
8010 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8011 "destination register and base register can't be identical");
8015 case ARM::MVE_VLDRBU8_rq:
8016 case ARM::MVE_VLDRBU16_rq:
8017 case ARM::MVE_VLDRBS16_rq:
8018 case ARM::MVE_VLDRBU32_rq:
8019 case ARM::MVE_VLDRBS32_rq:
8020 case ARM::MVE_VLDRHU16_rq:
8021 case ARM::MVE_VLDRHU16_rq_u:
8022 case ARM::MVE_VLDRHU32_rq:
8023 case ARM::MVE_VLDRHU32_rq_u:
8024 case ARM::MVE_VLDRHS32_rq:
8025 case ARM::MVE_VLDRHS32_rq_u:
8026 case ARM::MVE_VLDRWU32_rq:
8027 case ARM::MVE_VLDRWU32_rq_u:
8028 case ARM::MVE_VLDRDU64_rq:
8029 case ARM::MVE_VLDRDU64_rq_u:
8030 case ARM::MVE_VLDRWU32_qi:
8031 case ARM::MVE_VLDRWU32_qi_pre:
8032 case ARM::MVE_VLDRDU64_qi:
8033 case ARM::MVE_VLDRDU64_qi_pre: {
8035 unsigned QdIdx = 0, QmIdx = 2;
8036 bool QmIsPointer =
false;
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRDU64_qi:
8043 case ARM::MVE_VLDRWU32_qi_pre:
8044 case ARM::MVE_VLDRDU64_qi_pre:
8054 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8055 Twine(
"destination vector register and vector ") +
8056 (QmIsPointer ?
"pointer" :
"offset") +
8057 " register can't be identical");
8069 if (Widthm1 >= 32 - LSB)
8070 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8071 "bitfield width must be in range [1,32-lsb]");
8083 bool HasWritebackToken =
8084 (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8086 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8089 bool ListContainsBase;
8093 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8094 "registers must be in range r0-r7");
8096 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8098 Operands[
getRegListInd(Operands, MnemonicOpsEndInd)]->getStartLoc(),
8099 "writeback operator '!' expected");
8102 if (ListContainsBase && HasWritebackToken)
8103 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8104 "writeback operator '!' not allowed when base register "
8105 "in register list");
8107 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8111 case ARM::LDMIA_UPD:
8112 case ARM::LDMDB_UPD:
8113 case ARM::LDMIB_UPD:
8114 case ARM::LDMDA_UPD:
8120 return Error(Operands.
back()->getStartLoc(),
8121 "writeback register not allowed in register list");
8125 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8130 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8133 case ARM::t2LDMIA_UPD:
8134 case ARM::t2LDMDB_UPD:
8135 case ARM::t2STMIA_UPD:
8136 case ARM::t2STMDB_UPD:
8138 return Error(Operands.
back()->getStartLoc(),
8139 "writeback register not allowed in register list");
8141 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8142 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8145 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 3))
8150 case ARM::sysLDMIA_UPD:
8151 case ARM::sysLDMDA_UPD:
8152 case ARM::sysLDMDB_UPD:
8153 case ARM::sysLDMIB_UPD:
8155 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8156 "writeback register only allowed on system LDM "
8157 "if PC in register-list");
8159 case ARM::sysSTMIA_UPD:
8160 case ARM::sysSTMDA_UPD:
8161 case ARM::sysSTMDB_UPD:
8162 case ARM::sysSTMIB_UPD:
8163 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8164 "system STM cannot have writeback register");
8169 bool ListContainsBase;
8171 ListContainsBase) &&
8173 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8174 "registers must be in range r0-r7 or pc");
8175 if (validatetLDMRegList(Inst, Operands, MnemonicOpsEndInd, 2, !isMClass()))
8180 bool ListContainsBase;
8182 ListContainsBase) &&
8184 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8185 "registers must be in range r0-r7 or lr");
8186 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 2))
8190 case ARM::tSTMIA_UPD: {
8191 bool ListContainsBase, InvalidLowList;
8193 0, ListContainsBase);
8194 if (InvalidLowList && !isThumbTwo())
8195 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8196 "registers must be in range r0-r7");
8200 if (InvalidLowList && ListContainsBase)
8201 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8202 "writeback operator '!' not allowed when base register "
8203 "in register list");
8205 if (validatetSTMRegList(Inst, Operands, MnemonicOpsEndInd, 4))
8212 if (!isThumbTwo() &&
8214 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8215 "source register must be the same as destination");
8225 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8226 "source register must be sp if destination is sp");
8231 if (!(
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd]))
8232 .isSignedOffset<11, 1>())
8233 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8234 "branch target out of range");
8237 int op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8238 : MnemonicOpsEndInd + 1;
8239 ARMOperand &Operand =
static_cast<ARMOperand &
>(*Operands[
op]);
8242 !Operand.isSignedOffset<24, 1>())
8243 return Error(Operands[
op]->getStartLoc(),
"branch target out of range");
8248 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8249 .isSignedOffset<8, 1>())
8250 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8251 "branch target out of range");
8254 int Op = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8255 : MnemonicOpsEndInd + 1;
8256 if (!
static_cast<ARMOperand &
>(*Operands[
Op]).isSignedOffset<20, 1>())
8257 return Error(Operands[
Op]->getStartLoc(),
"branch target out of range");
8262 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8263 .isUnsignedOffset<6, 1>())
8264 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8265 "branch target out of range");
8271 case ARM::t2MOVTi16:
8279 int i = (Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8280 : MnemonicOpsEndInd + 1;
8281 ARMOperand &
Op =
static_cast<ARMOperand &
>(*Operands[i]);
8282 const MCExpr *
E =
Op.getImm();
8286 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8290 "immediate expression for mov requires :lower16: or :upper16");
8294 int i = (Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8295 : MnemonicOpsEndInd + 2;
8296 MCParsedAsmOperand &
Op = *Operands[i];
8298 return Error(
Op.getStartLoc(),
8299 "Immediate expression for Thumb adds requires :lower0_7:,"
8300 " :lower8_15:, :upper0_7: or :upper8_15:");
8304 MCParsedAsmOperand &
Op = *Operands[MnemonicOpsEndInd + 1];
8306 return Error(
Op.getStartLoc(),
8307 "Immediate expression for Thumb movs requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8317 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
8318 return Error(Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8319 "predicable, but condition "
8322 return Error(Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8323 "predicable, but condition "
8331 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8332 .isUnsignedOffset<4, 1>() ||
8334 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8335 "branch location out of range or not a multiple of 2");
8338 if (Opcode == ARM::t2BFi) {
8339 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8340 .isSignedOffset<16, 1>())
8341 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8342 "branch target out of range or not a multiple of 2");
8343 }
else if (Opcode == ARM::t2BFLi) {
8344 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8345 .isSignedOffset<18, 1>())
8346 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8347 "branch target out of range or not a multiple of 2");
8352 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd])
8353 .isUnsignedOffset<4, 1>() ||
8355 return Error(Operands[1]->getStartLoc(),
8356 "branch location out of range or not a multiple of 2");
8358 if (!
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8359 .isSignedOffset<16, 1>())
8360 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8361 "branch target out of range or not a multiple of 2");
8364 "branch location and else branch target should either both be "
8365 "immediates or both labels");
8369 if (Diff != 4 && Diff != 2)
8371 Operands[3]->getStartLoc(),
8372 "else branch target must be 2 or 4 greater than the branch location");
8379 !ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(
8381 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8382 "invalid register in register list. Valid registers are "
8383 "r0-r12, lr/r14 and APSR.");
8399 return Error(Operands[1]->getStartLoc(),
8400 "instruction 'ssbb' is not predicable, but condition code "
8403 return Error(Operands[1]->getStartLoc(),
8404 "instruction 'pssbb' is not predicable, but condition code "
8408 case ARM::VMOVRRS: {
8413 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8414 "source operands must be sequential");
8417 case ARM::VMOVSRR: {
8422 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8423 "destination operands must be sequential");
8427 case ARM::VSTMDIA: {
8429 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
8430 auto &RegList =
Op.getRegList();
8431 if (RegList.size() < 1 || RegList.size() > 16)
8432 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8433 "list of registers must be at least 1 and at most 16");
8436 case ARM::MVE_VQDMULLs32bh:
8437 case ARM::MVE_VQDMULLs32th:
8438 case ARM::MVE_VCMULf32:
8439 case ARM::MVE_VMULLBs32:
8440 case ARM::MVE_VMULLTs32:
8441 case ARM::MVE_VMULLBu32:
8442 case ARM::MVE_VMULLTu32: {
8443 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8444 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8445 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8446 "Qd register and Qn register can't be identical");
8448 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8449 Operands[MnemonicOpsEndInd + 2]->
getReg()) {
8450 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8451 "Qd register and Qm register can't be identical");
8455 case ARM::MVE_VREV64_8:
8456 case ARM::MVE_VREV64_16:
8457 case ARM::MVE_VREV64_32:
8458 case ARM::MVE_VQDMULL_qr_s32bh:
8459 case ARM::MVE_VQDMULL_qr_s32th: {
8460 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8461 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8462 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8463 "Qd register and Qn register can't be identical");
8467 case ARM::MVE_VCADDi32:
8468 case ARM::MVE_VCADDf32:
8469 case ARM::MVE_VHCADDs32: {
8470 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8471 Operands[MnemonicOpsEndInd + 2]->
getReg()) {
8472 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8473 "Qd register and Qm register can't be identical");
8477 case ARM::MVE_VMOV_rr_q: {
8478 if (Operands[MnemonicOpsEndInd + 2]->
getReg() !=
8479 Operands[MnemonicOpsEndInd + 4]->
getReg())
8480 return Error(Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8481 "Q-registers must be the same");
8482 if (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 3])
8483 .getVectorIndex() !=
8484 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 5])
8487 return Error(Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8488 "Q-register indexes must be 2 and 0 or 3 and 1");
8491 case ARM::MVE_VMOV_q_rr: {
8492 if (Operands[MnemonicOpsEndInd]->
getReg() !=
8493 Operands[MnemonicOpsEndInd + 2]->
getReg())
8494 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8495 "Q-registers must be the same");
8496 if (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
8497 .getVectorIndex() !=
8498 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 3])
8501 return Error(Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8502 "Q-register indexes must be 2 and 0 or 3 and 1");
8505 case ARM::MVE_SQRSHR:
8506 case ARM::MVE_UQRSHL: {
8507 if (Operands[MnemonicOpsEndInd]->
getReg() ==
8508 Operands[MnemonicOpsEndInd + 1]->
getReg()) {
8509 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8510 "Rda register and Rm register can't be identical");
8531 case ARM::t2SMLALBB:
8532 case ARM::t2SMLALBT:
8534 case ARM::t2SMLALDX:
8535 case ARM::t2SMLALTB:
8536 case ARM::t2SMLALTT:
8538 case ARM::t2SMLSLDX:
8539 case ARM::t2SMULL: {
8544 "unpredictable instruction, RdHi and RdLo must be different");
8552 case ARM::CDE_CX1DA:
8556 case ARM::CDE_CX2DA:
8560 case ARM::CDE_CX3DA:
8561 case ARM::CDE_VCX1_vec:
8562 case ARM::CDE_VCX1_fpsp:
8563 case ARM::CDE_VCX1_fpdp:
8564 case ARM::CDE_VCX1A_vec:
8565 case ARM::CDE_VCX1A_fpsp:
8566 case ARM::CDE_VCX1A_fpdp:
8567 case ARM::CDE_VCX2_vec:
8568 case ARM::CDE_VCX2_fpsp:
8569 case ARM::CDE_VCX2_fpdp:
8570 case ARM::CDE_VCX2A_vec:
8571 case ARM::CDE_VCX2A_fpsp:
8572 case ARM::CDE_VCX2A_fpdp:
8573 case ARM::CDE_VCX3_vec:
8574 case ARM::CDE_VCX3_fpsp:
8575 case ARM::CDE_VCX3_fpdp:
8576 case ARM::CDE_VCX3A_vec:
8577 case ARM::CDE_VCX3A_fpsp:
8578 case ARM::CDE_VCX3A_fpdp: {
8580 "CDE operand 1 must be a coprocessor ID");
8583 return Error(Operands[1]->getStartLoc(),
8584 "coprocessor must be configured as CDE");
8585 else if (Coproc >= 8)
8586 return Error(Operands[1]->getStartLoc(),
8587 "coprocessor must be in the range [p0, p7]");
8593 case ARM::t2LDC2L_OFFSET:
8594 case ARM::t2LDC2L_OPTION:
8595 case ARM::t2LDC2L_POST:
8596 case ARM::t2LDC2L_PRE:
8597 case ARM::t2LDC2_OFFSET:
8598 case ARM::t2LDC2_OPTION:
8599 case ARM::t2LDC2_POST:
8600 case ARM::t2LDC2_PRE:
8601 case ARM::t2LDCL_OFFSET:
8602 case ARM::t2LDCL_OPTION:
8603 case ARM::t2LDCL_POST:
8604 case ARM::t2LDCL_PRE:
8605 case ARM::t2LDC_OFFSET:
8606 case ARM::t2LDC_OPTION:
8607 case ARM::t2LDC_POST:
8608 case ARM::t2LDC_PRE:
8617 case ARM::t2STC2L_OFFSET:
8618 case ARM::t2STC2L_OPTION:
8619 case ARM::t2STC2L_POST:
8620 case ARM::t2STC2L_PRE:
8621 case ARM::t2STC2_OFFSET:
8622 case ARM::t2STC2_OPTION:
8623 case ARM::t2STC2_POST:
8624 case ARM::t2STC2_PRE:
8625 case ARM::t2STCL_OFFSET:
8626 case ARM::t2STCL_OPTION:
8627 case ARM::t2STCL_POST:
8628 case ARM::t2STCL_PRE:
8629 case ARM::t2STC_OFFSET:
8630 case ARM::t2STC_OPTION:
8631 case ARM::t2STC_POST:
8632 case ARM::t2STC_PRE: {
8637 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8639 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8642 "Operand must be a coprocessor ID");
8646 return Error(Operands[2]->getStartLoc(),
8647 "coprocessor must be configured as GCP");
8675 if (Operands[MnemonicOpsEndInd]->
getReg() !=
8676 Operands[MnemonicOpsEndInd + 1]->
getReg())
8677 return Error(Operands[MnemonicOpsEndInd]->getStartLoc(),
8678 "source and destination registers must be the same");
8690 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8691 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8693 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8694 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8695 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8696 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8697 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8698 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8701 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8702 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8704 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8707 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8708 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8709 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8710 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8711 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8713 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8714 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8715 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8716 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8717 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8720 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8721 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8723 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8725 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8726 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8727 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8728 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8729 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8730 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8731 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8732 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8733 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8734 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8737 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8738 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8739 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8740 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8741 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8742 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8743 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8744 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8745 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8746 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8747 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8748 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8749 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8750 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8751 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8752 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8753 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8754 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8757 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8758 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8760 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8762 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8763 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8764 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8765 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8766 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8767 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8768 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8769 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8770 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8771 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8774 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8775 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8776 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8777 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8778 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8779 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8780 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8781 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8782 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8783 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8784 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8785 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8786 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8787 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8788 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8789 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8790 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8791 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8799 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8800 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8802 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8805 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8806 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8807 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8810 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8811 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8813 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8815 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8818 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8820 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8821 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8822 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8823 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8824 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8827 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8828 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8830 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8833 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8836 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8839 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8840 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8841 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8842 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8843 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8844 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8847 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8848 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8850 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8852 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8855 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8857 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8858 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8859 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8860 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8861 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8864 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8865 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8867 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8870 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8871 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8872 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8873 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8874 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8875 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8876 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8877 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8878 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8879 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8880 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8881 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8884 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8885 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8887 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8889 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8892 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8894 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8895 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8896 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8897 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8898 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8901 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8902 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8904 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8907 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8910 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8913 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8914 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8915 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8916 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8917 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8918 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8921 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8922 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8924 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8927 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8928 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8929 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8930 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8931 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8932 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8933 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8934 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8935 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8936 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8937 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8938 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8942bool ARMAsmParser::processInstruction(MCInst &Inst,
8944 unsigned MnemonicOpsEndInd,
8948 bool HasWideQualifier =
false;
8949 for (
auto &
Op : Operands) {
8950 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8951 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8952 HasWideQualifier =
true;
8962 if (Operands.size() ==
8963 MnemonicOpsEndInd + 2) {
8964 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8965 *Operands[MnemonicOpsEndInd + 1]);
8967 auto &RegList =
Op.getRegList();
8970 if (RegList.size() == 32) {
8971 const unsigned Opcode =
8972 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8986 case ARM::LDRT_POST:
8987 case ARM::LDRBT_POST: {
8988 const unsigned Opcode =
8989 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8990 : ARM::LDRBT_POST_IMM;
9006 case ARM::LDRSHTii: {
9011 else if (Inst.
getOpcode() == ARM::LDRHTii)
9013 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9024 case ARM::STRT_POST:
9025 case ARM::STRBT_POST: {
9026 const unsigned Opcode =
9027 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9028 : ARM::STRBT_POST_IMM;
9077 case ARM::t2LDR_PRE_imm:
9078 case ARM::t2LDR_POST_imm: {
9092 case ARM::t2STR_PRE_imm:
9093 case ARM::t2STR_POST_imm: {
9107 case ARM::t2LDRB_OFFSET_imm: {
9117 case ARM::t2LDRB_PRE_imm:
9118 case ARM::t2LDRB_POST_imm: {
9122 : ARM::t2LDRB_POST);
9133 case ARM::t2STRB_OFFSET_imm: {
9143 case ARM::t2STRB_PRE_imm:
9144 case ARM::t2STRB_POST_imm: {
9148 : ARM::t2STRB_POST);
9159 case ARM::t2LDRH_OFFSET_imm: {
9169 case ARM::t2LDRH_PRE_imm:
9170 case ARM::t2LDRH_POST_imm: {
9174 : ARM::t2LDRH_POST);
9185 case ARM::t2STRH_OFFSET_imm: {
9195 case ARM::t2STRH_PRE_imm:
9196 case ARM::t2STRH_POST_imm: {
9200 : ARM::t2STRH_POST);
9211 case ARM::t2LDRSB_OFFSET_imm: {
9221 case ARM::t2LDRSB_PRE_imm:
9222 case ARM::t2LDRSB_POST_imm: {
9226 : ARM::t2LDRSB_POST);
9237 case ARM::t2LDRSH_OFFSET_imm: {
9247 case ARM::t2LDRSH_PRE_imm:
9248 case ARM::t2LDRSH_POST_imm: {
9252 : ARM::t2LDRSH_POST);
9263 case ARM::t2LDRpcrel:
9272 case ARM::t2LDRBpcrel:
9275 case ARM::t2LDRHpcrel:
9278 case ARM::t2LDRSBpcrel:
9281 case ARM::t2LDRSHpcrel:
9284 case ARM::LDRConstPool:
9285 case ARM::tLDRConstPool:
9286 case ARM::t2LDRConstPool: {
9291 if (Inst.
getOpcode() == ARM::LDRConstPool)
9293 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9295 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9297 const ARMOperand &PoolOperand =
9298 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1]);
9299 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9307 bool MovHasS =
true;
9308 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9318 else if (hasV6T2Ops() &&
9331 else if (hasThumb2() &&
9336 else if (hasV8MBaseline() &&
9356 const MCExpr *CPLoc =
9357 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9358 PoolOperand.getStartLoc());
9369 case ARM::VST1LNdWB_register_Asm_8:
9370 case ARM::VST1LNdWB_register_Asm_16:
9371 case ARM::VST1LNdWB_register_Asm_32: {
9389 case ARM::VST2LNdWB_register_Asm_8:
9390 case ARM::VST2LNdWB_register_Asm_16:
9391 case ARM::VST2LNdWB_register_Asm_32:
9392 case ARM::VST2LNqWB_register_Asm_16:
9393 case ARM::VST2LNqWB_register_Asm_32: {
9413 case ARM::VST3LNdWB_register_Asm_8:
9414 case ARM::VST3LNdWB_register_Asm_16:
9415 case ARM::VST3LNdWB_register_Asm_32:
9416 case ARM::VST3LNqWB_register_Asm_16:
9417 case ARM::VST3LNqWB_register_Asm_32: {
9439 case ARM::VST4LNdWB_register_Asm_8:
9440 case ARM::VST4LNdWB_register_Asm_16:
9441 case ARM::VST4LNdWB_register_Asm_32:
9442 case ARM::VST4LNqWB_register_Asm_16:
9443 case ARM::VST4LNqWB_register_Asm_32: {
9467 case ARM::VST1LNdWB_fixed_Asm_8:
9468 case ARM::VST1LNdWB_fixed_Asm_16:
9469 case ARM::VST1LNdWB_fixed_Asm_32: {
9487 case ARM::VST2LNdWB_fixed_Asm_8:
9488 case ARM::VST2LNdWB_fixed_Asm_16:
9489 case ARM::VST2LNdWB_fixed_Asm_32:
9490 case ARM::VST2LNqWB_fixed_Asm_16:
9491 case ARM::VST2LNqWB_fixed_Asm_32: {
9511 case ARM::VST3LNdWB_fixed_Asm_8:
9512 case ARM::VST3LNdWB_fixed_Asm_16:
9513 case ARM::VST3LNdWB_fixed_Asm_32:
9514 case ARM::VST3LNqWB_fixed_Asm_16:
9515 case ARM::VST3LNqWB_fixed_Asm_32: {
9537 case ARM::VST4LNdWB_fixed_Asm_8:
9538 case ARM::VST4LNdWB_fixed_Asm_16:
9539 case ARM::VST4LNdWB_fixed_Asm_32:
9540 case ARM::VST4LNqWB_fixed_Asm_16:
9541 case ARM::VST4LNqWB_fixed_Asm_32: {
9565 case ARM::VST1LNdAsm_8:
9566 case ARM::VST1LNdAsm_16:
9567 case ARM::VST1LNdAsm_32: {
9583 case ARM::VST2LNdAsm_8:
9584 case ARM::VST2LNdAsm_16:
9585 case ARM::VST2LNdAsm_32:
9586 case ARM::VST2LNqAsm_16:
9587 case ARM::VST2LNqAsm_32: {
9605 case ARM::VST3LNdAsm_8:
9606 case ARM::VST3LNdAsm_16:
9607 case ARM::VST3LNdAsm_32:
9608 case ARM::VST3LNqAsm_16:
9609 case ARM::VST3LNqAsm_32: {
9629 case ARM::VST4LNdAsm_8:
9630 case ARM::VST4LNdAsm_16:
9631 case ARM::VST4LNdAsm_32:
9632 case ARM::VST4LNqAsm_16:
9633 case ARM::VST4LNqAsm_32: {
9656 case ARM::VLD1LNdWB_register_Asm_8:
9657 case ARM::VLD1LNdWB_register_Asm_16:
9658 case ARM::VLD1LNdWB_register_Asm_32: {
9677 case ARM::VLD2LNdWB_register_Asm_8:
9678 case ARM::VLD2LNdWB_register_Asm_16:
9679 case ARM::VLD2LNdWB_register_Asm_32:
9680 case ARM::VLD2LNqWB_register_Asm_16:
9681 case ARM::VLD2LNqWB_register_Asm_32: {
9704 case ARM::VLD3LNdWB_register_Asm_8:
9705 case ARM::VLD3LNdWB_register_Asm_16:
9706 case ARM::VLD3LNdWB_register_Asm_32:
9707 case ARM::VLD3LNqWB_register_Asm_16:
9708 case ARM::VLD3LNqWB_register_Asm_32: {
9735 case ARM::VLD4LNdWB_register_Asm_8:
9736 case ARM::VLD4LNdWB_register_Asm_16:
9737 case ARM::VLD4LNdWB_register_Asm_32:
9738 case ARM::VLD4LNqWB_register_Asm_16:
9739 case ARM::VLD4LNqWB_register_Asm_32: {
9770 case ARM::VLD1LNdWB_fixed_Asm_8:
9771 case ARM::VLD1LNdWB_fixed_Asm_16:
9772 case ARM::VLD1LNdWB_fixed_Asm_32: {
9791 case ARM::VLD2LNdWB_fixed_Asm_8:
9792 case ARM::VLD2LNdWB_fixed_Asm_16:
9793 case ARM::VLD2LNdWB_fixed_Asm_32:
9794 case ARM::VLD2LNqWB_fixed_Asm_16:
9795 case ARM::VLD2LNqWB_fixed_Asm_32: {
9818 case ARM::VLD3LNdWB_fixed_Asm_8:
9819 case ARM::VLD3LNdWB_fixed_Asm_16:
9820 case ARM::VLD3LNdWB_fixed_Asm_32:
9821 case ARM::VLD3LNqWB_fixed_Asm_16:
9822 case ARM::VLD3LNqWB_fixed_Asm_32: {
9849 case ARM::VLD4LNdWB_fixed_Asm_8:
9850 case ARM::VLD4LNdWB_fixed_Asm_16:
9851 case ARM::VLD4LNdWB_fixed_Asm_32:
9852 case ARM::VLD4LNqWB_fixed_Asm_16:
9853 case ARM::VLD4LNqWB_fixed_Asm_32: {
9884 case ARM::VLD1LNdAsm_8:
9885 case ARM::VLD1LNdAsm_16:
9886 case ARM::VLD1LNdAsm_32: {
9903 case ARM::VLD2LNdAsm_8:
9904 case ARM::VLD2LNdAsm_16:
9905 case ARM::VLD2LNdAsm_32:
9906 case ARM::VLD2LNqAsm_16:
9907 case ARM::VLD2LNqAsm_32: {
9928 case ARM::VLD3LNdAsm_8:
9929 case ARM::VLD3LNdAsm_16:
9930 case ARM::VLD3LNdAsm_32:
9931 case ARM::VLD3LNqAsm_16:
9932 case ARM::VLD3LNqAsm_32: {
9957 case ARM::VLD4LNdAsm_8:
9958 case ARM::VLD4LNdAsm_16:
9959 case ARM::VLD4LNdAsm_32:
9960 case ARM::VLD4LNqAsm_16:
9961 case ARM::VLD4LNqAsm_32: {
9991 case ARM::VLD3DUPdAsm_8:
9992 case ARM::VLD3DUPdAsm_16:
9993 case ARM::VLD3DUPdAsm_32:
9994 case ARM::VLD3DUPqAsm_8:
9995 case ARM::VLD3DUPqAsm_16:
9996 case ARM::VLD3DUPqAsm_32: {
10013 case ARM::VLD3DUPdWB_fixed_Asm_8:
10014 case ARM::VLD3DUPdWB_fixed_Asm_16:
10015 case ARM::VLD3DUPdWB_fixed_Asm_32:
10016 case ARM::VLD3DUPqWB_fixed_Asm_8:
10017 case ARM::VLD3DUPqWB_fixed_Asm_16:
10018 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10037 case ARM::VLD3DUPdWB_register_Asm_8:
10038 case ARM::VLD3DUPdWB_register_Asm_16:
10039 case ARM::VLD3DUPdWB_register_Asm_32:
10040 case ARM::VLD3DUPqWB_register_Asm_8:
10041 case ARM::VLD3DUPqWB_register_Asm_16:
10042 case ARM::VLD3DUPqWB_register_Asm_32: {
10062 case ARM::VLD3dAsm_8:
10063 case ARM::VLD3dAsm_16:
10064 case ARM::VLD3dAsm_32:
10065 case ARM::VLD3qAsm_8:
10066 case ARM::VLD3qAsm_16:
10067 case ARM::VLD3qAsm_32: {
10084 case ARM::VLD3dWB_fixed_Asm_8:
10085 case ARM::VLD3dWB_fixed_Asm_16:
10086 case ARM::VLD3dWB_fixed_Asm_32:
10087 case ARM::VLD3qWB_fixed_Asm_8:
10088 case ARM::VLD3qWB_fixed_Asm_16:
10089 case ARM::VLD3qWB_fixed_Asm_32: {
10108 case ARM::VLD3dWB_register_Asm_8:
10109 case ARM::VLD3dWB_register_Asm_16:
10110 case ARM::VLD3dWB_register_Asm_32:
10111 case ARM::VLD3qWB_register_Asm_8:
10112 case ARM::VLD3qWB_register_Asm_16:
10113 case ARM::VLD3qWB_register_Asm_32: {
10133 case ARM::VLD4DUPdAsm_8:
10134 case ARM::VLD4DUPdAsm_16:
10135 case ARM::VLD4DUPdAsm_32:
10136 case ARM::VLD4DUPqAsm_8:
10137 case ARM::VLD4DUPqAsm_16:
10138 case ARM::VLD4DUPqAsm_32: {
10157 case ARM::VLD4DUPdWB_fixed_Asm_8:
10158 case ARM::VLD4DUPdWB_fixed_Asm_16:
10159 case ARM::VLD4DUPdWB_fixed_Asm_32:
10160 case ARM::VLD4DUPqWB_fixed_Asm_8:
10161 case ARM::VLD4DUPqWB_fixed_Asm_16:
10162 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10183 case ARM::VLD4DUPdWB_register_Asm_8:
10184 case ARM::VLD4DUPdWB_register_Asm_16:
10185 case ARM::VLD4DUPdWB_register_Asm_32:
10186 case ARM::VLD4DUPqWB_register_Asm_8:
10187 case ARM::VLD4DUPqWB_register_Asm_16:
10188 case ARM::VLD4DUPqWB_register_Asm_32: {
10210 case ARM::VLD4dAsm_8:
10211 case ARM::VLD4dAsm_16:
10212 case ARM::VLD4dAsm_32:
10213 case ARM::VLD4qAsm_8:
10214 case ARM::VLD4qAsm_16:
10215 case ARM::VLD4qAsm_32: {
10234 case ARM::VLD4dWB_fixed_Asm_8:
10235 case ARM::VLD4dWB_fixed_Asm_16:
10236 case ARM::VLD4dWB_fixed_Asm_32:
10237 case ARM::VLD4qWB_fixed_Asm_8:
10238 case ARM::VLD4qWB_fixed_Asm_16:
10239 case ARM::VLD4qWB_fixed_Asm_32: {
10260 case ARM::VLD4dWB_register_Asm_8:
10261 case ARM::VLD4dWB_register_Asm_16:
10262 case ARM::VLD4dWB_register_Asm_32:
10263 case ARM::VLD4qWB_register_Asm_8:
10264 case ARM::VLD4qWB_register_Asm_16:
10265 case ARM::VLD4qWB_register_Asm_32: {
10287 case ARM::VST3dAsm_8:
10288 case ARM::VST3dAsm_16:
10289 case ARM::VST3dAsm_32:
10290 case ARM::VST3qAsm_8:
10291 case ARM::VST3qAsm_16:
10292 case ARM::VST3qAsm_32: {
10309 case ARM::VST3dWB_fixed_Asm_8:
10310 case ARM::VST3dWB_fixed_Asm_16:
10311 case ARM::VST3dWB_fixed_Asm_32:
10312 case ARM::VST3qWB_fixed_Asm_8:
10313 case ARM::VST3qWB_fixed_Asm_16:
10314 case ARM::VST3qWB_fixed_Asm_32: {
10333 case ARM::VST3dWB_register_Asm_8:
10334 case ARM::VST3dWB_register_Asm_16:
10335 case ARM::VST3dWB_register_Asm_32:
10336 case ARM::VST3qWB_register_Asm_8:
10337 case ARM::VST3qWB_register_Asm_16:
10338 case ARM::VST3qWB_register_Asm_32: {
10358 case ARM::VST4dAsm_8:
10359 case ARM::VST4dAsm_16:
10360 case ARM::VST4dAsm_32:
10361 case ARM::VST4qAsm_8:
10362 case ARM::VST4qAsm_16:
10363 case ARM::VST4qAsm_32: {
10382 case ARM::VST4dWB_fixed_Asm_8:
10383 case ARM::VST4dWB_fixed_Asm_16:
10384 case ARM::VST4dWB_fixed_Asm_32:
10385 case ARM::VST4qWB_fixed_Asm_8:
10386 case ARM::VST4qWB_fixed_Asm_16:
10387 case ARM::VST4qWB_fixed_Asm_32: {
10408 case ARM::VST4dWB_register_Asm_8:
10409 case ARM::VST4dWB_register_Asm_16:
10410 case ARM::VST4dWB_register_Asm_32:
10411 case ARM::VST4qWB_register_Asm_8:
10412 case ARM::VST4qWB_register_Asm_16:
10413 case ARM::VST4qWB_register_Asm_32: {
10441 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10442 !HasWideQualifier) {
10446 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
10447 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
10448 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
10466 case ARM::t2MOVSsr: {
10470 bool isNarrow =
false;
10475 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr) &&
10482 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
10483 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
10484 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
10485 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
10491 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10498 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10503 case ARM::t2MOVSsi: {
10507 bool isNarrow =
false;
10510 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi) &&
10517 bool isMov =
false;
10528 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10532 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
10533 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
10534 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
10535 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
10536 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
10539 if (Amount == 32) Amount = 0;
10542 if (isNarrow && !isMov)
10544 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10546 if (newOpc != ARM::t2RRX && !isMov)
10552 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10596 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10605 if (
Opc == ARM::MOVsi)
10626 case ARM::t2LDMIA_UPD: {
10642 case ARM::t2STMDB_UPD: {
10658 case ARM::LDMIA_UPD:
10661 if (
static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"pop" &&
10676 case ARM::STMDB_UPD:
10679 if (
static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"push" &&
10692 case ARM::t2ADDri12:
10693 case ARM::t2SUBri12:
10694 case ARM::t2ADDspImm12:
10695 case ARM::t2SUBspImm12: {
10698 const StringRef Token =
static_cast<ARMOperand &
>(*Operands[0]).
getToken();
10699 if ((Token !=
"add" && Token !=
"sub") ||
10703 case ARM::t2ADDri12:
10706 case ARM::t2SUBri12:
10709 case ARM::t2ADDspImm12:
10712 case ARM::t2SUBspImm12:
10727 Operands.size() == MnemonicOpsEndInd + 3) {
10738 Operands.size() == MnemonicOpsEndInd + 3) {
10744 case ARM::t2SUBri: {
10749 if (HasWideQualifier)
10756 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10762 int i = (Operands[MnemonicOpsEndInd + 1]->isImm())
10763 ? MnemonicOpsEndInd + 1
10764 : MnemonicOpsEndInd + 2;
10765 MCParsedAsmOperand &
Op = *Operands[i];
10771 ARM::tADDi8 : ARM::tSUBi8);
10781 case ARM::t2ADDspImm:
10782 case ARM::t2SUBspImm: {
10787 if (V & 3 || V > ((1 << 7) - 1) << 2)
10800 case ARM::t2ADDrr: {
10862 case ARM::tLDMIA: {
10868 bool hasWritebackToken =
10869 (
static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
10871 static_cast<ARMOperand &
>(*Operands[MnemonicOpsEndInd + 1])
10873 bool listContainsBase;
10875 (!listContainsBase && !hasWritebackToken) ||
10876 (listContainsBase && hasWritebackToken)) {
10879 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10882 if (hasWritebackToken)
10889 case ARM::tSTMIA_UPD: {
10894 bool listContainsBase;
10904 bool listContainsBase;
10918 bool listContainsBase;
10935 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10936 !HasWideQualifier) {
10957 !HasWideQualifier) {
10964 if (
Op == ARM::tMOVr) {
10982 !HasWideQualifier) {
10986 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
10987 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
10988 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
10989 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
11027 case ARM::ADDrsi: {
11033 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
11034 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
11035 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
11036 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
11037 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
11038 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
11061 assert(!inITBlock() &&
"nested IT blocks?!");
11077 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11078 !HasWideQualifier) {
11082 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
11083 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
11084 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
11085 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
11086 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
11087 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
11114 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11115 !HasWideQualifier) {
11119 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
11120 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
11121 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
11122 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
11141 case ARM::MVE_VPST:
11142 case ARM::MVE_VPTv16i8:
11143 case ARM::MVE_VPTv8i16:
11144 case ARM::MVE_VPTv4i32:
11145 case ARM::MVE_VPTv16u8:
11146 case ARM::MVE_VPTv8u16:
11147 case ARM::MVE_VPTv4u32:
11148 case ARM::MVE_VPTv16s8:
11149 case ARM::MVE_VPTv8s16:
11150 case ARM::MVE_VPTv4s32:
11151 case ARM::MVE_VPTv4f32:
11152 case ARM::MVE_VPTv8f16:
11153 case ARM::MVE_VPTv16i8r:
11154 case ARM::MVE_VPTv8i16r:
11155 case ARM::MVE_VPTv4i32r:
11156 case ARM::MVE_VPTv16u8r:
11157 case ARM::MVE_VPTv8u16r:
11158 case ARM::MVE_VPTv4u32r:
11159 case ARM::MVE_VPTv16s8r:
11160 case ARM::MVE_VPTv8s16r:
11161 case ARM::MVE_VPTv4s32r:
11162 case ARM::MVE_VPTv4f32r:
11163 case ARM::MVE_VPTv8f16r: {
11164 assert(!inVPTBlock() &&
"Nested VPT blocks are not allowed");
11166 VPTState.Mask = MO.
getImm();
11167 VPTState.CurPosition = 0;
11175ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11182 if (Operands[0]->isToken() &&
11183 static_cast<ARMOperand &
>(*Operands[0]).
getToken() ==
"nop" &&
11184 ((
isThumb() && !isThumbOne()) || hasV6MOps())) {
11185 return Match_MnemonicFail;
11190 return Match_Success;
11194unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11198 const MCInstrDesc &MCID = MII.get(
Opc);
11201 "optionally flag setting instruction missing optional def operand");
11203 "operand count mismatch!");
11204 bool IsCPSR =
false;
11206 for (
unsigned OpNo = 0; OpNo < MCID.
NumOperands; ++OpNo) {
11207 if (MCID.
operands()[OpNo].isOptionalDef() &&
11214 if (isThumbOne() && !IsCPSR)
11215 return Match_RequiresFlagSetting;
11218 if (isThumbTwo() && !IsCPSR && !inITBlock())
11219 return Match_RequiresITBlock;
11220 if (isThumbTwo() && IsCPSR && inITBlock())
11221 return Match_RequiresNotITBlock;
11224 return Match_RequiresNotITBlock;
11225 }
else if (isThumbOne()) {
11228 if (
Opc == ARM::tADDhirr && !hasV6MOps() &&
11231 return Match_RequiresThumb2;
11233 else if (
Opc == ARM::tMOVr && !hasV6Ops() &&
11236 return Match_RequiresV6;
11242 if (
Opc == ARM::t2MOVr && !hasV8Ops())
11247 return Match_RequiresV8;
11252 return Match_RequiresV8;
11258 case ARM::VMRS_FPCXTS:
11259 case ARM::VMRS_FPCXTNS:
11260 case ARM::VMSR_FPCXTS:
11261 case ARM::VMSR_FPCXTNS:
11262 case ARM::VMRS_FPSCR_NZCVQC:
11263 case ARM::VMSR_FPSCR_NZCVQC:
11265 case ARM::VMRS_VPR:
11267 case ARM::VMSR_VPR:
11273 return Match_InvalidOperand;
11279 return Match_RequiresV8;
11287 return Match_InvalidTiedOperand;
11294 if (MCID.
operands()[
I].RegClass == ARM::rGPRRegClassID) {
11309 MCRegister
Reg =
Op.getReg();
11310 if ((
Reg == ARM::SP) && !hasV8Ops())
11311 return Match_RequiresV8;
11312 else if (
Reg == ARM::PC)
11313 return Match_InvalidOperand;
11316 return Match_Success;
11329bool ARMAsmParser::isITBlockTerminator(MCInst &Inst)
const {
11330 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11346unsigned ARMAsmParser::MatchInstruction(
OperandVector &Operands, MCInst &Inst,
11347 SmallVectorImpl<NearMissInfo> &NearMisses,
11348 bool MatchingInlineAsm,
11349 bool &EmitInITBlock,
11352 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11353 return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11357 if (inImplicitITBlock()) {
11358 extendImplicitITBlock(ITState.Cond);
11359 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
11363 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11369 if (InstCond == ITCond) {
11370 EmitInITBlock =
true;
11371 return Match_Success;
11373 invertCurrentITCondition();
11374 EmitInITBlock =
true;
11375 return Match_Success;
11379 rewindImplicitITPosition();
11383 flushPendingInstructions(Out);
11384 unsigned PlainMatchResult =
11385 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
11386 if (PlainMatchResult == Match_Success) {
11387 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11395 EmitInITBlock =
false;
11396 return Match_Success;
11399 EmitInITBlock =
false;
11400 return Match_Success;
11403 EmitInITBlock =
false;
11404 return Match_Success;
11411 startImplicitITBlock();
11412 if (MatchInstructionImpl(Operands, Inst,
nullptr, MatchingInlineAsm) ==
11414 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11419 EmitInITBlock =
true;
11420 return Match_Success;
11423 discardImplicitITBlock();
11427 EmitInITBlock =
false;
11428 return PlainMatchResult;
11432 unsigned VariantID = 0);
11435bool ARMAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
11438 bool MatchingInlineAsm) {
11440 unsigned MatchResult;
11441 bool PendConditionalInstruction =
false;
11444 MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
11445 PendConditionalInstruction, Out);
11450 switch (MatchResult) {
11451 case Match_Success:
11458 if (validateInstruction(Inst, Operands, MnemonicOpsEndInd)) {
11461 forwardITPosition();
11462 forwardVPTPosition();
11471 while (processInstruction(Inst, Operands, MnemonicOpsEndInd, Out))
11480 forwardITPosition();
11481 forwardVPTPosition();
11489 if (PendConditionalInstruction) {
11490 PendingConditionalInsts.
push_back(Inst);
11491 if (isITBlockFull() || isITBlockTerminator(Inst))
11492 flushPendingInstructions(Out);
11497 case Match_NearMisses:
11498 ReportNearMisses(NearMisses, IDLoc, Operands);
11500 case Match_MnemonicFail: {
11501 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11503 ((ARMOperand &)*Operands[0]).
getToken(), FBS);
11504 return Error(IDLoc,
"invalid instruction" + Suggestion,
11505 ((ARMOperand &)*Operands[0]).getLocRange());
11513bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11519 if (IDVal ==
".word")
11520 parseLiteralValues(4, DirectiveID.
getLoc());
11521 else if (IDVal ==
".short" || IDVal ==
".hword")
11522 parseLiteralValues(2, DirectiveID.
getLoc());
11523 else if (IDVal ==
".thumb")
11524 parseDirectiveThumb(DirectiveID.
getLoc());
11525 else if (IDVal ==
".arm")
11526 parseDirectiveARM(DirectiveID.
getLoc());
11527 else if (IDVal ==
".thumb_func")
11528 parseDirectiveThumbFunc(DirectiveID.
getLoc());
11529 else if (IDVal ==
".code")
11530 parseDirectiveCode(DirectiveID.
getLoc());
11531 else if (IDVal ==
".syntax")
11532 parseDirectiveSyntax(DirectiveID.
getLoc());
11533 else if (IDVal ==
".unreq")
11534 parseDirectiveUnreq(DirectiveID.
getLoc());
11535 else if (IDVal ==
".fnend")
11536 parseDirectiveFnEnd(DirectiveID.
getLoc());
11537 else if (IDVal ==
".cantunwind")
11538 parseDirectiveCantUnwind(DirectiveID.
getLoc());
11539 else if (IDVal ==
".personality")
11540 parseDirectivePersonality(DirectiveID.
getLoc());
11541 else if (IDVal ==
".handlerdata")
11542 parseDirectiveHandlerData(DirectiveID.
getLoc());
11543 else if (IDVal ==
".setfp")
11544 parseDirectiveSetFP(DirectiveID.
getLoc());
11545 else if (IDVal ==
".pad")
11546 parseDirectivePad(DirectiveID.
getLoc());
11547 else if (IDVal ==
".save")
11548 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
11549 else if (IDVal ==
".vsave")
11550 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
11551 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
11552 parseDirectiveLtorg(DirectiveID.
getLoc());
11553 else if (IDVal ==
".even")
11554 parseDirectiveEven(DirectiveID.
getLoc());
11555 else if (IDVal ==
".personalityindex")
11556 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
11557 else if (IDVal ==
".unwind_raw")
11558 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
11559 else if (IDVal ==
".movsp")
11560 parseDirectiveMovSP(DirectiveID.
getLoc());
11561 else if (IDVal ==
".arch_extension")
11562 parseDirectiveArchExtension(DirectiveID.
getLoc());
11563 else if (IDVal ==
".align")
11564 return parseDirectiveAlign(DirectiveID.
getLoc());
11565 else if (IDVal ==
".thumb_set")
11566 parseDirectiveThumbSet(DirectiveID.
getLoc());
11567 else if (IDVal ==
".inst")
11568 parseDirectiveInst(DirectiveID.
getLoc());
11569 else if (IDVal ==
".inst.n")
11570 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
11571 else if (IDVal ==
".inst.w")
11572 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
11573 else if (!IsMachO && !IsCOFF) {
11574 if (IDVal ==
".arch")
11575 parseDirectiveArch(DirectiveID.
getLoc());
11576 else if (IDVal ==
".cpu")
11577 parseDirectiveCPU(DirectiveID.
getLoc());
11578 else if (IDVal ==
".eabi_attribute")
11579 parseDirectiveEabiAttr(DirectiveID.
getLoc());
11580 else if (IDVal ==
".fpu")
11581 parseDirectiveFPU(DirectiveID.
getLoc());
11582 else if (IDVal ==
".fnstart")
11583 parseDirectiveFnStart(DirectiveID.
getLoc());
11584 else if (IDVal ==
".object_arch")
11585 parseDirectiveObjectArch(DirectiveID.
getLoc());
11586 else if (IDVal ==
".tlsdescseq")
11587 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
11590 }
else if (IsCOFF) {
11591 if (IDVal ==
".seh_stackalloc")
11592 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
false);
11593 else if (IDVal ==
".seh_stackalloc_w")
11594 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
true);
11595 else if (IDVal ==
".seh_save_regs")
11596 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
false);
11597 else if (IDVal ==
".seh_save_regs_w")
11598 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
true);
11599 else if (IDVal ==
".seh_save_sp")
11600 parseDirectiveSEHSaveSP(DirectiveID.
getLoc());
11601 else if (IDVal ==
".seh_save_fregs")
11602 parseDirectiveSEHSaveFRegs(DirectiveID.
getLoc());
11603 else if (IDVal ==
".seh_save_lr")
11604 parseDirectiveSEHSaveLR(DirectiveID.
getLoc());
11605 else if (IDVal ==
".seh_endprologue")
11606 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
false);
11607 else if (IDVal ==
".seh_endprologue_fragment")
11608 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
true);
11609 else if (IDVal ==
".seh_nop")
11610 parseDirectiveSEHNop(DirectiveID.
getLoc(),
false);
11611 else if (IDVal ==
".seh_nop_w")
11612 parseDirectiveSEHNop(DirectiveID.
getLoc(),
true);
11613 else if (IDVal ==
".seh_startepilogue")
11614 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
false);
11615 else if (IDVal ==
".seh_startepilogue_cond")
11616 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
true);
11617 else if (IDVal ==
".seh_endepilogue")
11618 parseDirectiveSEHEpilogEnd(DirectiveID.
getLoc());
11619 else if (IDVal ==
".seh_custom")
11620 parseDirectiveSEHCustom(DirectiveID.
getLoc());
11632bool ARMAsmParser::parseLiteralValues(
unsigned Size, SMLoc L) {
11633 auto parseOne = [&]() ->
bool {
11634 const MCExpr *
Value;
11635 if (getParser().parseExpression(
Value))
11637 getParser().getStreamer().emitValue(
Value,
Size, L);
11640 return (parseMany(parseOne));
11645bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11646 if (parseEOL() || check(!hasThumb(), L,
"target does not support Thumb mode"))
11652 getTargetStreamer().emitCode16();
11653 getParser().getStreamer().emitCodeAlignment(
Align(2), &getSTI(), 0);
11659bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11660 if (parseEOL() || check(!hasARM(), L,
"target does not support ARM mode"))
11665 getTargetStreamer().emitCode32();
11666 getParser().getStreamer().emitCodeAlignment(
Align(4), &getSTI(), 0);
11670void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11673 flushPendingInstructions(getStreamer());
11676void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11677 if (NextSymbolIsThumb) {
11678 getTargetStreamer().emitThumbFunc(Symbol);
11679 NextSymbolIsThumb =
false;
11685bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11686 MCAsmParser &Parser = getParser();
11696 MCSymbol *
Func = getParser().getContext().getOrCreateSymbol(
11698 getTargetStreamer().emitThumbFunc(Func);
11713 getTargetStreamer().emitCode16();
11715 NextSymbolIsThumb =
true;
11721bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11722 MCAsmParser &Parser = getParser();
11723 const AsmToken &Tok = Parser.
getTok();
11725 Error(L,
"unexpected token in .syntax directive");
11731 if (check(
Mode ==
"divided" ||
Mode ==
"DIVIDED", L,
11732 "'.syntax divided' arm assembly not supported") ||
11733 check(
Mode !=
"unified" &&
Mode !=
"UNIFIED", L,
11734 "unrecognized syntax mode in .syntax directive") ||
11745bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11746 MCAsmParser &Parser = getParser();
11747 const AsmToken &Tok = Parser.
getTok();
11749 return Error(L,
"unexpected token in .code directive");
11751 if (Val != 16 && Val != 32) {
11752 Error(L,
"invalid operand to .code directive");
11762 return Error(L,
"target does not support Thumb mode");
11766 getTargetStreamer().emitCode16();
11769 return Error(L,
"target does not support ARM mode");
11773 getTargetStreamer().emitCode32();
11781bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11782 MCAsmParser &Parser = getParser();
11785 SMLoc SRegLoc, ERegLoc;
11786 const bool parseResult = parseRegister(
Reg, SRegLoc, ERegLoc);
11787 if (check(parseResult, SRegLoc,
"register name expected") || parseEOL())
11790 if (RegisterReqs.
insert(std::make_pair(Name,
Reg)).first->second !=
Reg)
11791 return Error(SRegLoc,
11792 "redefinition of '" + Name +
"' does not match original.");
11799bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11800 MCAsmParser &Parser = getParser();
11802 return Error(L,
"unexpected input in .unreq directive.");
11811void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb, SMLoc Loc) {
11813 if (WasThumb && hasThumb()) {
11816 }
else if (!WasThumb && hasARM()) {
11822 getTargetStreamer().emitCode16();
11824 getTargetStreamer().emitCode32();
11828 Warning(Loc, Twine(
"new target does not support ") +
11829 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
11830 (!WasThumb ?
"thumb" :
"arm") +
" mode");
11837bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11838 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11841 if (
ID == ARM::ArchKind::INVALID)
11842 return Error(L,
"Unknown arch name");
11845 MCSubtargetInfo &STI = copySTI();
11848 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11849 FixModeAfterArchChange(WasThumb, L);
11851 getTargetStreamer().emitArch(
ID);
11858bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11859 MCAsmParser &Parser = getParser();
11868 Error(TagLoc,
"attribute name not recognised: " + Name);
11874 const MCExpr *AttrExpr;
11881 if (check(!CE, TagLoc,
"expected numeric constant"))
11884 Tag =
CE->getValue();
11890 StringRef StringValue =
"";
11891 bool IsStringValue =
false;
11893 int64_t IntegerValue = 0;
11894 bool IsIntegerValue =
false;
11897 IsStringValue =
true;
11899 IsStringValue =
true;
11900 IsIntegerValue =
true;
11901 }
else if (
Tag < 32 ||
Tag % 2 == 0)
11902 IsIntegerValue =
true;
11903 else if (
Tag % 2 == 1)
11904 IsStringValue =
true;
11908 if (IsIntegerValue) {
11909 const MCExpr *ValueExpr;
11916 return Error(ValueExprLoc,
"expected numeric constant");
11917 IntegerValue =
CE->getValue();
11925 std::string EscapedValue;
11926 if (IsStringValue) {
11934 StringValue = EscapedValue;
11944 if (IsIntegerValue && IsStringValue) {
11946 getTargetStreamer().emitIntTextAttribute(
Tag, IntegerValue, StringValue);
11947 }
else if (IsIntegerValue)
11948 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
11949 else if (IsStringValue)
11950 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
11956bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11957 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11962 if (!getSTI().isCPUStringValid(CPU))
11963 return Error(L,
"Unknown CPU name");
11966 MCSubtargetInfo &STI = copySTI();
11968 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11969 FixModeAfterArchChange(WasThumb, L);
11976bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11977 SMLoc FPUNameLoc = getTok().getLoc();
11978 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11981 std::vector<StringRef> Features;
11983 return Error(FPUNameLoc,
"Unknown FPU name");
11985 MCSubtargetInfo &STI = copySTI();
11986 for (
auto Feature : Features)
11988 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11990 getTargetStreamer().emitFPU(
ID);
11996bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
12000 if (UC.hasFnStart()) {
12001 Error(L,
".fnstart starts before the end of previous one");
12002 UC.emitFnStartLocNotes();
12009 getTargetStreamer().emitFnStart();
12011 UC.recordFnStart(L);
12017bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12021 if (!UC.hasFnStart())
12022 return Error(L,
".fnstart must precede .fnend directive");
12025 getTargetStreamer().emitFnEnd();
12033bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12037 UC.recordCantUnwind(L);
12039 if (check(!UC.hasFnStart(), L,
".fnstart must precede .cantunwind directive"))
12042 if (UC.hasHandlerData()) {
12043 Error(L,
".cantunwind can't be used with .handlerdata directive");
12044 UC.emitHandlerDataLocNotes();
12047 if (UC.hasPersonality()) {
12048 Error(L,
".cantunwind can't be used with .personality directive");
12049 UC.emitPersonalityLocNotes();
12053 getTargetStreamer().emitCantUnwind();
12059bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12060 MCAsmParser &Parser = getParser();
12061 bool HasExistingPersonality = UC.hasPersonality();
12065 return Error(L,
"unexpected input in .personality directive.");
12072 UC.recordPersonality(L);
12075 if (!UC.hasFnStart())
12076 return Error(L,
".fnstart must precede .personality directive");
12077 if (UC.cantUnwind()) {
12078 Error(L,
".personality can't be used with .cantunwind directive");
12079 UC.emitCantUnwindLocNotes();
12082 if (UC.hasHandlerData()) {
12083 Error(L,
".personality must precede .handlerdata directive");
12084 UC.emitHandlerDataLocNotes();
12087 if (HasExistingPersonality) {
12088 Error(L,
"multiple personality directives");
12089 UC.emitPersonalityLocNotes();
12093 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12094 getTargetStreamer().emitPersonality(PR);
12100bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12104 UC.recordHandlerData(L);
12106 if (!UC.hasFnStart())
12107 return Error(L,
".fnstart must precede .personality directive");
12108 if (UC.cantUnwind()) {
12109 Error(L,
".handlerdata can't be used with .cantunwind directive");
12110 UC.emitCantUnwindLocNotes();
12114 getTargetStreamer().emitHandlerData();
12120bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12121 MCAsmParser &Parser = getParser();
12123 if (check(!UC.hasFnStart(), L,
".fnstart must precede .setfp directive") ||
12124 check(UC.hasHandlerData(), L,
12125 ".setfp must precede .handlerdata directive"))
12130 MCRegister
FPReg = tryParseRegister();
12132 if (check(!
FPReg, FPRegLoc,
"frame pointer register expected") ||
12138 MCRegister
SPReg = tryParseRegister();
12139 if (check(!
SPReg, SPRegLoc,
"stack pointer register expected") ||
12140 check(
SPReg != ARM::SP &&
SPReg != UC.getFPReg(), SPRegLoc,
12141 "register should be either $sp or the latest fp register"))
12145 UC.saveFPReg(
FPReg);
12155 const MCExpr *OffsetExpr;
12158 if (getParser().parseExpression(OffsetExpr, EndLoc))
12159 return Error(ExLoc,
"malformed setfp offset");
12161 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
12175bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12176 MCAsmParser &Parser = getParser();
12178 if (!UC.hasFnStart())
12179 return Error(L,
".fnstart must precede .pad directive");
12180 if (UC.hasHandlerData())
12181 return Error(L,
".pad must precede .handlerdata directive");
12189 const MCExpr *OffsetExpr;
12192 if (getParser().parseExpression(OffsetExpr, EndLoc))
12193 return Error(ExLoc,
"malformed pad offset");
12196 return Error(ExLoc,
"pad offset must be an immediate");
12201 getTargetStreamer().emitPad(
CE->getValue());
12208bool ARMAsmParser::parseDirectiveRegSave(SMLoc L,
bool IsVector) {
12210 if (!UC.hasFnStart())
12211 return Error(L,
".fnstart must precede .save or .vsave directives");
12212 if (UC.hasHandlerData())
12213 return Error(L,
".save or .vsave must precede .handlerdata directive");
12219 if (parseRegisterList(Operands,
true,
true) || parseEOL())
12221 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12222 if (!IsVector && !
Op.isRegList())
12223 return Error(L,
".save expects GPR registers");
12224 if (IsVector && !
Op.isDPRRegList())
12225 return Error(L,
".vsave expects DPR registers");
12227 getTargetStreamer().emitRegSave(
Op.getRegList(), IsVector);
12235bool ARMAsmParser::parseDirectiveInst(SMLoc Loc,
char Suffix) {
12251 return Error(Loc,
"width suffixes are invalid in ARM mode");
12254 auto parseOne = [&]() ->
bool {
12255 const MCExpr *Expr;
12256 if (getParser().parseExpression(Expr))
12260 return Error(Loc,
"expected constant expression");
12263 char CurSuffix = Suffix;
12266 if (
Value->getValue() > 0xffff)
12267 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
12270 if (
Value->getValue() > 0xffffffff)
12271 return Error(Loc, StringRef(Suffix ?
"inst.w" :
"inst") +
12272 " operand is too big");
12276 if (
Value->getValue() < 0xe800)
12278 else if (
Value->getValue() >= 0xe8000000)
12281 return Error(Loc,
"cannot determine Thumb instruction size, "
12282 "use inst.n/inst.w instead");
12288 getTargetStreamer().emitInst(
Value->getValue(), CurSuffix);
12289 forwardITPosition();
12290 forwardVPTPosition();
12295 return Error(Loc,
"expected expression following directive");
12296 if (parseMany(parseOne))
12303bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12306 getTargetStreamer().emitCurrentConstantPool();
12310bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12311 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12317 getStreamer().initSections(getSTI());
12318 Section = getStreamer().getCurrentSectionOnly();
12321 assert(Section &&
"must have section to emit alignment");
12322 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12323 getStreamer().emitCodeAlignment(
Align(2), &getSTI());
12325 getStreamer().emitValueToAlignment(
Align(2));
12332bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12333 MCAsmParser &Parser = getParser();
12334 bool HasExistingPersonality = UC.hasPersonality();
12336 const MCExpr *IndexExpression;
12342 UC.recordPersonalityIndex(L);
12344 if (!UC.hasFnStart()) {
12345 return Error(L,
".fnstart must precede .personalityindex directive");
12347 if (UC.cantUnwind()) {
12348 Error(L,
".personalityindex cannot be used with .cantunwind");
12349 UC.emitCantUnwindLocNotes();
12352 if (UC.hasHandlerData()) {
12353 Error(L,
".personalityindex must precede .handlerdata directive");
12354 UC.emitHandlerDataLocNotes();
12357 if (HasExistingPersonality) {
12358 Error(L,
"multiple personality directives");
12359 UC.emitPersonalityLocNotes();
12365 return Error(IndexLoc,
"index must be a constant number");
12367 return Error(IndexLoc,
12368 "personality routine index should be in range [0-3]");
12370 getTargetStreamer().emitPersonalityIndex(
CE->getValue());
12376bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12377 MCAsmParser &Parser = getParser();
12378 int64_t StackOffset;
12379 const MCExpr *OffsetExpr;
12380 SMLoc OffsetLoc = getLexer().
getLoc();
12382 if (!UC.hasFnStart())
12383 return Error(L,
".fnstart must precede .unwind_raw directives");
12384 if (getParser().parseExpression(OffsetExpr))
12385 return Error(OffsetLoc,
"expected expression");
12389 return Error(OffsetLoc,
"offset must be a constant");
12391 StackOffset =
CE->getValue();
12398 auto parseOne = [&]() ->
bool {
12399 const MCExpr *OE =
nullptr;
12400 SMLoc OpcodeLoc = getLexer().getLoc();
12403 OpcodeLoc,
"expected opcode expression"))
12407 return Error(OpcodeLoc,
"opcode value must be a constant");
12408 const int64_t Opcode = OC->
getValue();
12409 if (Opcode & ~0xff)
12410 return Error(OpcodeLoc,
"invalid opcode");
12416 SMLoc OpcodeLoc = getLexer().getLoc();
12418 return Error(OpcodeLoc,
"expected opcode expression");
12419 if (parseMany(parseOne))
12422 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12428bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12429 MCAsmParser &Parser = getParser();
12432 return TokError(
"expected variable after '.tlsdescseq' directive");
12442 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12448bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12449 MCAsmParser &Parser = getParser();
12450 if (!UC.hasFnStart())
12451 return Error(L,
".fnstart must precede .movsp directives");
12452 if (UC.getFPReg() != ARM::SP)
12453 return Error(L,
"unexpected .movsp directive");
12456 MCRegister
SPReg = tryParseRegister();
12458 return Error(SPRegLoc,
"register expected");
12460 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
12467 const MCExpr *OffsetExpr;
12471 return Error(OffsetLoc,
"malformed offset expression");
12475 return Error(OffsetLoc,
"offset must be an immediate constant");
12484 UC.saveFPReg(
SPReg);
12491bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12492 MCAsmParser &Parser = getParser();
12494 return Error(getLexer().getLoc(),
"unexpected token");
12502 if (
ID == ARM::ArchKind::INVALID)
12503 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
12507 getTargetStreamer().emitObjectArch(
ID);
12513bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12518 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12519 assert(Section &&
"must have section to emit alignment");
12520 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12521 getStreamer().emitCodeAlignment(
Align(4), &getSTI(), 0);
12523 getStreamer().emitValueToAlignment(
Align(4), 0, 1, 0);
12531bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12532 MCAsmParser &Parser = getParser();
12536 "expected identifier after '.thumb_set'") ||
12541 const MCExpr *
Value;
12543 Parser, Sym,
Value))
12546 getTargetStreamer().emitThumbSet(Sym,
Value);
12553bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L,
bool Wide) {
12555 if (parseImmExpr(
Size))
12557 getTargetStreamer().emitARMWinCFIAllocStack(
Size, Wide);
12564bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L,
bool Wide) {
12567 if (parseRegisterList(Operands) || parseEOL())
12569 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12570 if (!
Op.isRegList())
12571 return Error(L,
".seh_save_regs{_w} expects GPR registers");
12572 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12574 for (
size_t i = 0; i < RegList.
size(); ++i) {
12579 return Error(L,
".seh_save_regs{_w} can't include SP");
12580 assert(
Reg < 16U &&
"Register out of range");
12581 unsigned Bit = (1u <<
Reg);
12584 if (!Wide && (Mask & 0x1f00) != 0)
12586 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12587 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12593bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12594 MCRegister
Reg = tryParseRegister();
12596 return Error(L,
"expected GPR");
12598 if (Index > 14 || Index == 13)
12599 return Error(L,
"invalid register for .seh_save_sp");
12600 getTargetStreamer().emitARMWinCFISaveSP(Index);
12606bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12609 if (parseRegisterList(Operands) || parseEOL())
12611 ARMOperand &
Op = (ARMOperand &)*Operands[0];
12612 if (!
Op.isDPRRegList())
12613 return Error(L,
".seh_save_fregs expects DPR registers");
12614 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12616 for (
size_t i = 0; i < RegList.
size(); ++i) {
12618 assert(
Reg < 32U &&
"Register out of range");
12619 unsigned Bit = (1u <<
Reg);
12624 return Error(L,
".seh_save_fregs missing registers");
12626 unsigned First = 0;
12627 while ((Mask & 1) == 0) {
12631 if (((Mask + 1) & Mask) != 0)
12633 ".seh_save_fregs must take a contiguous range of registers");
12635 while ((Mask & 2) != 0) {
12640 return Error(L,
".seh_save_fregs must be all d0-d15 or d16-d31");
12641 getTargetStreamer().emitARMWinCFISaveFRegs(
First,
Last);
12647bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12649 if (parseImmExpr(
Offset))
12651 getTargetStreamer().emitARMWinCFISaveLR(
Offset);
12658bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L,
bool Fragment) {
12659 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12666bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L,
bool Wide) {
12667 getTargetStreamer().emitARMWinCFINop(Wide);
12674bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L,
bool Condition) {
12677 MCAsmParser &Parser = getParser();
12679 const AsmToken &Tok = Parser.
getTok();
12681 return Error(S,
".seh_startepilogue_cond missing condition");
12684 return Error(S,
"invalid condition");
12688 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12694bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12695 getTargetStreamer().emitARMWinCFIEpilogEnd();
12701bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12702 unsigned Opcode = 0;
12705 if (parseImmExpr(Byte))
12707 if (Byte > 0xff || Byte < 0)
12708 return Error(L,
"Invalid byte value in .seh_custom");
12709 if (Opcode > 0x00ffffff)
12710 return Error(L,
"Too many bytes in .seh_custom");
12713 Opcode = (Opcode << 8) | Byte;
12715 getTargetStreamer().emitARMWinCFICustom(Opcode);
12727#define GET_REGISTER_MATCHER
12728#define GET_SUBTARGET_FEATURE_NAME
12729#define GET_MATCHER_IMPLEMENTATION
12730#define GET_MNEMONIC_SPELL_CHECKER
12731#include "ARMGenAsmMatcher.inc"
12737ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12738 switch (MatchError) {
12741 return hasV8Ops() ?
"operand must be a register in range [r0, r14]"
12742 :
"operand must be a register in range [r0, r12] or r14";
12745 return hasD32() ?
"operand must be a register in range [d0, d31]"
12746 :
"operand must be a register in range [d0, d15]";
12747 case Match_DPR_RegList:
12748 return hasD32() ?
"operand must be a list of registers in range [d0, d31]"
12749 :
"operand must be a list of registers in range [d0, d15]";
12753 return getMatchKindDiag(MatchError);
12761ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12762 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12776 std::multimap<unsigned, unsigned> OperandMissesSeen;
12777 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12778 bool ReportedTooFewOperands =
false;
12784 for (NearMissInfo &
I :
reverse(NearMissesIn)) {
12785 switch (
I.getKind()) {
12788 ((ARMOperand &)*Operands[
I.getOperandIndex()]).getStartLoc();
12789 const char *OperandDiag =
12790 getCustomOperandDiag((ARMMatchResultTy)
I.getOperandError());
12797 unsigned DupCheckMatchClass = OperandDiag ?
I.getOperandClass() : ~0
U;
12798 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
12799 if (std::any_of(PrevReports.first, PrevReports.second,
12800 [DupCheckMatchClass](
12801 const std::pair<unsigned, unsigned> Pair) {
12802 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12803 return Pair.second == DupCheckMatchClass;
12805 return isSubclass((MatchClassKind)DupCheckMatchClass,
12806 (MatchClassKind)Pair.second);
12809 OperandMissesSeen.insert(
12810 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
12812 NearMissMessage Message;
12813 Message.Loc = OperandLoc;
12815 Message.Message = OperandDiag;
12816 }
else if (
I.getOperandClass() == InvalidMatchClass) {
12817 Message.Message =
"too many operands for instruction";
12819 Message.Message =
"invalid operand for instruction";
12821 dbgs() <<
"Missing diagnostic string for operand class "
12822 << getMatchClassName((MatchClassKind)
I.getOperandClass())
12823 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
12824 <<
", opcode " << MII.getName(
I.getOpcode()) <<
"\n");
12830 const FeatureBitset &MissingFeatures =
I.getFeatures();
12832 if (FeatureMissesSeen.
count(MissingFeatures))
12834 FeatureMissesSeen.
insert(MissingFeatures);
12838 if (MissingFeatures.
test(Feature_IsARMBit) && !hasARM())
12842 if (
isThumb() && MissingFeatures.
test(Feature_IsARMBit) &&
12843 MissingFeatures.
count() > 1)
12845 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumbBit) &&
12846 MissingFeatures.
count() > 1)
12848 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumb2Bit) &&
12849 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12850 Feature_IsThumbBit})).any())
12852 if (isMClass() && MissingFeatures.
test(Feature_HasNEONBit))
12855 NearMissMessage Message;
12856 Message.Loc = IDLoc;
12857 raw_svector_ostream OS(Message.Message);
12859 OS <<
"instruction requires:";
12860 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i)
12861 if (MissingFeatures.
test(i))
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
constexpr size_t size() 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.
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)
FunctionAddr VTableAddr Value
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.
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.
FunctionAddr VTableAddr Count
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
FunctionAddr VTableAddr Next
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)
@ 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,...